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

Contents of /tag_complete/tag_complete.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 53 - (show 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 /*
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 tag2i: new Array(),
11 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() {
202
203 $('.tag').each( function(i) {
204 var n = this.firstChild.nodeValue;
205 _tag.name[i] = n;
206 _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' );
214
215 $.log.info( 'hook onchange to #tags_form' );
216 $('#tags_form').keyup( function(e) {
217
218 $.log.debug('keyup: '+e.keyCode);
219
220 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 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
240
241 var t = _tag.current_tag();
242
243 $.log.debug('tag: ' + t + ' ['+t.length+']');
244
245 _tag.clean_selected();
246
247 if (t == '') return false;
248
249 _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
262 $.log.toggle();
263
264 _tag.focus();
265 });
266

  ViewVC Help
Powered by ViewVC 1.1.26