| [ Index ] |
PHP Cross Reference of Drupal 6 (gatewave) |
[Summary view] [Print] [Text view]
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 359 $form.slideDown(function() { 360 $form.parents('div.form-builder-wrapper:first').find('a.progress').removeClass('progress'); 361 }); 362 //Drupal.unfreezeHeight(); 363 364 Drupal.formBuilder.updatingElement = false; 365 }; 366 367 /** 368 * Upon changing a field, submit via AJAX to the server. 369 */ 370 Drupal.formBuilder.elementChange = function() { 371 if (!Drupal.formBuilder.updatingElement) { 372 $(this).parents('form:first').ajaxSubmit({ 373 success: Drupal.formBuilder.updateElement, 374 dataType: 'json', 375 }); 376 } 377 378 // Clear any pending updates until further changes are made. 379 if (Drupal.formBuilder.updateDelay) { 380 clearTimeout(Drupal.formBuilder.updateDelay); 381 } 382 383 Drupal.formBuilder.updatingElement = true; 384 }; 385 386 /** 387 * Update a field after a delay. 388 * 389 * Similar to immediately changing a field, this field as pending changes that 390 * will be updated after a delay. This includes textareas and textfields in 391 * which updating continuously would be a strain the server and actually slow 392 * down responsiveness. 393 */ 394 Drupal.formBuilder.elementPendingChange = function(e) { 395 // Only operate on "normal" keys, excluding special function keys. 396 // http://protocolsofmatrix.blogspot.com/2007/09/javascript-keycode-reference-table-for.html 397 if (e.type == 'keyup' && !( 398 e.keyCode >= 48 && e.keyCode <= 90 || // 0-9, A-Z. 399 e.keyCode >= 93 && e.keyCode <= 111 || // Number pad. 400 e.keyCode >= 186 && e.keyCode <= 222 || // Symbols. 401 e.keyCode == 8) // Backspace. 402 ) { 403 return; 404 } 405 406 if (Drupal.formBuilder.updateDelay) { 407 clearTimeout(Drupal.formBuilder.updateDelay); 408 } 409 Drupal.formBuilder.updateDelayElement = this; 410 Drupal.formBuilder.updateDelay = setTimeout("Drupal.formBuilder.elementChange.apply(Drupal.formBuilder.updateDelayElement, [true])", 500); 411 }; 412 413 /** 414 * After submitting the change to the server, display the updated element. 415 */ 416 Drupal.formBuilder.updateElement = function(response) { 417 var $configureForm = $('#form-builder-field-configure'); 418 419 // Do not let older requests replace newer updates. 420 if (response.time < Drupal.formBuilder.lastUpdateTime) { 421 return; 422 } 423 else { 424 Drupal.formBuilder.lastUpdateTime = response.time; 425 } 426 427 // Set the error class on fields. 428 $configureForm.find('.error').removeClass('error'); 429 if (response.errors) { 430 for (var elementName in response.errors) { 431 elementName = elementName.replace(/([a-z0-9_]+)\](.*)/, '$1$2]'); 432 $configureForm.find('[name=' + elementName + ']').addClass('error'); 433 } 434 } 435 436 // Display messages, if any. 437 $configureForm.find('.messages').remove(); 438 if (response.messages) { 439 $configureForm.find('fieldset:visible:first').prepend(response.messages); 440 } 441 442 // Do not update the element if errors were received. 443 if (!response.errors) { 444 var $exisiting = $('#form-builder-element-' + response.elementId); 445 var $new = $(response.html).find('div.form-builder-element:first'); 446 $exisiting.replaceWith($new); 447 448 // Expand root level fieldsets after updating to prevent them from closing 449 // after every update. 450 $new.children('fieldset.collapsible').removeClass('collapsed'); 451 Drupal.attachBehaviors($new.parent().get(0)); 452 } 453 454 // Set the variable stating we're done updating. 455 Drupal.formBuilder.updatingElement = false; 456 }; 457 458 /** 459 * When adding a new field, remove the placeholder and insert the new element. 460 */ 461 Drupal.formBuilder.addElement = function(response) { 462 // This is very similar to the update element callback, only we replace the 463 // entire wrapper instead of just the element. 464 var $exisiting = $('#form-builder-element-' + response.elementId).parent(); 465 var $new = $(response.html).find('div.form-builder-element:first').parent(); 466 $exisiting.replaceWith($new); 467 Drupal.attachBehaviors($new.get(0)); 468 469 // Set the variable stating we're done updating. 470 Drupal.formBuilder.updatingElement = false; 471 472 // Insert the new position form containing the new element. 473 $('#form-builder-positions').replaceWith(response.positionForm); 474 475 // Submit the new positions form to save the new element position. 476 Drupal.formBuilder.updateElementPosition($new.get(0)); 477 }; 478 479 /** 480 * Given an element, update it's position (weight and parent) on the server. 481 */ 482 Drupal.formBuilder.updateElementPosition = function(element) { 483 // Update weights of all children within this element's parent. 484 $(element).parent().children('div.form-builder-wrapper').each(function(index) { 485 var child_id = $(this).children('div.form-builder-element:first').attr('id'); 486 $('#form-builder-positions input.form-builder-weight').filter('.' + child_id).val(index); 487 }); 488 489 // Update this element's parent. 490 var $parent = $(element).parents('div.form-builder-element:first'); 491 var parent_id = $parent.size() ? $parent.attr('id').replace(/form-builder-element-(.*)/, '$1') : 0; 492 var child_id = $(element).children('div.form-builder-element:first').attr('id'); 493 $('#form-builder-positions input.form-builder-parent').filter('.' + child_id).val(parent_id); 494 495 // Submit the position form via AJAX to save the new weights and parents. 496 $('#form-builder-positions').ajaxSubmit(); 497 } 498 499 /** 500 * Called when a field is about to be moved via Sortables. 501 * 502 * @param e 503 * The event object containing status information about the event. 504 * @param ui 505 * The jQuery Sortables object containing information about the sortable. 506 */ 507 Drupal.formBuilder.startDrag = function(e, ui) { 508 Drupal.formBuilder.activeDragUi = ui; 509 } 510 511 /** 512 * Called when a field has been moved via Sortables. 513 * 514 * @param e 515 * The event object containing status information about the event. 516 * @param ui 517 * The jQuery Sortables object containing information about the sortable. 518 */ 519 Drupal.formBuilder.stopDrag = function(e, ui){ 520 var element = ui.item.get(0); 521 522 // If the element is a new field from the palette, update it with a real field. 523 if ($(element).is('.ui-draggable')) { 524 var name = 'new_' + new Date().getTime(); 525 // If this is a "unique" element, its element ID is hard-coded. 526 if ($(element).is('.form-builder-unique')) { 527 name = element.className.replace(/^.*?form-builder-element-([a-z0-9_]+).*?$/, '$1'); 528 } 529 530 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>'); 531 532 $.ajax({ 533 url: $(element).find('a').get(0).href, 534 type: 'GET', 535 dataType: 'json', 536 data: 'js=1&element_id=' + name, 537 success: Drupal.formBuilder.addElement, 538 }); 539 540 $(element).replaceWith($ajaxPlaceholder); 541 542 Drupal.formBuilder.updatingElement = true; 543 } 544 // Update the positions (weights and parents) in the form cache. 545 else { 546 Drupal.formBuilder.updateElementPosition(element); 547 } 548 549 Drupal.formBuilder.activeDragUi = false; 550 551 // Scroll the palette into view. 552 $(window).scroll(); 553 } 554 555 /** 556 * Called when a field is about to be moved from the new field palette. 557 * 558 * @param e 559 * The event object containing status information about the event. 560 * @param ui 561 * The jQuery Sortables object containing information about the sortable. 562 */ 563 Drupal.formBuilder.startPaletteDrag = function(e, ui) { 564 if ($(this).is('.form-builder-unique')) { 565 $(this).css('visibility', 'hidden'); 566 } 567 568 Drupal.formBuilder.activeDragUi = ui; 569 } 570 571 /** 572 * Called after a field has been moved from the new field palette. 573 * 574 * @param e 575 * The event object containing status information about the event. 576 * @param ui 577 * The jQuery Sortables object containing information about the sortable. 578 */ 579 Drupal.formBuilder.stopPaletteDrag = function(e, ui) { 580 // If the activeDragUi is still set, we did not drop onto the form. 581 if (Drupal.formBuilder.activeDragUi) { 582 ui.helper.remove(); 583 Drupal.formBuilder.activeDragUi = false; 584 $(this).css('visibility', ''); 585 $(window).scroll(); 586 } 587 // If dropped onto the form and a unique field, remove it from the palette. 588 else if ($(this).is('.form-builder-unique')){ 589 $(this).animate({ height: '0', width: '0' }, function() { 590 $(this).css({ visibility: '', height: '', width: '', display: 'none' }); 591 }); 592 } 593 } 594 595 /** 596 * Update the indentation and width of elements as they move over fieldsets. 597 * 598 * This function is called on every mouse movement during a Sortables drag. 599 * 600 * @param e 601 * The event object containing status information about the event. 602 * @param ui 603 * The jQuery Sortables object containing information about the sortable. 604 */ 605 Drupal.formBuilder.elementIndent = function(e, ui) { 606 var placeholder = ui.placeholder.get(0); 607 var helper = ui.helper.get(0); 608 var item = ui.item.get(0); 609 610 // Do not affect the elements being dragged from the pallette. 611 if ($(item).is('li')) { 612 return; 613 } 614 615 // Turn on the placeholder item (which is in the final location) to take some stats. 616 $(placeholder).css('visibility', 'visible'); 617 var difference = $(helper).width() - $(placeholder).width(); 618 var offset = $(placeholder).offset().left; 619 $(placeholder).css('visibility', 'hidden'); 620 621 // Adjust the helper to match the location and width of the real item. 622 var newWidth = $(helper).width() - difference; 623 $(helper).css('width', newWidth + 'px'); 624 $(helper).css('left', offset + 'px'); 625 } 626 627 /** 628 * Insert DIVs into empty fieldsets so that items can be dropped within them. 629 * 630 * This function is called every time an element changes positions during 631 * a Sortables drag and drop operation. 632 * 633 * @param e 634 * The event object containing status information about the event. 635 * @param ui 636 * The jQuery Sortables object containing information about the sortable. 637 * @param 638 */ 639 Drupal.formBuilder.checkFieldsets = function(e, ui, expand) { 640 var $fieldsets = $('#form-builder').find('div.form-builder-element > fieldset.form-builder-fieldset'); 641 var emptyFieldsets = []; 642 643 // Remove all current fieldset placeholders. 644 $fieldsets.find('.ui-sortable-placeholder').siblings('div.form-builder-empty-placeholder').remove(); 645 646 // Find all empty fieldsets. 647 $fieldsets.each(function() { 648 // Check for empty collapsible fieldsets. 649 if ($(this).children('div.fieldset-wrapper').size()) { 650 if ($(this).children('div.fieldset-wrapper').children(':not(.description):visible, .ui-sortable-placeholder').filter().size() == 0) { 651 emptyFieldsets.push(this); 652 } 653 } 654 // Check for empty normal fieldsets. 655 if ($(this).children(':not(legend, .description):visible, .ui-sortable-placeholder').size() == 0) { 656 emptyFieldsets.push(this); 657 } 658 }); 659 660 // Add a placeholder DIV in the empty fieldsets. 661 $(emptyFieldsets).each(function() { 662 var wrapper = $(this).children('div.fieldset-wrapper').get(0) || this; 663 var $placeholder = $(Drupal.settings.formBuilder.emptyFieldset).css('display', 'none').appendTo(wrapper); 664 if (expand) { 665 $placeholder.slideDown(); 666 } 667 else { 668 $placeholder.css('display', 'block'); 669 } 670 }); 671 672 $('#form-builder').sortable('refresh'); 673 } 674 675 Drupal.formBuilder.setActive = function(element, link) { 676 Drupal.formBuilder.unsetActive(); 677 Drupal.formBuilder.activeElement = element; 678 Drupal.formBuilder.activeLink = link; 679 $(Drupal.formBuilder.activeElement).addClass('form-builder-active'); 680 }; 681 682 Drupal.formBuilder.unsetActive = function() { 683 if (Drupal.formBuilder.activeElement) { 684 $(Drupal.formBuilder.activeElement).removeClass('form-builder-active'); 685 Drupal.formBuilder.activeElement = false; 686 Drupal.formBuilder.activeLink = false; 687 } 688 } 689 690 Drupal.formBuilder.closeActive = function(callback) { 691 if (Drupal.formBuilder.activeElement) { 692 var $activeForm = $(Drupal.formBuilder.activeElement).find('form'); 693 694 if ($activeForm.size()) { 695 Drupal.freezeHeight(); 696 $activeForm.slideUp(function(){ 697 $(this).remove(); 698 if (callback) { 699 callback.call(); 700 } 701 }); 702 } 703 } 704 else if (callback) { 705 callback.call(); 706 } 707 708 return false; 709 }; 710 711 /** 712 * Work around for tabledrags within tabs. On load, if the tab was hidden the 713 * offsets cannot be calculated correctly. Recalculate and update the tableDrag. 714 */ 715 Drupal.formBuilder.fixTableDragTabs = function(context) { 716 if (Drupal.tableDrag && Drupal.tableDrag.length > 1) { 717 for (var n in Drupal.tableDrag) { 718 if (typeof(Drupal.tableDrag[n]) == 'object') { 719 var table = $('#' + n, context).get(0); 720 if (table) { 721 var indent = Drupal.theme('tableDragIndentation'); 722 var testCell = $('tr.draggable:first td:first', table).prepend(indent).prepend(indent); 723 Drupal.tableDrag[n].indentAmount = $('.indentation', testCell).get(1).offsetLeft - $('.indentation', testCell).get(0).offsetLeft; 724 $('.indentation', testCell).slice(0, 2).remove(); 725 } 726 } 727 } 728 } 729 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Mar 24 11:18:33 2011 | Cross-referenced by PHPXref 0.7 |