publisher autocomplete correctly adds name into status_message_fake textarea

This commit is contained in:
danielvincent 2011-02-04 14:09:44 -08:00 committed by Raphael Sofaer
parent 77403596aa
commit 7d21f7bfdd
4 changed files with 123 additions and 27 deletions

View file

@ -13,7 +13,6 @@
;(function($) {
function lastWord(s){return s;} //Fuck you
$.fn.extend({
autocomplete: function(urlOrData, options) {
var isUrl = typeof urlOrData == "string";
@ -148,6 +147,7 @@ $.Autocompleter = function(input, options) {
break;
default:
options.onLetterTyped(event, $input);
clearTimeout(timeout);
timeout = setTimeout(onChange, options.delay);
break;
@ -215,9 +215,8 @@ $.Autocompleter = function(input, options) {
v += options.multipleSeparator;
}
$input.val(v);
hideResultsNow();
$input.trigger("result", [selected.data, selected.value]);
options.onSelect($input, selected.data, selected.value);
return true;
}
@ -265,9 +264,9 @@ $.Autocompleter = function(input, options) {
function autoFill(q, sValue){
// autofill in the complete box w/the first match as long as the user hasn't entered in more data
// if the last user key pressed was backspace, don't autofill
if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
if( options.autoFill && (options.lastWord($input.val(), null, options.multiple).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
// fill in the value (keep the case the user has typed)
$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
$input.val($input.val() + sValue.substring(options.lastWord(previousValue, null, options.multiple).length));
// select the portion of the value not typed by the user (so the next character will erase)
$.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
}
@ -340,7 +339,7 @@ $.Autocompleter = function(input, options) {
dataType: options.dataType,
url: options.url,
data: $.extend({
q: lastWord(term),
q: options.lastWord(term, null, options.multiple),
limit: options.max
}, extraParams),
success: function(data) {
@ -380,10 +379,19 @@ $.Autocompleter = function(input, options) {
};
$.Autocompleter.defaults = {
searchTermFromValue: lastWord,
onLetterTyped : function(event){},
lastWord : function(value, crap, multiple) {
if ( !multiple )
return value;
var words = trimWords(value);
return words[words.length - 1];
},
inputClass: "ac_input",
resultsClass: "ac_results",
loadingClass: "ac_loading",
onSelect: function(input, data, formatted){
input.val(formatted);
},
minChars: 1,
delay: 400,
matchCase: false,
@ -407,6 +415,7 @@ $.Autocompleter.defaults = {
scroll: true,
scrollHeight: 180
};
$.Autocompleter.defaults.searchTermFromValue = $.Autocompleter.defaults.lastWord;
$.Autocompleter.Cache = function(options) {

View file

@ -28,18 +28,28 @@ var Publisher = {
return Publisher.cachedInput;
},
updateHiddenField: function(evt){
Publisher.form().find('#status_message_message').val(
cachedHiddenInput : false,
hiddenInput: function(){
if(!Publisher.cachedHiddenInput){
Publisher.cachedHiddenInput = Publisher.form().find('#status_message_message');
}
return Publisher.cachedHiddenInput;
},
appendToHiddenField: function(evt){
Publisher.hiddenInput().val(
Publisher.input().val());
},
autocompletion: {
options : function(){return {
minChars : 1,
max : 5,
onSelect : Publisher.autocompletion.onSelect,
searchTermFromValue: Publisher.autocompletion.searchTermFromValue,
scroll : false,
formatItem: function(row, i, max) {
return row.name;
return "<img src='"+ row.avatar +"' class='avatar'/>" + row.name;
},
formatMatch: function(row, i, max) {
return row.name;
@ -49,24 +59,44 @@ var Publisher = {
}
};},
selectItemCallback : function(event, data, formatted) {
var textarea = Publisher.input();
textarea.val(formatted);
onSelect : function(input, data, formatted) {
addMentionToVisibleInput(input, formatted);
},
addMentionToVisibleInput: function(input, formatted){
var cursorIndex = input[0].selectionStart;
var inputContent = input.val();
var stringLoc = Publisher.autocompletion.findStringToReplace(input.val(), cursorIndex);
var stringStart = inputContent.slice(0, stringLoc[0]);
var stringEnd = inputContent.slice(stringLoc[1]);
input.val(stringStart + formatted + stringEnd);
},
findStringToReplace: function(value, cursorIndex){
var atLocation = value.lastIndexOf('@', cursorIndex);
if(atLocation == -1){return [0,0];}
var nextAt = value.indexOf('@', cursorIndex+1);
if(nextAt == -1){nextAt = value.length;}
return [atLocation, nextAt];
},
searchTermFromValue: function(value, cursorIndex)
{
var atLocation = value.lastIndexOf('@', cursorIndex);
if(atLocation == -1){return '';}
var nextAt = value.indexOf('@', cursorIndex+1);
var stringLoc = Publisher.autocompletion.findStringToReplace(value, cursorIndex);
if(stringLoc[0] <= 2){
stringLoc[0] = 0;
}else{
stringLoc[0] -= 2
}
if(nextAt == -1){nextAt = value.length;}
if(atLocation < 2){
atLocation = 0;
}else{ atLocation = atLocation -2 }
var relevantString = value.slice(stringLoc[0], stringLoc[1]).replace(/\s+$/,"");
relevantString = value.slice(atLocation, nextAt).replace(/\s+$/,"");
matches = relevantString.match(/(^|\s)@(.+)/);
var matches = relevantString.match(/(^|\s)@(.+)/);
if(matches){
return matches[2];
}else{
@ -98,7 +128,7 @@ var Publisher = {
Publisher.autocompletion.initialize();
Publisher.updateHiddenField();
Publisher.form().find('#status_message_fake_message').change(
Publisher.form().find('#status_message_fake_message').bind('keydown',
Publisher.updateHiddenField);
Publisher.form().find("textarea").bind("focus", function(evt) {
Publisher.open();

View file

@ -25,6 +25,7 @@ var Search = {
},
options : function(){return {
minChars : 3,
onSelect: Search.selectItemCallback,
max : 5,
scroll : false,
delay : 200,
@ -49,7 +50,6 @@ var Search = {
initialize : function() {
$(Search.selector).autocomplete(Search.source, Search.options());
$(Search.selector).result(Search.selectItemCallback);
}
}

View file

@ -13,12 +13,12 @@ describe("Publisher", function() {
expect(Publisher.updateHiddenField).toHaveBeenCalled();
});
it("attaches updateHiddenField to the change handler on fake_message", function(){
it("attaches updateHiddenField to the keydown handler on fake_message", function(){
spec.loadFixture('aspects_index_prefill');
spyOn(Publisher, 'updateHiddenField');
Publisher.initialize();
Publisher.form().find('#status_message_fake_message').change();
expect(Publisher.updateHiddenField.mostRecentCall.args[0].type).toBe('change');
Publisher.form().find('#status_message_fake_message').keydown();
expect(Publisher.updateHiddenField.mostRecentCall.args[0].type).toBe('keydown');
});
it("calls close when it does not have text", function(){
@ -120,5 +120,62 @@ describe("Publisher", function() {
expect(func('@asod asdo @asd asok', 15)).toBe('asd asok');
});
});
describe("onSelect", function(){
});
describe("addMentionToHiddenInput", function(){
var func;
var input;
beforeEach(function(){
spec.loadFixture('aspects_index');
func = Publisher.autocompletion.addMentionToHiddenInput;
input = Publisher.input();
});
});
describe("addMentionToVisibleInput", function(){
var func;
var input;
var replaceWith;
beforeEach(function(){
spec.loadFixture('aspects_index');
func = Publisher.autocompletion.addMentionToVisibleInput;
input = Publisher.input();
replaceWith = "Replace with this.";
});
it("replaces everything after an @ if the cursor is a word after that @", function(){
input.val('not @dan grip');
func(input, replaceWith);
input[0].selectionStart = 13;
expect(input.val()).toBe('not ' + replaceWith);
});
it("replaces everything after an @ if the cursor is after that @", function(){
input.val('not @dan grip');
input[0].selectionStart = 7;
func(input, replaceWith);
expect(input.val()).toBe('not ' + replaceWith);
});
it("replaces everything after an @ at the start of the line", function(){
input.val('@dan grip');
input[0].selectionStart = 9;
func(input, replaceWith);
expect(input.val()).toBe(replaceWith);
});
it("replaces everything between @s if there are 2 @s and the cursor is between them", function(){
input.val('@asdpo aoisdj @asodk');
input[0].selectionStart = 8;
func(input, replaceWith);
expect(input.val()).toBe(replaceWith + ' @asodk');
});
it("replaces everything after the 2nd @ if there are 2 @s and the cursor after them", function(){
input.val('@asod asdo @asd asok');
input[0].selectionStart = 15;
func(input, replaceWith);
expect(input.val()).toBe('@asod asdo ' + replaceWith);
});
});
});
});