/[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

Annotation of /tag_complete/tag_complete.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 53 - (hide annotations)
Sat Aug 19 23:11:12 2006 UTC (17 years, 8 months ago) by dpavlin
File MIME type: application/javascript
File size: 5643 byte(s)
added parser for tag names entered to support de-select of edited tags
1 dpavlin 41 /*
2     tag auto-completer written with jquery
3    
4     2006-08-18 Dobrica Pavlinusic <dpavlin@rot13.org>
5     */
6    
7     var _tag = {
8     name: new Array(),
9     obj: new Array(),
10 dpavlin 53 tag2i: new Array(),
11 dpavlin 51 selected: new Array(),
12 dpavlin 52 entered: { // array of entered tags
13     i: new Array(), // offset to tags
14     tag: new Array() // mapping from tag i to entered
15     },
16 dpavlin 45
17 dpavlin 52 current: null, // current selected suggestion
18 dpavlin 53 last_tags: '',
19 dpavlin 51
20 dpavlin 45 select: function( tag ) {
21    
22     $.log.info('filter '+tag);
23    
24     var j = 0;
25     var tag_len = tag.length;
26 dpavlin 50 var suggest = '';
27 dpavlin 45
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 dpavlin 52 suggest += '<a href="#'+i+'" onclick="javascript:return _tag.tag(\'' + t + '\',' + i + ')">' + t + '</a> ';
36 dpavlin 51 _tag.selected[j++] = {
37     i: i,
38 dpavlin 52 obj: _tag.obj[i]
39 dpavlin 51 }
40 dpavlin 45 }
41     }
42    
43     $('#suggest').html( suggest );
44     if (j > 0) {
45 dpavlin 50 $('#suggest a:nth(0)').addClass('selected');
46 dpavlin 45 _tag.current = 0;
47     }
48    
49     },
50    
51     clean_selected: function() {
52 dpavlin 51 for(var i = 0; i < _tag.selected.length; i++) {
53     jQuery.className.remove( _tag.selected[i].obj, 'selected' );
54 dpavlin 45 }
55    
56     var c = _tag.current;
57 dpavlin 46 if (c == null) return c;
58 dpavlin 45
59     $('#suggest').html('');
60     _tag.current = null;
61 dpavlin 46
62     return c;
63 dpavlin 45 },
64    
65    
66     take_suggested: function() {
67 dpavlin 46 var c = _tag.current;
68     if (c == null) {
69     $.log.debug('no current, return true');
70     return true;
71     }
72    
73 dpavlin 50 var s = $('#suggest a:nth('+c+')').html();
74 dpavlin 46 if (s == null) {
75     $.log.debug('no suggest, return true');
76     return true;
77     }
78    
79 dpavlin 51 var i = _tag.selected[c].i;
80     $.log.debug('take_suggested '+i+':'+s);
81     _tag.add_tag( s, i );
82 dpavlin 48 return false;
83     },
84    
85 dpavlin 51 add_tag: function( t, i ) {
86     $.log.info('add '+i+': '+t);
87     _tag.focus();
88     jQuery.className.add( _tag.obj[i], 'entered' );
89 dpavlin 52 var entered_i = _tag.entered.i.length;
90     _tag.entered.i[ entered_i ] = i;
91     _tag.entered.tag[i] = entered_i;
92 dpavlin 50 _tag.clean_selected();
93 dpavlin 45 $('#tags').val(
94     $('#tags').val().replace(
95 dpavlin 48 /[^ ]*$/, t + ' '
96 dpavlin 45 )
97     );
98 dpavlin 46 return false;
99 dpavlin 45 },
100    
101 dpavlin 52 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 dpavlin 45 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 dpavlin 51 if (to < 0 || to >= _tag.selected.length) {
144 dpavlin 45 $.log.error('move to invalid element '+to);
145     return;
146     }
147 dpavlin 50 var s = '#suggest a:nth('+c+')';
148 dpavlin 45 $( s ).removeClass('selected');
149     $.log.debug('remove selected from '+s);
150 dpavlin 50 s = '#suggest a:nth('+to+')';
151 dpavlin 45 $( s ).addClass('selected');
152     $.log.debug('add selected to '+s);
153     _tag.current = to;
154     },
155    
156 dpavlin 53 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 dpavlin 45 },
184 dpavlin 53
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 dpavlin 45 focus: function() {
195     // $('#tags').focus() doesn't work!
196     document.getElementById('tags').focus();
197     }
198    
199 dpavlin 41 };
200    
201     $(document).ready( function() {
202    
203     $('.tag').each( function(i) {
204 dpavlin 48 var n = this.firstChild.nodeValue;
205     _tag.name[i] = n;
206 dpavlin 41 _tag.obj[i] = this;
207 dpavlin 53 _tag.tag2i[n] = i;
208 dpavlin 48 this.onclick = function() {
209 dpavlin 52 return _tag.tag( n, i );
210 dpavlin 48 }
211 dpavlin 52 this.href = '#'+i; // FIXME debug
212 dpavlin 41 });
213     $.log.info( 'found ' + _tag.name.length + ' tags' );
214    
215     $.log.info( 'hook onchange to #tags_form' );
216 dpavlin 45 $('#tags_form').keyup( function(e) {
217 dpavlin 41
218 dpavlin 45 $.log.debug('keyup: '+e.keyCode);
219 dpavlin 41
220 dpavlin 45 switch (e.keyCode) {
221     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 dpavlin 46 if (_tag.current != null) _tag.focus();
232 dpavlin 45 e.preventDefault();
233     return false;
234 dpavlin 53 case 8: // backspace
235     case 46: // del
236     _tag.parse();
237     return false;
238 dpavlin 41 }
239    
240    
241 dpavlin 53 var t = _tag.current_tag();
242 dpavlin 41
243 dpavlin 45 $.log.debug('tag: ' + t + ' ['+t.length+']');
244 dpavlin 41
245 dpavlin 45 _tag.clean_selected();
246 dpavlin 41
247 dpavlin 45 if (t == '') return false;
248    
249     _tag.select(t);
250    
251 dpavlin 51 $.log.info('selected ' + _tag.selected.length + ' tags');
252 dpavlin 45
253     return true;
254     }).submit( function() {
255     $.log.debug('submit');
256 dpavlin 46 return _tag.take_suggested();
257 dpavlin 45 }).blur( function() {
258     $.log.debug('blur');
259 dpavlin 46 return _tag.take_suggested();
260 dpavlin 45 });
261 dpavlin 41
262     $.log.toggle();
263    
264 dpavlin 45 _tag.focus();
265 dpavlin 41 });
266    

  ViewVC Help
Powered by ViewVC 1.1.26