/[jquery]/tag_complete/tag_complete.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /tag_complete/tag_complete.js

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 41 by dpavlin, Fri Aug 18 17:23:51 2006 UTC revision 53 by dpavlin, Sat Aug 19 23:11:12 2006 UTC
# Line 7  Line 7 
7  var _tag = {  var _tag = {
8          name: new Array(),          name: new Array(),
9          obj: new Array(),          obj: new Array(),
10          selected_name: new Array(),          tag2i: new Array(),
11          selected_obj: new Array()          selected: new Array(),
12            entered: {                      // array of entered tags
13                    i: new Array(),         // offset to tags
14                    tag: new Array()        // mapping from tag i to entered
15            },
16    
17            current: null,                  // current selected suggestion
18            last_tags: '',
19    
20            select: function( tag ) {
21    
22                    $.log.info('filter '+tag);
23    
24                    var j = 0;
25                    var tag_len = tag.length;
26                    var suggest = '';
27    
28                    for(var i = 0; i < _tag.name.length; i++) {
29                            var t = _tag.name[i];
30                            if ( t.substr(0, tag_len) == tag ) {
31                                    $.log.debug('selected ['+i+']: ' + t );
32    
33                                    jQuery.className.add( _tag.obj[i], 'selected' );
34    
35                                    suggest += '<a href="#'+i+'" onclick="javascript:return _tag.tag(\'' + t + '\',' + i + ')">' + t + '</a> ';
36                                    _tag.selected[j++] = {
37                                            i: i,
38                                            obj: _tag.obj[i]
39                                    }
40                            }
41                    }
42    
43                    $('#suggest').html( suggest );
44                    if (j > 0) {
45                            $('#suggest a:nth(0)').addClass('selected');
46                            _tag.current = 0;
47                    }
48    
49            },
50    
51            clean_selected: function() {
52                    for(var i = 0; i < _tag.selected.length; i++) {
53                            jQuery.className.remove( _tag.selected[i].obj, 'selected' );
54                    }
55    
56                    var c = _tag.current;
57                    if (c == null) return c;
58    
59                    $('#suggest').html('');
60                    _tag.current = null;
61    
62                    return c;
63            },
64    
65    
66            take_suggested: function() {
67                    var c = _tag.current;
68                    if (c == null) {
69                            $.log.debug('no current, return true');
70                            return true;
71                    }
72    
73                    var s = $('#suggest a:nth('+c+')').html();
74                    if (s == null) {
75                            $.log.debug('no suggest, return true');
76                            return true;
77                    }
78    
79                    var i = _tag.selected[c].i;
80                    $.log.debug('take_suggested '+i+':'+s);
81                    _tag.add_tag( s, i );
82                    return false;
83            },
84    
85            add_tag: function( t, i ) {
86                    $.log.info('add '+i+': '+t);
87                    _tag.focus();
88                    jQuery.className.add( _tag.obj[i], 'entered' );
89                    var entered_i = _tag.entered.i.length;
90                    _tag.entered.i[ entered_i ] = i;
91                    _tag.entered.tag[i] = entered_i;
92                    _tag.clean_selected();
93                    $('#tags').val(
94                            $('#tags').val().replace(
95                                    /[^ ]*$/, t + ' '
96                            )
97                    );
98                    return false;
99            },
100    
101            remove_tag: function( t, i ) {
102                    $.log.info('remove '+i+': '+t);
103                    _tag.focus();
104                    jQuery.className.remove( _tag.obj[i], 'entered' );
105                    // remove selected tag and rebuild tags
106    
107                    var ent_i = _tag.entered.tag[i];
108                    $.log.debug('entered i:'+ent_i);
109                    _tag.entered.i.splice(ent_i,1);
110                    _tag.entered.tag[i] = null;
111    
112                    $.log.debug("tags "+_tag.entered.i.join(","));
113    
114                    var tags = '';
115                    for (var j = 0; j < _tag.entered.i.length; j++) {
116                            var tag_i = _tag.entered.i[j];
117                            tags += _tag.name[ tag_i ] + ' ';
118                            _tag.entered.tag[ tag_i ] = j;
119                    }
120    
121                    _tag.clean_selected();
122                    $.log.debug('tags left: '+tags);
123                    $('#tags').val( tags );
124                    return false;
125            },
126    
127            tag: function( t, i ) {
128                    if (_tag.entered.tag[i] != null) {
129                            _tag.remove_tag( t, i );
130                    } else {
131                            _tag.add_tag( t, i );
132                    }
133            },
134    
135            move_suggested: function( where ) {
136                    var c = _tag.current;
137                    if (c == null) {
138                            $.log.error('_tag.current is null');
139                            return;
140                    }
141                    var to = c + where;
142                    $.log.info('move_suggested('+where+') '+c+' -> '+to);
143                    if (to < 0 || to >= _tag.selected.length) {
144                            $.log.error('move to invalid element '+to);
145                            return;
146                    }
147                    var s = '#suggest a:nth('+c+')';
148                    $( s ).removeClass('selected');
149                    $.log.debug('remove selected from '+s);
150                    s = '#suggest a:nth('+to+')';
151                    $( s ).addClass('selected');
152                    $.log.debug('add selected to '+s);
153                    _tag.current = to;
154            },
155    
156            parse: function() {
157                    $.log.info('re-parse tags');
158    
159                    var t = $('#tags').val().replace(/^  */,'').replace(/  *$/,'').split(/ /);
160    
161                    _tag.entered = {
162                            i: new Array(),
163                            tag: new Array()
164                    };
165    
166                    $('.entered').removeClass('entered');
167    
168                    var ids = '';
169                    for (var i = 0; i < t.length; i++) {
170                            var tag = t[i];
171                            if (_tag.tag2i[ tag ] != null) {
172                                    var tag_i = _tag.tag2i[ tag ];
173                                    _tag.entered.tag[ tag ] =
174                                            _tag.entered.i.push( tag_i ) - 1;
175                                    jQuery.className.add( _tag.obj[ tag_i ], 'entered' );
176                                    ids += i + ':' + tag_i + ' ';
177                            } else {
178                                    ids += i + ':{' + tag + '} ';
179                            }
180                    }
181                    $.log.debug('tags: '+t.join(','), 'ids:'+ids);
182    
183            },
184    
185            current_tag: function() {
186                    var tags = $('#tags').val();
187                    if (tags != _tag.last_tags) {
188                            _tag.last_tags = tags;
189                            _tag.parse();
190                    }
191                    return tags.replace(/^([^ ][^ ]* )*/, '');
192            },
193    
194            focus: function() {
195                    // $('#tags').focus() doesn't work!
196                    document.getElementById('tags').focus();
197            }
198    
199  };  };
200    
201  $(document).ready( function() {  $(document).ready( function() {
202    
203          $('.tag').each( function(i) {          $('.tag').each( function(i) {
204                  _tag.name[i] = this.firstChild.nodeValue;                  var n = this.firstChild.nodeValue;
205                    _tag.name[i] = n;
206                  _tag.obj[i] = this;                  _tag.obj[i] = this;
207                    _tag.tag2i[n] = i;
208                    this.onclick = function() {
209                            return _tag.tag( n, i );
210                    }
211                    this.href = '#'+i;      // FIXME debug
212          });          });
213          $.log.info( 'found ' + _tag.name.length + ' tags' );          $.log.info( 'found ' + _tag.name.length + ' tags' );
214    
215          $.log.info( 'hook onchange to #tags_form' );          $.log.info( 'hook onchange to #tags_form' );
216          $('#tags_form').change( function() {          $('#tags_form').keyup( function(e) {
                 $.log.debug('submit #tags_form');  
                 //this.submit();  
                 return false;  
         }).keyup( function() {  
                 var t = $('#tags').val().replace(/^([^ ][^ ]* )*/, '');  
   
                 if (! t ) return;  
217    
218                  $.log.debug('tag: ' + t);                  $.log.debug('keyup: '+e.keyCode);
219    
220                  for(var i = 0; i < _tag.selected_obj.length; i++) {                  switch (e.keyCode) {
221                          jQuery.className.remove( _tag.selected_obj[i], 'selected' );                          case 38:        // up
222                                    e.preventDefault();
223                                    _tag.move_suggested( -1 );
224                                    return false;
225                            case 40:        // down
226                                    e.preventDefault();
227                                    _tag.move_suggested( +1 );
228                                    return false;
229                            case 9:         // tab
230                            case 13:        // return
231                                    if (_tag.current != null) _tag.focus();
232                                    e.preventDefault();
233                                    return false;
234                            case 8:         // backspace
235                            case 46:        // del
236                                    _tag.parse();
237                                    return false;
238                  }                  }
239    
                 _tag.selected_name = Array();  
                 _tag.selected_obj = Array();  
                 var j = 0;  
240    
241                  if (t == '') return;                  var t = _tag.current_tag();
242    
243                  for(var i = 0; i < _tag.name.length; i++) {                  $.log.debug('tag: ' + t + ' ['+t.length+']');
                         if ( _tag.name[i].substr(0, t.length) == t ) {  
                                 var t = _tag.name[i];  
                                 $.log.debug('selected ' + t );  
244    
245                                  jQuery.className.add( _tag.obj[i], 'selected' );                  _tag.clean_selected();
246    
247                                  _tag.selected_obj[j] = _tag.obj[i];                  if (t == '') return false;
                                 _tag.selected_name[j] = _tag.name[i];  
                                 j++;  
                         }  
                 }  
248    
249                  $.log.debug('selected ' + _tag.selected_obj.length + ' tags');                  _tag.select(t);
250    
251                    $.log.info('selected ' + _tag.selected.length + ' tags');
252    
253                    return true;
254            }).submit( function() {
255                    $.log.debug('submit');
256                    return _tag.take_suggested();
257            }).blur( function() {
258                    $.log.debug('blur');
259                    return _tag.take_suggested();
260            });
261    
                 $('#suggest').html( _tag.selected_name.join(" ") );  
         }).focus();  
           
262          $.log.toggle();          $.log.toggle();
263    
264            _tag.focus();
265  });  });
266    

Legend:
Removed from v.41  
changed lines
  Added in v.53

  ViewVC Help
Powered by ViewVC 1.1.26