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

Contents of /contributions/modules/form_builder/form_builder.js

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


Revision 1.18 - (show annotations) (download) (as text)
Mon Jun 29 17:02:33 2009 UTC (4 months, 4 weeks ago) by quicksketch
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-6--1
Changes since 1.17: +4 -2 lines
File MIME type: text/javascript
Adding messages to initial display of field edit configuration.
1 // $Id: form_builder.js,v 1.17 2009/06/20 21:18:42 quicksketch Exp $
2
3 /**
4 * @file form_builder.js
5 * Provide enhancements to the form building user interface.
6 */
7
8 Drupal.behaviors.formBuilderElement = function(context) {
9 var $wrappers = $('div.form-builder-wrapper', context);
10 var $elements = $('div.form-builder-element', context);
11
12 // If the context itself is a wrapper, add it to the list.
13 if ($(context).is('div.form-builder-wrapper')) {
14 $wrappers = $wrappers.add(context);
15 }
16
17 // Add over effect on rollover.
18 // The .hover() method is not used to avoid issues with nested hovers.
19 $wrappers.not('div.form-builder-empty-placeholder')
20 .bind('mouseover', Drupal.formBuilder.addHover)
21 .bind('mouseout', Drupal.formBuilder.removeHover);
22
23 // Add AJAX to edit links.
24 $wrappers.find('span.form-builder-links a.configure').click(Drupal.formBuilder.editField);
25
26 // Add AJAX to remove links.
27 $wrappers.find('span.form-builder-links a.remove').click(Drupal.formBuilder.editField);
28
29 // Add AJAX to entire field for easy editing.
30 $elements.each(function() {
31 if ($(this).children('fieldset.form-builder-fieldset').size() == 0) {
32 var link = $(this).parents('div.form-builder-wrapper:first').find('a.configure').get(0);
33 if (link) {
34 $(this).click(Drupal.formBuilder.clickField).addClass('form-builder-clickable');
35 $(this).find('div.form-builder-element label').click(Drupal.formBuilder.clickField);
36 }
37 else {
38 $(this).addClass('form-builder-draggable');
39 }
40 }
41 });
42
43 // Disable field functionality on click.
44 $elements.find('input, textarea').bind('mousedown', Drupal.formBuilder.disableField);
45 };
46
47 /**
48 * Behavior to disable preview fields and instead open up the configuration.
49 */
50 Drupal.behaviors.formBuilderFields = function(context) {
51 // Bind a function to all elements to update the preview on change.
52 var $configureForm = $('#form-builder-field-configure');
53
54 $configureForm.find('input, textarea, select')
55 .filter(':not(.form-builder-field-change)')
56 .addClass('form-builder-field-change')
57 .bind('change', Drupal.formBuilder.elementPendingChange);
58
59 $configureForm.find('input.form-text, textarea')
60 .filter(':not(.form-builder-field-keyup)')
61 .addClass('form-builder-field-keyup')
62 .bind('keyup', Drupal.formBuilder.elementPendingChange);
63 }
64
65 /**
66 * Behavior for the entire form builder. Add drag and drop to elements.
67 */
68 Drupal.behaviors.formBuilder = function(context) {
69 $('#form-builder', context).sortable({
70 items: 'div.form-builder-wrapper',
71 handle: 'div.form-builder-title-bar, div.form-builder-element',
72 axis: 'y',
73 opacity: 0.8,
74 forcePlaceholderSize: true,
75 scroll: true,
76 scrollSensitivity: 50,
77 distance: 4, // Pixels before dragging starts.
78 appendTo: 'body',
79 helper: createHelper,
80 sort: Drupal.formBuilder.elementIndent, // Called on drag.
81 start: Drupal.formBuilder.startDrag,
82 stop: Drupal.formBuilder.stopDrag,
83 change: Drupal.formBuilder.checkFieldsets
84 });
85
86 // This helper function is needed to make the appendTo option take effect.
87 function createHelper(e, $el) {
88 return $el.clone().get(0);
89 }
90 };
91
92 /**
93 * Behavior that renders fieldsets as tabs within the field configuration form.
94 */
95 Drupal.behaviors.formBuilderTabs = function(context) {
96 var $fieldsets = $('fieldset.form-builder-group:not(.form-builer-tabs-processed)', context);
97 var $close = $('<a class="close" href="#">' + Drupal.t('Close') + '</a>');
98 var $tabs;
99 var tabs = '';
100
101 // Convert fieldsets to tabs.
102 tabs = '<ul class="form-builder-tabs tabs clear-block">';
103 $fieldsets.children('legend').each(function() {
104 tabs += '<li>' + this.innerHTML + '</li>';
105 $(this).remove();
106 });
107 tabs += '</ul>';
108
109 // Add the new tabs to the page.
110 $tabs = $(tabs);
111 $fieldsets.filter(':first').before($close).before($tabs);
112
113 // Hide all the fieldsets except the first.
114 $fieldsets.filter(':not(:first)').css('display', 'none');
115 $tabs.find('li:first').addClass('active').click(Drupal.formBuilder.clickCancel);
116
117 // Enable tab switching by clicking on each tab.
118 $tabs.find('li:not(.close)').each(function(index) {
119 $(this).click(function() {
120 $fieldsets.filter(':visible').css('display', 'none');
121 $fieldsets.eq(index).css('display', 'block');
122 $tabs.find('li.active').removeClass('active').unbind('click', Drupal.formBuilder.clickCancel);
123 $(this).addClass('active').click(Drupal.formBuilder.clickCancel);
124 Drupal.formBuilder.fixTableDragTabs($fieldsets.eq(index).get(0));
125 });
126 });
127
128 $close.click(Drupal.formBuilder.clickCancel);
129
130 // Add guard class.
131 $fieldsets.addClass('form-builer-tabs-processed');
132 };
133
134 /**
135 * Submit the delete form via AJAX or close the form with the cancel link.
136 */
137 Drupal.behaviors.formBuilderDeleteConfirmation = function(context) {
138 $confirmForm = $('form.confirmation');
139 if ($confirmForm.size()) {
140 $confirmForm.submit(Drupal.formBuilder.deleteField);
141 $confirmForm.find('a').click(Drupal.formBuilder.clickCancel);
142 }
143 }
144
145 /**
146 * Keeps record of if a mouse button is pressed.
147 */
148 Drupal.behaviors.formBuilderMousePress = function(context) {
149 if (context == document) {
150 $('body').mousedown(function() { Drupal.formBuilder.mousePressed = 1; });
151 $('body').mouseup(function() { Drupal.formBuilder.mousePressed = 0; });
152 }
153 }
154
155 /**
156 * Scrolls the add new field block with the window.
157 */
158 Drupal.behaviors.formBuilderBlockScroll = function(context) {
159 var $list = $('ul.form-builder-fields', context);
160
161 if ($list.size()) {
162 var $block = $list.parents('div.block:first').css('position', 'relative');
163 var blockScrollStart = $block.offset().top;
164
165 function blockScroll() {
166 // Do not move the palette while dragging a field.
167 if (Drupal.formBuilder.activeDragUi) {
168 return;
169 }
170
171 var windowOffset = $(window).scrollTop();
172 var blockHeight = $block.height();
173 var formBuilderHeight = $('#form-builder').height();
174 if (windowOffset - blockScrollStart > 0) {
175 // Do not scroll beyond the bottom of the editing area.
176 var newTop = Math.min(windowOffset - blockScrollStart + 20, formBuilderHeight - blockHeight);
177 $block.animate({ top: (newTop + 'px') }, 'fast');
178 }
179 else {
180 $block.animate({ top: '0px' }, 'fast');
181 }
182 }
183
184 var timeout = false;
185 function scrollTimeout() {
186 if (timeout) {
187 clearTimeout(timeout);
188 }
189 timeout = setTimeout(blockScroll, 100);
190 }
191
192 $(window).scroll(scrollTimeout);
193 }
194 }
195
196 /**
197 * Behavior for the Add a field block.
198 * @param {Object} context
199 */
200 Drupal.behaviors.formBuilderNewField = function(context) {
201 var $list = $('ul.form-builder-fields', context);
202
203 if ($list.size()) {
204 // Allow items to be copied from the list of new fields.
205 $list.children('li:not(.ui-draggable)').draggable({
206 opacity: 0.8,
207 helper: 'clone',
208 scroll: true,
209 scrollSensitivity: 50,
210 containment: 'body',
211 connectToSortable: ['#form-builder'],
212 start: Drupal.formBuilder.startPaletteDrag,
213 stop: Drupal.formBuilder.stopPaletteDrag,
214 change: Drupal.formBuilder.checkFieldsets
215 });
216 }
217 }
218
219 Drupal.formBuilder = {
220 // Variable to prevent multiple requests.
221 updatingElement: false,
222 // Variables to allow delayed updates on textfields and textareas.
223 updateDelayElement: false,
224 updateDelay: false,
225 // Variable holding the actively edited element (if any).
226 activeElement: false,
227 // Variable holding the active drag object (if any).
228 activeDragUi: false,
229 // Variable of the time of the last update, used to prevent old data from
230 // replacing newer updates.
231 lastUpdateTime: 0,
232 // Status of mouse click.
233 mousePressed: 0
234 };
235
236 /**
237 * Event callback for mouseover of fields. Adds hover class.
238 */
239 Drupal.formBuilder.addHover = function() {
240 // Do not add hover effect while dragging over other fields.
241 if (!Drupal.formBuilder.activeDragUi && !Drupal.formBuilder.mousePressed) {
242 if ($(this).find('div.form-builder-hover').size() == 0) {
243 $(this).addClass('form-builder-hover');
244 }
245 }
246 }
247
248 /**
249 * Event callback for mouseout of fields. Removes hover class.
250 */
251 Drupal.formBuilder.removeHover = function() {
252 // Do not add hover effect while dragging over other fields.
253 if (!Drupal.formBuilder.activeDragUi && !Drupal.formBuilder.mousePressed) {
254 $(this).removeClass('form-builder-hover');
255 }
256 }
257
258 /**
259 * Click handler for fields.
260 *
261 * Note this is applied to both the entire field and to the labels within the
262 * field, as they have special browser behavior that needs to be overridden.
263 */
264 Drupal.formBuilder.clickField = function(e) {
265 // Allow select lists to be clicked on without opening the edit options.
266 if ($(e.target).is('select')) {
267 return;
268 }
269
270 var link = $(this).parents('div.form-builder-wrapper:first').find('a.configure').get(0);
271 Drupal.formBuilder.editField.apply(link);
272
273 return false;
274 }
275
276 /**
277 * Mousedown event on element previews.
278 */
279 Drupal.formBuilder.disableField = function(e) {
280 return false;
281 }
282
283 /**
284 * Load the edit form from the server.
285 */
286 Drupal.formBuilder.editField = function() {
287 var element = $(this).parents('div.form-builder-wrapper').get(0);
288 var link = this;
289
290 // Prevent duplicate clicks from taking effect if already handling a click.
291 if (Drupal.formBuilder.updatingElement) {
292 return false;
293 }
294
295 // If clicking on the link a second time, close the form instead of open.
296 if (element == Drupal.formBuilder.activeElement && link == Drupal.formBuilder.activeLink) {
297 $(link).addClass('progress');
298 Drupal.formBuilder.closeActive(function() {
299 $(link).removeClass('progress');
300 });
301 Drupal.formBuilder.unsetActive();
302 return false;
303 }
304
305 var getForm = function() {
306 $.ajax({
307 url: link.href,
308 type: 'GET',
309 dataType: 'json',
310 data: 'js=1',
311 success: Drupal.formBuilder.displayForm,
312 });
313 };
314
315 $(link).addClass('progress');
316 Drupal.formBuilder.updatingElement = true;
317 Drupal.formBuilder.closeActive(getForm);
318 Drupal.formBuilder.setActive(element, link);
319
320 return false;
321 };
322
323 /**
324 * Click handler for deleting a field.
325 */
326 Drupal.formBuilder.deleteField = function() {
327 $(this).parents('div.form-builder-wrapper:first').animate({ height: 'hide', opacity: 'hide' }, 'normal', function() {
328 // If this is a unique field, show the field in the palette again.
329 var elementId = $(this).find('div.form-builder-element').attr('id');
330 $('ul.form-builder-fields').find('li.' + elementId).show('slow');
331 // Remove the field from the form.
332 $(this).remove();
333 // Check for empty fieldsets.
334 Drupal.formBuilder.checkFieldsets(null, null, true);
335 });
336 }
337
338 Drupal.formBuilder.clickCancel = function() {
339 Drupal.formBuilder.closeActive();
340 Drupal.formBuilder.unsetActive();
341 return false;
342 }
343
344 /**
345 * Display the edit form from the server.
346 */
347 Drupal.formBuilder.displayForm = function(response) {
348 var $preview = $('#form-builder-element-' + response.elementId);
349 var $form = $(response.html).insertAfter($preview).css('display', 'none');
350 Drupal.attachBehaviors($form.parent().get(0));
351
352 $form
353 // Add the ajaxForm behavior to the new form.
354 .ajaxForm()
355 // Using the 'data' $.ajaxForm property doesn't seem to work.
356 // Manually add a hidden element to pass additional data on submit.
357 .prepend('<input type="hidden" name="return" value="field" />')
358 // Add in any messages from the server.
359 .find('fieldset:visible:first').prepend(response.messages);
360
361 $form.slideDown(function() {
362 $form.parents('div.form-builder-wrapper:first').find('a.progress').removeClass('progress');
363 });
364 //Drupal.unfreezeHeight();
365
366 Drupal.formBuilder.updatingElement = false;
367 };
368
369 /**
370 * Upon changing a field, submit via AJAX to the server.
371 */
372 Drupal.formBuilder.elementChange = function() {
373 if (!Drupal.formBuilder.updatingElement) {
374 $(this).parents('form:first').ajaxSubmit({
375 success: Drupal.formBuilder.updateElement,
376 dataType: 'json',
377 });
378 }
379
380 // Clear any pending updates until further changes are made.
381 if (Drupal.formBuilder.updateDelay) {
382 clearTimeout(Drupal.formBuilder.updateDelay);
383 }
384
385 Drupal.formBuilder.updatingElement = true;
386 };
387
388 /**
389 * Update a field after a delay.
390 *
391 * Similar to immediately changing a field, this field as pending changes that
392 * will be updated after a delay. This includes textareas and textfields in
393 * which updating continuously would be a strain the server and actually slow
394 * down responsiveness.
395 */
396 Drupal.formBuilder.elementPendingChange = function(e) {
397 // Only operate on "normal" keys, excluding special function keys.
398 // http://protocolsofmatrix.blogspot.com/2007/09/javascript-keycode-reference-table-for.html
399 if (e.type == 'keyup' && !(
400 e.keyCode >= 48 && e.keyCode <= 90 || // 0-9, A-Z.
401 e.keyCode >= 93 && e.keyCode <= 111 || // Number pad.
402 e.keyCode >= 186 && e.keyCode <= 222 || // Symbols.
403 e.keyCode == 8) // Backspace.
404 ) {
405 return;
406 }
407
408 if (Drupal.formBuilder.updateDelay) {
409 clearTimeout(Drupal.formBuilder.updateDelay);
410 }
411 Drupal.formBuilder.updateDelayElement = this;
412 Drupal.formBuilder.updateDelay = setTimeout("Drupal.formBuilder.elementChange.apply(Drupal.formBuilder.updateDelayElement, [true])", 500);
413 };
414
415 /**
416 * After submitting the change to the server, display the updated element.
417 */
418 Drupal.formBuilder.updateElement = function(response) {
419 var $configureForm = $('#form-builder-field-configure');
420
421 // Do not let older requests replace newer updates.
422 if (response.time < Drupal.formBuilder.lastUpdateTime) {
423 return;
424 }
425 else {
426 Drupal.formBuilder.lastUpdateTime = response.time;
427 }
428
429 // Set the error class on fields.
430 $configureForm.find('.error').removeClass('error');
431 if (response.errors) {
432 for (var elementName in response.errors) {
433 elementName = elementName.replace(/([a-z0-9_]+)\](.*)/, '$1$2]');
434 $configureForm.find('[name=' + elementName + ']').addClass('error');
435 }
436 }
437
438 // Display messages, if any.
439 $configureForm.find('.messages').remove();
440 if (response.messages) {
441 $configureForm.find('fieldset:visible:first').prepend(response.messages);
442 }
443
444 // Do not update the element if errors were received.
445 if (!response.errors) {
446 var $exisiting = $('#form-builder-element-' + response.elementId);
447 var $new = $(response.html).find('div.form-builder-element:first');
448 $exisiting.replaceWith($new);
449
450 // Expand root level fieldsets after updating to prevent them from closing
451 // after every update.
452 $new.children('fieldset.collapsible').removeClass('collapsed');
453 Drupal.attachBehaviors($new.parent().get(0));
454 }
455
456 // Set the variable stating we're done updating.
457 Drupal.formBuilder.updatingElement = false;
458 };
459
460 /**
461 * When adding a new field, remove the placeholder and insert the new element.
462 */
463 Drupal.formBuilder.addElement = function(response) {
464 // This is very similar to the update element callback, only we replace the
465 // entire wrapper instead of just the element.
466 var $exisiting = $('#form-builder-element-' + response.elementId).parent();
467 var $new = $(response.html).find('div.form-builder-element:first').parent();
468 $exisiting.replaceWith($new);
469 Drupal.attachBehaviors($new.get(0));
470
471 // Set the variable stating we're done updating.
472 Drupal.formBuilder.updatingElement = false;
473
474 // Insert the new position form containing the new element.
475 $('#form-builder-positions').replaceWith(response.positionForm);
476
477 // Submit the new positions form to save the new element position.
478 Drupal.formBuilder.updateElementPosition($new.get(0));
479 };
480
481 /**
482 * Given an element, update it's position (weight and parent) on the server.
483 */
484 Drupal.formBuilder.updateElementPosition = function(element) {
485 // Update weights of all children within this element's parent.
486 $(element).parent().children('div.form-builder-wrapper').each(function(index) {
487 var child_id = $(this).children('div.form-builder-element:first').attr('id');
488 $('#form-builder-positions input.form-builder-weight').filter('.' + child_id).val(index);
489 });
490
491 // Update this element's parent.
492 var $parent = $(element).parents('div.form-builder-element:first');
493 var parent_id = $parent.size() ? $parent.attr('id').replace(/form-builder-element-(.*)/, '$1') : 0;
494 var child_id = $(element).children('div.form-builder-element:first').attr('id');
495 $('#form-builder-positions input.form-builder-parent').filter('.' + child_id).val(parent_id);
496
497 // Submit the position form via AJAX to save the new weights and parents.
498 $('#form-builder-positions').ajaxSubmit();
499 }
500
501 /**
502 * Called when a field is about to be moved via Sortables.
503 *
504 * @param e
505 * The event object containing status information about the event.
506 * @param ui
507 * The jQuery Sortables object containing information about the sortable.
508 */
509 Drupal.formBuilder.startDrag = function(e, ui) {
510 Drupal.formBuilder.activeDragUi = ui;
511 }
512
513 /**
514 * Called when a field has been moved via Sortables.
515 *
516 * @param e
517 * The event object containing status information about the event.
518 * @param ui
519 * The jQuery Sortables object containing information about the sortable.
520 */
521 Drupal.formBuilder.stopDrag = function(e, ui){
522 var element = ui.item.get(0);
523
524 // If the element is a new field from the palette, update it with a real field.
525 if ($(element).is('.ui-draggable')) {
526 var name = 'new_' + new Date().getTime();
527 // If this is a "unique" element, its element ID is hard-coded.
528 if ($(element).is('.form-builder-unique')) {
529 name = element.className.replace(/^.*?form-builder-element-([a-z0-9_]+).*?$/, '$1');
530 }
531
532 var $ajaxPlaceholder = $('<div class="form-builder-wrapper form-builder-new-field"><div id="form-builder-element-' + name + '" class="form-builder-element"><span class="progress">' + Drupal.t('Please wait...') + '</span></div></div>');
533
534 $.ajax({
535 url: $(element).find('a').get(0).href,
536 type: 'GET',
537 dataType: 'json',
538 data: 'js=1&element_id=' + name,
539 success: Drupal.formBuilder.addElement,
540 });
541
542 $(element).replaceWith($ajaxPlaceholder);
543
544 Drupal.formBuilder.updatingElement = true;
545 }
546 // Update the positions (weights and parents) in the form cache.
547 else {
548 Drupal.formBuilder.updateElementPosition(element);
549 }
550
551 Drupal.formBuilder.activeDragUi = false;
552
553 // Scroll the palette into view.
554 $(window).scroll();
555 }
556
557 /**
558 * Called when a field is about to be moved from the new field palette.
559 *
560 * @param e
561 * The event object containing status information about the event.
562 * @param ui
563 * The jQuery Sortables object containing information about the sortable.
564 */
565 Drupal.formBuilder.startPaletteDrag = function(e, ui) {
566 if ($(this).is('.form-builder-unique')) {
567 $(this).css('visibility', 'hidden');
568 }
569
570 Drupal.formBuilder.activeDragUi = ui;
571 }
572
573 /**
574 * Called after a field has been moved from the new field palette.
575 *
576 * @param e
577 * The event object containing status information about the event.
578 * @param ui
579 * The jQuery Sortables object containing information about the sortable.
580 */
581 Drupal.formBuilder.stopPaletteDrag = function(e, ui) {
582 // If the activeDragUi is still set, we did not drop onto the form.
583 if (Drupal.formBuilder.activeDragUi) {
584 ui.helper.remove();
585 Drupal.formBuilder.activeDragUi = false;
586 $(this).css('visibility', '');
587 $(window).scroll();
588 }
589 // If dropped onto the form and a unique field, remove it from the palette.
590 else if ($(this).is('.form-builder-unique')){
591 $(this).animate({ height: '0', width: '0' }, function() {
592 $(this).css({ visibility: '', height: '', width: '', display: 'none' });
593 });
594 }
595 }
596
597 /**
598 * Update the indentation and width of elements as they move over fieldsets.
599 *
600 * This function is called on every mouse movement during a Sortables drag.
601 *
602 * @param e
603 * The event object containing status information about the event.
604 * @param ui
605 * The jQuery Sortables object containing information about the sortable.
606 */
607 Drupal.formBuilder.elementIndent = function(e, ui) {
608 var placeholder = ui.placeholder.get(0);
609 var helper = ui.helper.get(0);
610 var item = ui.item.get(0);
611
612 // Do not affect the elements being dragged from the pallette.
613 if ($(item).is('li')) {
614 return;
615 }
616
617 // Turn on the placeholder item (which is in the final location) to take some stats.
618 $(placeholder).css('visibility', 'visible');
619 var difference = $(helper).width() - $(placeholder).width();
620 var offset = $(placeholder).offset().left;
621 $(placeholder).css('visibility', 'hidden');
622
623 // Adjust the helper to match the location and width of the real item.
624 var newWidth = $(helper).width() - difference;
625 $(helper).css('width', newWidth + 'px');
626 $(helper).css('left', offset + 'px');
627 }
628
629 /**
630 * Insert DIVs into empty fieldsets so that items can be dropped within them.
631 *
632 * This function is called every time an element changes positions during
633 * a Sortables drag and drop operation.
634 *
635 * @param e
636 * The event object containing status information about the event.
637 * @param ui
638 * The jQuery Sortables object containing information about the sortable.
639 * @param
640 */
641 Drupal.formBuilder.checkFieldsets = function(e, ui, expand) {
642 var $fieldsets = $('#form-builder').find('div.form-builder-element > fieldset.form-builder-fieldset');
643 var emptyFieldsets = [];
644
645 // Remove all current fieldset placeholders.
646 $fieldsets.find('.ui-sortable-placeholder').siblings('div.form-builder-empty-placeholder').remove();
647
648 // Find all empty fieldsets.
649 $fieldsets.each(function() {
650 // Check for empty collapsible fieldsets.
651 if ($(this).children('div.fieldset-wrapper').size()) {
652 if ($(this).children('div.fieldset-wrapper').children(':not(.description):visible, .ui-sortable-placeholder').filter().size() == 0) {
653 emptyFieldsets.push(this);
654 }
655 }
656 // Check for empty normal fieldsets.
657 if ($(this).children(':not(legend, .description):visible, .ui-sortable-placeholder').size() == 0) {
658 emptyFieldsets.push(this);
659 }
660 });
661
662 // Add a placeholder DIV in the empty fieldsets.
663 $(emptyFieldsets).each(function() {
664 var wrapper = $(this).children('div.fieldset-wrapper').get(0) || this;
665 var $placeholder = $(Drupal.settings.formBuilder.emptyFieldset).css('display', 'none').appendTo(wrapper);
666 if (expand) {
667 $placeholder.slideDown();
668 }
669 else {
670 $placeholder.css('display', 'block');
671 }
672 });
673
674 $('#form-builder').sortable('refresh');
675 }
676
677 Drupal.formBuilder.setActive = function(element, link) {
678 Drupal.formBuilder.unsetActive();
679 Drupal.formBuilder.activeElement = element;
680 Drupal.formBuilder.activeLink = link;
681 $(Drupal.formBuilder.activeElement).addClass('form-builder-active');
682 };
683
684 Drupal.formBuilder.unsetActive = function() {
685 if (Drupal.formBuilder.activeElement) {
686 $(Drupal.formBuilder.activeElement).removeClass('form-builder-active');
687 Drupal.formBuilder.activeElement = false;
688 Drupal.formBuilder.activeLink = false;
689 }
690 }
691
692 Drupal.formBuilder.closeActive = function(callback) {
693 if (Drupal.formBuilder.activeElement) {
694 var $activeForm = $(Drupal.formBuilder.activeElement).find('form');
695
696 if ($activeForm.size()) {
697 Drupal.freezeHeight();
698 $activeForm.slideUp(function(){
699 $(this).remove();
700 if (callback) {
701 callback.call();
702 }
703 });
704 }
705 }
706 else if (callback) {
707 callback.call();
708 }
709
710 return false;
711 };
712
713 /**
714 * Work around for tabledrags within tabs. On load, if the tab was hidden the
715 * offsets cannot be calculated correctly. Recalculate and update the tableDrag.
716 */
717 Drupal.formBuilder.fixTableDragTabs = function(context) {
718 if (Drupal.tableDrag && Drupal.tableDrag.length > 1) {
719 for (var n in Drupal.tableDrag) {
720 if (typeof(Drupal.tableDrag[n]) == 'object') {
721 var table = $('#' + n, context).get(0);
722 if (table) {
723 var indent = Drupal.theme('tableDragIndentation');
724 var testCell = $('tr.draggable:first td:first', table).prepend(indent).prepend(indent);
725 Drupal.tableDrag[n].indentAmount = $('.indentation', testCell).get(1).offsetLeft - $('.indentation', testCell).get(0).offsetLeft;
726 $('.indentation', testCell).slice(0, 2).remove();
727 }
728 }
729 }
730 }
731 }

  ViewVC Help
Powered by ViewVC 1.1.2