[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/form_builder/ -> form_builder.js (source)

   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  }


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7