/[drupal]/contributions/modules/activeselect/activeselect.js
ViewVC logotype

Contents of /contributions/modules/activeselect/activeselect.js

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.20 - (show annotations) (download) (as text)
Mon Apr 9 14:36:58 2007 UTC (2 years, 7 months ago) by bdragon
Branch: MAIN
CVS Tags: HEAD
Changes since 1.19: +2 -2 lines
File MIME type: text/javascript
Rolling the option creation back to the 4.7 way, which apparently works better.
1 // $Id: activeselect.js,v 1.19 2007/04/08 04:42:42 bdragon Exp $
2
3 /**
4 * Attaches the activeselect behaviour to all required fields
5 */
6 Drupal.activeselectAutoAttach = function () {
7 var asdb = [];
8 $('input.activeselect-path').each(function () {
9 var index = this.id.substr(0, this.id.length - 18);
10 var uri = this.value +'/'+ encodeURIComponent(index).substr(5);
11 var extra = $('#' + index + '-activeselect-extra').val();
12 var targets = $('#' + index + '-activeselect-targets').val();
13 var input = $('#' + index).get(0);
14
15 if (!asdb[uri]) {
16 asdb[uri] = new Drupal.ASDB(uri, targets);
17 }
18 new Drupal.jsAS(input, asdb[uri], targets, extra);
19 });
20 }
21
22 /**
23 * An ActiveSelect object
24 */
25 Drupal.jsAS = function (input, db, targets, extra) {
26 var as = this;
27 this.input = input;
28 this.db = db;
29 $(this.input).change(function (event) { return as.onchange(this, event); });
30 this.extra = extra;
31 var targetsArray = targets.split(',');
32 this.targets = [];
33 for (var target = 0; target < targetsArray.length; target++) {
34 var newTarget = $('#' + targetsArray[target]).get(0);
35 newTarget.owner = this;
36 this.targets.push(newTarget);
37 }
38 // this only runs if the current element does not have a parent activeselect
39 // linked to it - otherwise, IE has problems.
40 if (!this.input.owner) {
41 this.populateTargets();
42 }
43 };
44
45 /**
46 * Handler for the "onchange" event
47 */
48 Drupal.jsAS.prototype.onchange = function (input, e) {
49 if (!e) {
50 e = window.event;
51 }
52
53 this.populateTargets();
54 }
55
56 /**
57 * Return the currently selected options as a pipe-delimited string
58 */
59 Drupal.jsAS.prototype.getSelectedOptions = function () {
60 var selectedOptions = [];
61 var maxWidth = 0;
62 $('#' + this.input.id + ' option').each(function () {
63 if (this.selected) {
64 var optionString = this.value.replace(/\|/g, '&#124;') +'|'+ this.text.replace(/\|/g, '&#124;');
65 selectedOptions.push(optionString);
66 }
67 if (this.text.length > maxWidth) {
68 maxWidth = this.text.length;
69 }
70 });
71 this.setSelectWidth(maxWidth);
72
73 return selectedOptions.join('||');
74 }
75
76 /**
77 * Sets the width and background position of the activeselect element.
78 */
79 Drupal.jsAS.prototype.setSelectWidth = function (width) {
80 if (width != null) {
81 this.selectWidth = ((width * 10) * 1.5) + 20;
82 }
83 $(this.input).css({
84 width: this.selectWidth +'px',
85 backgroundPosition: (this.selectWidth - 35) +'px 2px'
86 });
87 }
88
89 /**
90 * Sets the width of the specified target element
91 */
92 Drupal.jsAS.prototype.setTargetWidth = function (target, width) {
93 if (width != null) {
94 this.targets[target].targetWidth = (width * 10) * 1.2;
95 }
96 $(this.targets[target]).css({
97 width: this.targets[target].targetWidth +'px'
98 });
99 }
100
101 /**
102 * Starts a search
103 */
104 Drupal.jsAS.prototype.populateTargets = function () {
105 var as = this;
106 this.db.owner = this;
107
108 this.db.search(this.getSelectedOptions(), this.targets, this.extra);
109 }
110
111 /**
112 * Fills the target select boxes with any matches received
113 */
114 Drupal.jsAS.prototype.populate = function (matches) {
115 for (targetIndex in this.targets) {
116 var target = this.targets[targetIndex];
117 var matchesTarget = 0;
118 for (targetElement in matches) {
119 if ('edit-'+targetElement == target.id) {
120 matchesTarget = targetElement;
121 continue;
122 }
123 }
124 if (matchesTarget) {
125 this.targets[targetIndex].multiple = matches[matchesTarget]['multiple'];
126 if (matches[matchesTarget]['multiple']) {
127 if (target.name.indexOf('[]') == -1) {
128 this.targets[targetIndex].name += '[]';
129 }
130 }
131 else {
132 var bracketIndex = target.name.indexOf('[]');
133 if (bracketIndex != -1) {
134 this.targets[targetIndex].name = target.name.substr(0, target.name.length-2);
135 }
136 }
137
138 $(target).empty();
139 var targetMatches = matches[matchesTarget]['options'];
140 var maxWidth = 0;
141 for (currMatch in targetMatches) {
142 var value = currMatch;
143 var text = targetMatches[currMatch]['value'];
144 var selected = targetMatches[currMatch]['selected'];
145
146 if (text.length > maxWidth) {
147 maxWidth = text.length;
148 }
149 // 'new Option()' used instead of appendChild(), because IE6 refuses to
150 // display option text if the latter method is used (otherwise they seem
151 // to behave the same).
152 this.targets[targetIndex].options[this.targets[targetIndex].options.length] = new Option(text, value, false, selected);
153 if (selected && !this.targets[targetIndex].multiple) {
154 this.targets[targetIndex].selectedIndex = this.targets[targetIndex].options.length-1;
155 }
156 }
157 if (this.targets[targetIndex].selectedIndex == -1) {
158 this.targets[targetIndex].selectedIndex = 0;
159 }
160
161 if (this.hasClass(this.targets[targetIndex], 'form-activeselect')) {
162 // Since IE does not support the DOM 2 methods for manually firing an
163 // event, we must cater especially to its needs.
164 // Reference: http://www.howtocreate.co.uk/tutorials/javascript/domevents
165 if (document.createEvent) {
166 // DOM 2 compliant method (Firefox / Opera / Safari / etc)
167 var e = document.createEvent('HTMLEvents');
168 e.initEvent('change', true, false);
169 this.targets[targetIndex].dispatchEvent(e);
170 }
171 else if (document.createEventObject) {
172 // IE special weird method
173 var e = document.createEventObject();
174 e.bubbles = true;
175 e.cancelable = false;
176 this.targets[targetIndex].fireEvent('onchange', e);
177 }
178 }
179 else {
180 this.setTargetWidth(targetIndex, maxWidth);
181 }
182 }
183 }
184 this.setSelectWidth(null);
185 }
186
187 /**
188 * Returns true if an element has a specified class name
189 */
190 Drupal.jsAS.prototype.hasClass = function (node, className) {
191 if (node.className == className) {
192 return true;
193 }
194 var reg = new RegExp('(^| )'+ className +'($| )')
195 if (reg.test(node.className)) {
196 return true;
197 }
198 return false;
199 }
200
201 /**
202 * An ActiveSelect DataBase object
203 */
204 Drupal.ASDB = function (uri, targets) {
205 this.uri = uri;
206 this.targets = targets;
207 this.delay = 300;
208 this.cache = {};
209 }
210
211 /**
212 * Performs a cached and delayed search
213 */
214 Drupal.ASDB.prototype.search = function(searchString, targets, extra) {
215 this.searchString = searchString;
216 if (this.cache[searchString]) {
217 return this.owner.populate(this.cache[searchString]);
218 }
219 if (this.timer) {
220 clearTimeout(this.timer);
221 }
222 var db = this;
223 this.timer = setTimeout(function() {
224 $(db.owner.input).css({
225 width: db.owner.selectWidth +'px',
226 backgroundPosition: (db.owner.selectWidth - 35) +'px -18px'
227 });
228 var targetIds = [];
229 for (var target = 0; target < targets.length; target++) {
230 if (targets[target].id) {
231 targetIds.push($(targets[target]).id().substr(5));
232 }
233 }
234 var targetsString = targetIds.join(',');
235
236 // Ajax GET request for activeselect
237 $.ajax({
238 type: "GET",
239 url: db.uri +'/'+ encodeURIComponent(targetsString) +'/'+ encodeURIComponent(searchString) +'/'+ encodeURIComponent(extra),
240 success: function (data) {
241 // Split into array of key->value pairs
242 if (data.length > 0) {
243 var targets = Drupal.parseJson(data);
244 if (typeof targets['status'] == 'undefined' || targets['status'] != 0) {
245 db.cache[searchString] = targets;
246 db.owner.populate(targets);
247 }
248 }
249 },
250 error: function (xmlhttp) {
251 asdb.owner.setSelectWidth(null);
252 alert('An HTTP error '+ xmlhttp.status +' occured.\n'+ db.uri);
253 }
254 });
255 }, this.delay);
256 }
257
258 // Global Killswitch
259 if (Drupal.jsEnabled) {
260 $(document).ready(Drupal.activeselectAutoAttach);
261 }

  ViewVC Help
Powered by ViewVC 1.1.2