--- tag_complete/tag_complete.js 2006/08/18 23:10:48 48
+++ tag_complete/tag_complete.js 2006/08/19 23:11:12 53
@@ -7,16 +7,23 @@
var _tag = {
name: new Array(),
obj: new Array(),
- selected_obj: new Array(),
+ tag2i: new Array(),
+ selected: new Array(),
+ entered: { // array of entered tags
+ i: new Array(), // offset to tags
+ tag: new Array() // mapping from tag i to entered
+ },
+
+ current: null, // current selected suggestion
+ last_tags: '',
select: function( tag ) {
$.log.info('filter '+tag);
- _tag.selected_obj = Array();
var j = 0;
var tag_len = tag.length;
- var suggest = '
';
+ var suggest = '';
for(var i = 0; i < _tag.name.length; i++) {
var t = _tag.name[i];
@@ -25,25 +32,25 @@
jQuery.className.add( _tag.obj[i], 'selected' );
- suggest += '- ' + t + '
';
- _tag.selected_obj[j] = _tag.obj[i];
- j++;
+ suggest += '' + t + ' ';
+ _tag.selected[j++] = {
+ i: i,
+ obj: _tag.obj[i]
+ }
}
}
- suggest += '
';
-
$('#suggest').html( suggest );
if (j > 0) {
- $('#suggest li:nth(0)').addClass('selected');
+ $('#suggest a:nth(0)').addClass('selected');
_tag.current = 0;
}
},
clean_selected: function() {
- for(var i = 0; i < _tag.selected_obj.length; i++) {
- jQuery.className.remove( _tag.selected_obj[i], 'selected' );
+ for(var i = 0; i < _tag.selected.length; i++) {
+ jQuery.className.remove( _tag.selected[i].obj, 'selected' );
}
var c = _tag.current;
@@ -63,28 +70,68 @@
return true;
}
- var s = $('#suggest li:nth('+c+')').html();
+ var s = $('#suggest a:nth('+c+')').html();
if (s == null) {
$.log.debug('no suggest, return true');
return true;
}
- _tag.add_tag( s );
- _tag.clean_selected();
+ var i = _tag.selected[c].i;
+ $.log.debug('take_suggested '+i+':'+s);
+ _tag.add_tag( s, i );
return false;
},
- add_tag: function( t ) {
- $.log.info('add: '+t);
+ add_tag: function( t, i ) {
+ $.log.info('add '+i+': '+t);
+ _tag.focus();
+ jQuery.className.add( _tag.obj[i], 'entered' );
+ var entered_i = _tag.entered.i.length;
+ _tag.entered.i[ entered_i ] = i;
+ _tag.entered.tag[i] = entered_i;
+ _tag.clean_selected();
$('#tags').val(
$('#tags').val().replace(
/[^ ]*$/, t + ' '
)
);
+ return false;
+ },
+
+ remove_tag: function( t, i ) {
+ $.log.info('remove '+i+': '+t);
_tag.focus();
+ jQuery.className.remove( _tag.obj[i], 'entered' );
+ // remove selected tag and rebuild tags
+
+ var ent_i = _tag.entered.tag[i];
+ $.log.debug('entered i:'+ent_i);
+ _tag.entered.i.splice(ent_i,1);
+ _tag.entered.tag[i] = null;
+
+ $.log.debug("tags "+_tag.entered.i.join(","));
+
+ var tags = '';
+ for (var j = 0; j < _tag.entered.i.length; j++) {
+ var tag_i = _tag.entered.i[j];
+ tags += _tag.name[ tag_i ] + ' ';
+ _tag.entered.tag[ tag_i ] = j;
+ }
+
+ _tag.clean_selected();
+ $.log.debug('tags left: '+tags);
+ $('#tags').val( tags );
return false;
},
+ tag: function( t, i ) {
+ if (_tag.entered.tag[i] != null) {
+ _tag.remove_tag( t, i );
+ } else {
+ _tag.add_tag( t, i );
+ }
+ },
+
move_suggested: function( where ) {
var c = _tag.current;
if (c == null) {
@@ -93,22 +140,57 @@
}
var to = c + where;
$.log.info('move_suggested('+where+') '+c+' -> '+to);
- if (to < 0 || to >= _tag.selected_obj.length) {
+ if (to < 0 || to >= _tag.selected.length) {
$.log.error('move to invalid element '+to);
return;
}
- var s = '#suggest li:nth('+c+')';
+ var s = '#suggest a:nth('+c+')';
$( s ).removeClass('selected');
$.log.debug('remove selected from '+s);
- s = '#suggest li:nth('+to+')';
+ s = '#suggest a:nth('+to+')';
$( s ).addClass('selected');
$.log.debug('add selected to '+s);
_tag.current = to;
},
- last_tag: function() {
- return $('#tags').val().replace(/^([^ ][^ ]* )*/, '');
+ parse: function() {
+ $.log.info('re-parse tags');
+
+ var t = $('#tags').val().replace(/^ */,'').replace(/ *$/,'').split(/ /);
+
+ _tag.entered = {
+ i: new Array(),
+ tag: new Array()
+ };
+
+ $('.entered').removeClass('entered');
+
+ var ids = '';
+ for (var i = 0; i < t.length; i++) {
+ var tag = t[i];
+ if (_tag.tag2i[ tag ] != null) {
+ var tag_i = _tag.tag2i[ tag ];
+ _tag.entered.tag[ tag ] =
+ _tag.entered.i.push( tag_i ) - 1;
+ jQuery.className.add( _tag.obj[ tag_i ], 'entered' );
+ ids += i + ':' + tag_i + ' ';
+ } else {
+ ids += i + ':{' + tag + '} ';
+ }
+ }
+ $.log.debug('tags: '+t.join(','), 'ids:'+ids);
+
+ },
+
+ current_tag: function() {
+ var tags = $('#tags').val();
+ if (tags != _tag.last_tags) {
+ _tag.last_tags = tags;
+ _tag.parse();
+ }
+ return tags.replace(/^([^ ][^ ]* )*/, '');
},
+
focus: function() {
// $('#tags').focus() doesn't work!
document.getElementById('tags').focus();
@@ -122,9 +204,11 @@
var n = this.firstChild.nodeValue;
_tag.name[i] = n;
_tag.obj[i] = this;
+ _tag.tag2i[n] = i;
this.onclick = function() {
- return _tag.add_tag( n );
+ return _tag.tag( n, i );
}
+ this.href = '#'+i; // FIXME debug
});
$.log.info( 'found ' + _tag.name.length + ' tags' );
@@ -147,10 +231,14 @@
if (_tag.current != null) _tag.focus();
e.preventDefault();
return false;
+ case 8: // backspace
+ case 46: // del
+ _tag.parse();
+ return false;
}
- var t = _tag.last_tag();
+ var t = _tag.current_tag();
$.log.debug('tag: ' + t + ' ['+t.length+']');
@@ -160,7 +248,7 @@
_tag.select(t);
- $.log.info('selected ' + _tag.selected_obj.length + ' tags');
+ $.log.info('selected ' + _tag.selected.length + ' tags');
return true;
}).submit( function() {