(function($) {
/**
* @file form_builder.js
* Provide enhancements to the form building user interface.
*/
Drupal.behaviors.formBuilderElement = function(context) {
var $wrappers = $('div.form-builder-wrapper:not(.form-builder-processed)', context);
var $elements = $('div.form-builder-element:not(.form-builder-processed)', context);
// If the context itself is a wrapper, add it to the list.
if ($(context).is('div.form-builder-wrapper:not(.form-builder-processed)')) {
$wrappers = $wrappers.add(context);
}
// If the context itself is an element, add to the list.
else if ($(context).is('div.form-builder-element:not(.form-builder-processed)')) {
$elements = $elements.add(context);
}
// Add a guard class.
$wrappers.addClass('form-builder-processed');
$elements.addClass('form-builder-processed');
// Add over effect on rollover.
// The .hover() method is not used to avoid issues with nested hovers.
$wrappers.not('div.form-builder-empty-placeholder')
.bind('mouseover', Drupal.formBuilder.addHover)
.bind('mouseout', Drupal.formBuilder.removeHover);
// Add AJAX to edit links.
$wrappers.find('span.form-builder-links a.configure').click(Drupal.formBuilder.editField);
// Add AJAX to remove links.
$wrappers.find('span.form-builder-links a.remove').click(Drupal.formBuilder.editField);
// Add AJAX to entire field for easy editing.
$elements.each(function() {
if ($(this).children('fieldset.form-builder-fieldset').length == 0) {
var link = $(this).parents('div.form-builder-wrapper:first').find('a.configure').get(0);
if (link) {
$(this).click(Drupal.formBuilder.clickField).addClass('form-builder-clickable');
$(this).find('div.form-builder-element label').click(Drupal.formBuilder.clickField);
}
else {
$(this).addClass('form-builder-draggable');
}
}
});
// Disable field functionality on click.
$elements.find('input, textarea').bind('mousedown', Drupal.formBuilder.disableField);
};
/**
* Behavior to disable preview fields and instead open up the configuration.
*/
Drupal.behaviors.formBuilderFields = function(context) {
// Bind a function to all elements to update the preview on change.
var $configureForm = $('#form-builder-field-configure');
$configureForm.find('input, textarea, select')
.not('.form-builder-field-change')
.addClass('form-builder-field-change')
.bind('change', Drupal.formBuilder.elementPendingChange);
$configureForm.find('input.form-text, textarea')
.not('.form-builder-field-keyup')
.addClass('form-builder-field-keyup')
.bind('keyup', Drupal.formBuilder.elementPendingChange);
};
/**
* Behavior for the entire form builder. Add drag and drop to elements.
*/
Drupal.behaviors.formBuilder = function(context) {
var $formbuilder = $('#form-builder');
var $elements = $('.form-builder-wrapper').not('.form-builder-empty-placeholder').not('.ui-draggable');
$elements.draggable({
distance: 4, // Pixels before dragging starts.
handle: 'div.form-builder-title-bar, div.form-builder-element',
helper: 'clone',
appendTo: $formbuilder,
opacity: 0.8,
scope: 'form-builder',
scroll: true,
scrollSensitivity: 50,
zIndex: 100,
start: Drupal.formBuilder.startDrag,
stop: Drupal.formBuilder.stopDrag
});
// This sets the height of the drag target to be at least as high as the field
// palette so that field can be more easily dropped into an empty form. IE6
// does not respect min-height but does treat height in the same manner that
// min-height would be expected. So a check for browser and version is needed
// here.
var property = $.browser.msie && $.browser.version < 7 ? 'height' : 'min-height';
$formbuilder.css(property, $('#form-builder-fields').height());
// Add the placeholder for an empty form.
Drupal.formBuilder.checkForm();
};
/**
* Behavior that renders fieldsets as tabs within the field configuration form.
*/
Drupal.behaviors.formBuilderTabs = function(context) {
var $fieldsets = $('fieldset.form-builder-group:not(.form-builer-tabs-processed)', context);
var $close = $('' + Drupal.t('Close') + '');
var $tabs;
var tabs = '';
// Convert fieldsets to tabs.
tabs = '
';
// Add the new tabs to the page.
$tabs = $(tabs);
$fieldsets.filter(':first').before($close).before($tabs);
// Remove 'fieldset-legend' class from tabs.
$tabs.find('.fieldset-legend').removeClass('fieldset-legend');
// Set clear-block on the parent div.
$tabs.parent().addClass('clear-block');
// Wrap each fieldset's content. This is only needed in D6.
$fieldsets.wrapInner('');
// Hide all the fieldsets except the first.
$fieldsets.not(':first').css('display', 'none');
$tabs.find('li:first').addClass('active').click(Drupal.formBuilder.clickCancel);
// Enable tab switching by clicking on each tab.
$tabs.find('li:not(.close)').each(function(index) {
$(this).click(function() {
$fieldsets.filter(':visible').css('display', 'none');
$fieldsets.eq(index).css('display', 'block');
$tabs.find('li.active').removeClass('active').unbind('click', Drupal.formBuilder.clickCancel);
$(this).addClass('active').click(Drupal.formBuilder.clickCancel);
Drupal.formBuilder.fixTableDragTabs($fieldsets.eq(index).get(0));
});
});
$close.click(Drupal.formBuilder.clickCancel);
// Add guard class.
$fieldsets.addClass('form-builer-tabs-processed');
};
/**
* Submit the delete form via AJAX or close the form with the cancel link.
*/
Drupal.behaviors.formBuilderDeleteConfirmation = function(context) {
var $confirmForm = $('form.confirmation', context);
// If the confirmation form is the context.
if ($(context).is('form.confirmation')) {
$confirmForm = $(context);
}
if ($confirmForm.length) {
$confirmForm.submit(Drupal.formBuilder.deleteField);
$confirmForm.find('a').click(Drupal.formBuilder.clickCancel);
}
};
/**
* Keeps record of if a mouse button is pressed.
*/
Drupal.behaviors.formBuilderMousePress = function(context) {
if (context == document) {
$('body').mousedown(function() { Drupal.formBuilder.mousePressed = 1; });
$('body').mouseup(function() { Drupal.formBuilder.mousePressed = 0; });
}
};
/**
* Scrolls the add new field block with the window.
*/
Drupal.behaviors.formBuilderBlockScroll = function(context) {
var $list = $('ul.form-builder-fields', context);
if ($list.length) {
var $block = $list.parents('div.block:first').css('position', 'relative');
var blockScrollStart = $block.offset().top;
function blockScroll() {
// Do not move the palette while dragging a field.
if (Drupal.formBuilder.activeDragUi) {
return;
}
var toolbarHeight = parseInt($('body.toolbar').css('padding-top'));
var windowOffset = $(window).scrollTop() + (toolbarHeight ? toolbarHeight : 0);
var blockHeight = $block.height();
var formBuilderHeight = $('#form-builder').height();
if (windowOffset - blockScrollStart > 0) {
// Do not scroll beyond the bottom of the editing area.
var newTop = Math.min(windowOffset - blockScrollStart + 20, formBuilderHeight - blockHeight);
$block.animate({ top: (newTop + 'px') }, 'fast');
}
else {
$block.animate({ top: '0px' }, 'fast');
}
}
var timeout = false;
function scrollTimeout() {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(blockScroll, 100);
}
$(window).scroll(scrollTimeout);
}
};
/**
* Behavior for the Add a field block.
* @param {Object} context
*/
Drupal.behaviors.formBuilderNewField = function(context) {
var $list = $('ul.form-builder-fields', context);
if ($list.length) {
// Allow items to be copied from the list of new fields.
$list.children('li:not(.ui-draggable)').draggable({
opacity: 0.8,
helper: 'clone',
scope: 'form-builder',
scroll: true,
scrollSensitivity: 50,
tolerance: 'pointer',
zIndex: 100,
start: Drupal.formBuilder.startDrag,
stop: Drupal.formBuilder.stopDrag
});
}
};
Drupal.formBuilder = {
// Variable to prevent multiple requests.
updatingElement: false,
// Variables to allow delayed updates on textfields and textareas.
updateDelayElement: false,
updateDelay: false,
// Variable holding the actively edited element (if any).
activeElement: false,
// Variable holding the active drag object (if any).
activeDragUi: false,
// Variables to keep trak of the current and previous drop target. Used to
// prevent overlapping targets from being shown as active at the same time.
activeDropzone: false,
previousDropzones: [],
// Variable of the time of the last update, used to prevent old data from
// replacing newer updates.
lastUpdateTime: 0,
// Status of mouse click.
mousePressed: 0,
// Selector for a custom field configuration form.
fieldConfigureForm: false
};
/**
* Event callback for mouseover of fields. Adds hover class.
*/
Drupal.formBuilder.addHover = function() {
// Do not add hover effect while dragging over other fields.
if (!Drupal.formBuilder.activeDragUi && !Drupal.formBuilder.mousePressed) {
if ($(this).find('div.form-builder-hover').length == 0) {
$(this).addClass('form-builder-hover');
}
}
};
/**
* Event callback for mouseout of fields. Removes hover class.
*/
Drupal.formBuilder.removeHover = function() {
// Do not add hover effect while dragging over other fields.
if (!Drupal.formBuilder.activeDragUi && !Drupal.formBuilder.mousePressed) {
$(this).removeClass('form-builder-hover');
}
};
/**
* Click handler for fields.
*
* Note this is applied to both the entire field and to the labels within the
* field, as they have special browser behavior that needs to be overridden.
*/
Drupal.formBuilder.clickField = function(e) {
// Allow select lists to be clicked on without opening the edit options.
if ($(e.target).is('select')) {
return;
}
// Find the first configure link for this field, ensuring we don't get a link
// belonging to a nested form element within this element.
var $wrapper = $(this).parents('.form-builder-wrapper:first');
var link = $wrapper.find('a.configure').not($wrapper.find('.form-builder-element .form-builder-element a')).get(0);
Drupal.formBuilder.editField.apply(link);
return false;
};
/**
* Mousedown event on element previews.
*/
Drupal.formBuilder.disableField = function(e) {
return false;
};
/**
* Load the edit form from the server.
*/
Drupal.formBuilder.editField = function() {
var $element = $(this).parents('div.form-builder-wrapper');
var $link = $(this);
// Prevent duplicate clicks from taking effect if already handling a click.
if (Drupal.formBuilder.updatingElement) {
return false;
}
// Show loading indicators.
$link.addClass('progress');
// If clicking on the link a second time, close the form instead of open.
if ($element.get(0) == Drupal.formBuilder.activeElement && $link.get(0) == Drupal.formBuilder.activeLink) {
Drupal.formBuilder.closeActive(function() {
$link.removeClass('progress');
});
Drupal.formBuilder.unsetActive();
return false;
}
var getForm = function() {
if (Drupal.formBuilder.fieldConfigureForm) {
$(Drupal.formBuilder.fieldConfigureForm).html(Drupal.settings.formBuilder.fieldLoading);
}
$.ajax({
url: $link.attr('href'),
type: 'GET',
dataType: 'json',
data: 'js=1',
success: Drupal.formBuilder.displayForm
});
};
Drupal.formBuilder.updatingElement = true;
Drupal.formBuilder.closeActive(getForm);
Drupal.formBuilder.setActive($element.get(0), $link.get(0));
return false;
};
/**
* Click handler for deleting a field.
*/
Drupal.formBuilder.deleteField = function() {
$(this).parents('div.form-builder-wrapper:first').animate({ height: 'hide', opacity: 'hide' }, 'normal', function() {
// If this is a unique field, show the field in the palette again.
var elementId = $(this).find('div.form-builder-element').attr('id');
$('ul.form-builder-fields').find('li.' + elementId).show('slow');
// Remove the field from the form.
$(this).remove();
// Check for an entirely empty form and for empty fieldsets.
Drupal.formBuilder.checkForm();
Drupal.formBuilder.checkFieldsets([], true);
});
};
Drupal.formBuilder.clickCancel = function() {
Drupal.formBuilder.closeActive();
Drupal.formBuilder.unsetActive();
return false;
};
/**
* Display the edit form from the server.
*/
Drupal.formBuilder.displayForm = function(response) {
// Update Drupal settings.
if (response.settings) {
$.extend(true, Drupal.settings, response.settings);
}
var $preview = $('#form-builder-element-' + response.elementId);
var $form = $(response.html);
if (Drupal.formBuilder.fieldConfigureForm) {
$(Drupal.formBuilder.fieldConfigureForm).html($form);
$form.css('display', 'none');
}
else {
$form.insertAfter($preview).css('display', 'none');
}
Drupal.attachBehaviors($form.get(0));
$form
// Add the ajaxForm behavior to the new form.
.ajaxForm()
// Using the 'data' $.ajaxForm property doesn't seem to work.
// Manually add a hidden element to pass additional data on submit.
.prepend('')
// Add in any messages from the server.
.find('fieldset:first').find('.fieldset-wrapper:first').prepend(response.messages);
$form.slideDown(function() {
$preview.parents('div.form-builder-wrapper:first').find('a.progress').removeClass('progress');
$form.find('input:visible:first').focus();
});
Drupal.formBuilder.updatingElement = false;
};
/**
* Upon changing a field, submit via AJAX to the server.
*/
Drupal.formBuilder.elementChange = function() {
if (!Drupal.formBuilder.updatingElement) {
$(this).parents('form:first').ajaxSubmit({
success: Drupal.formBuilder.updateElement,
dataType: 'json'
});
}
// Clear any pending updates until further changes are made.
if (Drupal.formBuilder.updateDelay) {
clearTimeout(Drupal.formBuilder.updateDelay);
}
Drupal.formBuilder.updatingElement = true;
};
/**
* Update a field after a delay.
*
* Similar to immediately changing a field, this field as pending changes that
* will be updated after a delay. This includes textareas and textfields in
* which updating continuously would be a strain the server and actually slow
* down responsiveness.
*/
Drupal.formBuilder.elementPendingChange = function(e) {
// Only operate on "normal" keys, excluding special function keys.
// http://protocolsofmatrix.blogspot.com/2007/09/javascript-keycode-reference-table-for.html
if (e.type == 'keyup' && !(
e.keyCode >= 48 && e.keyCode <= 90 || // 0-9, A-Z.
e.keyCode >= 93 && e.keyCode <= 111 || // Number pad.
e.keyCode >= 186 && e.keyCode <= 222 || // Symbols.
e.keyCode == 8) // Backspace.
) {
return;
}
if (Drupal.formBuilder.updateDelay) {
clearTimeout(Drupal.formBuilder.updateDelay);
}
Drupal.formBuilder.updateDelayElement = this;
Drupal.formBuilder.updateDelay = setTimeout("Drupal.formBuilder.elementChange.apply(Drupal.formBuilder.updateDelayElement, [true])", 500);
};
/**
* After submitting the change to the server, display the updated element.
*/
Drupal.formBuilder.updateElement = function(response) {
var $configureForm = $('#form-builder-field-configure');
// Do not let older requests replace newer updates.
if (response.time < Drupal.formBuilder.lastUpdateTime) {
return;
}
else {
Drupal.formBuilder.lastUpdateTime = response.time;
}
// Update Drupal.settings.
if (response.settings) {
$.extend(true, Drupal.settings, response.settings);
}
// Set the error class on fields.
$configureForm.find('.error').removeClass('error');
if (response.errors) {
for (var elementName in response.errors) {
elementName = elementName.replace(/([a-z0-9_]+)\](.*)/, '$1$2]');
$configureForm.find('[name=' + elementName + ']').addClass('error');
}
}
// Display messages, if any.
$configureForm.find('.messages').remove();
if (response.messages) {
$configureForm.find('fieldset:visible:first').find('.fieldset-wrapper:first').prepend(response.messages);
}
// Do not update the element if errors were received.
if (!response.errors) {
var $exisiting = $('#form-builder-element-' + response.elementId);
var $new = $(response.html).find('div.form-builder-element:first');
$exisiting.replaceWith($new);
// Expand root level fieldsets after updating to prevent them from closing
// after every update.
$new.children('fieldset.collapsible').removeClass('collapsed');
Drupal.attachBehaviors($new.get(0));
}
// Set the variable stating we're done updating.
Drupal.formBuilder.updatingElement = false;
};
/**
* When adding a new field, remove the placeholder and insert the new element.
*/
Drupal.formBuilder.addElement = function(response) {
// Update Drupal settings.
if (response.settings) {
$.extend(true, Drupal.settings, response.settings);
}
// This is very similar to the update element callback, only we replace the
// entire wrapper instead of just the element.
var $exisiting = $('#form-builder-element-' + response.elementId).parent();
var $new = $(response.html).find('div.form-builder-element:first').parent();
$exisiting.replaceWith($new);
Drupal.attachBehaviors($new.get(0));
// Set the variable stating we're done updating.
Drupal.formBuilder.updatingElement = false;
// Insert the new position form containing the new element.
$('#form-builder-positions').replaceWith(response.positionForm);
// Submit the new positions form to save the new element position.
Drupal.formBuilder.updateElementPosition($new.get(0));
};
/**
* Given an element, update it's position (weight and parent) on the server.
*/
Drupal.formBuilder.updateElementPosition = function(element) {
var $element = $(element);
// Update weights of all children within this element's parent.
$element.parent().children('div.form-builder-wrapper').each(function(index) {
var child_id = $(this).children('div.form-builder-element:first').attr('id');
$('#form-builder-positions input.form-builder-weight').filter('.' + child_id).val(index);
});
// Update this element's parent.
var $parent = $element.parents('div.form-builder-element:first');
var parent_id = $parent.length ? $parent.attr('id').replace(/form-builder-element-(.*)/, '$1') : 0;
var child_id = $element.children('div.form-builder-element:first').attr('id');
$('#form-builder-positions input.form-builder-parent').filter('.' + child_id).val(parent_id);
// Submit the position form via AJAX to save the new weights and parents.
$('#form-builder-positions').ajaxSubmit();
};
/**
* Called when a field is about to be moved via Sortables.
*
* @param e
* The event object containing status information about the event.
* @param ui
* The jQuery Sortables object containing information about the sortable.
*/
Drupal.formBuilder.startDrag = function(e, ui) {
Drupal.formBuilder.activeDragUi = ui;
var $this = $(this);
if ($this.hasClass('form-builder-unique') || $this.hasClass('form-builder-wrapper')) {
$this.hide();
}
// Check fieldsets and add placeholder text if needed.
Drupal.formBuilder.checkFieldsets([this, ui.helper]);
// Create the drop targets in between the form elements.
Drupal.formBuilder.createDropTargets(this, ui.helper);
};
/**
* Creates drop targets for the dragged element to be dropped into.
*/
Drupal.formBuilder.createDropTargets = function(draggable, helper) {
var $placeholder = $('');
var $elements = $('#form-builder .form-builder-wrapper:not(.form-builder-empty-placeholder)').not(draggable).not(helper);
if ($elements.length == 0) {
// There are no form elements, insert a placeholder
var $formBuilder = $('#form-builder');
$placeholder.height($formBuilder.height());
$placeholder.appendTo($formBuilder);
}
else {
$elements.each(function(i) {
$placeholder.clone().insertAfter(this);
// If the element is the first in its container, add a drop target above it.
if (this == $(this).parent().children('.form-builder-wrapper:not(.ui-draggable-dragging)').not(draggable)[0]) {
$placeholder.clone().insertBefore(this);
}
});
}
// Enable the drop targets
$('#form-builder').find('.form-builder-placeholder, .form-builder-empty-placeholder').droppable({
greedy: true,
scope: 'form-builder',
tolerance: 'pointer',
drop: Drupal.formBuilder.dropElement,
over: Drupal.formBuilder.dropHover,
out: Drupal.formBuilder.dropHover
});
};
/**
* Handles form elements being dropped onto the form.
*
* Existing elements will trigger a reorder, while new elements will be added in
* place to the form.
*/
Drupal.formBuilder.dropElement = function (event, ui) {
var $element = ui.draggable;
var $placeholder = $(this);
// If the element is a new field from the palette, update it with a real field.
if ($element.is('.form-builder-palette-element')) {
var name = 'new_' + new Date().getTime();
// If this is a "unique" element, its element ID is hard-coded.
if ($element.is('.form-builder-unique')) {
name = $element.get(0).className.replace(/^.*?form-builder-element-([a-z0-9_]+).*?$/, '$1');
}
var $ajaxPlaceholder = $('
' + Drupal.t('Please wait...') + '
');
$.ajax({
url: $element.find('a').attr('href'),
type: 'GET',
dataType: 'json',
data: 'js=1&element_id=' + name,
success: Drupal.formBuilder.addElement
});
$placeholder.replaceWith($ajaxPlaceholder);
Drupal.formBuilder.updatingElement = true;
}
// Update the positions (weights and parents) in the form cache.
else {
$element.removeAttr('style');
$placeholder.replaceWith($element);
ui.helper.remove();
Drupal.formBuilder.updateElementPosition($element.get(0));
}
Drupal.formBuilder.activeDragUi = false;
// Scroll the palette into view.
$(window).triggerHandler('scroll');
};
/**
* Adjusts the placeholder height for drop targets as they are hovered-over.
*/
Drupal.formBuilder.dropHover = function (event, ui) {
if (event.type == 'dropover') {
// In the event that two droppables overlap, the latest one acts as the drop
// target. If there is previous active droppable hide it temporarily.
if (Drupal.formBuilder.activeDropzone) {
$(Drupal.formBuilder.activeDropzone).css('display', 'none');
Drupal.formBuilder.previousDropzones.push(Drupal.formBuilder.activeDropzone);
}
$(this).css({ height: ui.helper.height() + 'px', display: ''}).addClass('form-builder-placeholder-hover');
Drupal.formBuilder.activeDropzone = this;
}
else {
$(this).css({ height: '', display: '' }).removeClass('form-builder-placeholder-hover');
// If this was active drop target, we remove the active state.
if (Drupal.formBuilder.activeDropzone && Drupal.formBuilder.activeDropzone == this) {
Drupal.formBuilder.activeDropzone = false;
}
// If there is a previous drop target that was hidden, restore it.
if (Drupal.formBuilder.previousDropzones.length) {
$(Drupal.formBuilder.previousDropzones).css('display', '');
Drupal.formBuilder.activeDropzone = Drupal.formBuilder.previousDropzones.pop;
}
}
};
/**
* Called when a field has stopped moving via draggable.
*
* @param e
* The event object containing status information about the event.
* @param ui
* The jQuery Sortables object containing information about the sortable.
*/
Drupal.formBuilder.stopDrag = function(e, ui) {
var $this = $(this);
// If the activeDragUi is still set, we did not drop onto the form.
if (Drupal.formBuilder.activeDragUi) {
if ($this.hasClass('form-builder-unique') || $this.hasClass('form-builder-wrapper')) {
$this.show();
}
}
// Remove the placeholders and reset the hover state for all for elements
$('#form-builder .form-builder-placeholder').remove();
$('#form-builder .form-builder-hover').removeClass('form-builder-hover');
Drupal.formBuilder.checkFieldsets();
// Scroll the palette into view.
$(window).triggerHandler('scroll');
};
/**
* Insert DIVs into empty fieldsets so that items can be dropped within them.
*
* This function is called every time an element changes positions during
* a drag and drop operation. Fieldsets are considered empty if they have no
* immediate children or they only contain exclusions.
*
* @param exclusions
* An array of DOM objects within a fieldset that should not be included when
* checking if the fieldset is empty.
*/
Drupal.formBuilder.checkFieldsets = function(exclusions, animate) {
var $wrappers = $('#form-builder div.form-builder-element > fieldset.form-builder-fieldset > div.fieldset-wrapper');
// Make sure exclusions is an array and always skip any description.
exclusions = exclusions ? exclusions : [];
exclusions.push('.description, legend');
// Insert a placeholder into all empty fieldset wrappers.
$wrappers.each(function() {
var children = $(this).children(':visible, :not(.ui-draggable-dragging)');
for (var i in exclusions) {
children = children.not(exclusions[i]);
}
if (children.length == 0) {
// No children, add a placeholder.
if (animate) {
$(Drupal.settings.formBuilder.emptyFieldset).css('display', 'none').appendTo(this).slideDown();
}
else {
$(Drupal.settings.formBuilder.emptyFieldset).appendTo(this);
}
}
else if (children.length > 1 && children.hasClass('form-builder-empty-placeholder')) {
// The fieldset has at least one element besides the placeholder, remove
// the placeholder.
$(this).find('.form-builder-empty-placeholder').remove();
}
});
};
/**
* Check the root form tag and place explanatory text if the form is empty.
*/
Drupal.formBuilder.checkForm = function () {
var $formBuilder = $('#form-builder');
if ($formBuilder.children('div.form-builder-wrapper').length == 0) {
$formBuilder.append(Drupal.settings.formBuilder.emptyForm);
}
};
Drupal.formBuilder.setActive = function(element, link) {
Drupal.formBuilder.unsetActive();
Drupal.formBuilder.activeElement = element;
Drupal.formBuilder.activeLink = link;
$(Drupal.formBuilder.activeElement).addClass('form-builder-active');
};
Drupal.formBuilder.unsetActive = function() {
if (Drupal.formBuilder.activeElement) {
$(Drupal.formBuilder.activeElement).removeClass('form-builder-active');
Drupal.formBuilder.activeElement = false;
Drupal.formBuilder.activeLink = false;
}
};
Drupal.formBuilder.closeActive = function(callback) {
if (Drupal.formBuilder.activeElement) {
var $activeForm = Drupal.formBuilder.fieldConfigureForm ? $(Drupal.formBuilder.fieldConfigureForm).find('form') : $(Drupal.formBuilder.activeElement).find('form');
if ($activeForm.length) {
Drupal.freezeHeight();
$activeForm.slideUp(function(){
$(this).remove();
// Set a message in the custom configure form location if it exists.
if (Drupal.formBuilder.fieldConfigureForm) {
$(Drupal.formBuilder.fieldConfigureForm).html(Drupal.settings.formBuilder.noFieldSelected);
}
if (callback) {
callback.call();
}
});
}
}
else if (callback && $.isFunction(callback)) {
callback.call();
}
return false;
};
/**
* Work around for tabledrags within tabs. On load, if the tab was hidden the
* offsets cannot be calculated correctly. Recalculate and update the tableDrag.
*/
Drupal.formBuilder.fixTableDragTabs = function(context) {
if (Drupal.tableDrag && Drupal.tableDrag.length > 1) {
for (var n in Drupal.tableDrag) {
if (typeof(Drupal.tableDrag[n]) == 'object') {
var table = $('#' + n, context).get(0);
if (table) {
var indent = Drupal.theme('tableDragIndentation');
var testCell = $('tr.draggable:first td:first', table).prepend(indent).prepend(indent);
Drupal.tableDrag[n].indentAmount = $('.indentation', testCell).get(1).offsetLeft - $('.indentation', testCell).get(0).offsetLeft;
$('.indentation', testCell).slice(0, 2).remove();
}
}
}
}
};
})(jQuery);