123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702 |
- (function($) {
- Drupal.behaviors.HierarchicalSelect = {
- attach: function (context) {
- $('.hierarchical-select-wrapper:not(.hierarchical-select-wrapper-processed)', context)
- .addClass('hierarchical-select-wrapper-processed').each(function() {
- var hsid = $(this).attr('id').replace(/^hierarchical-select-(.+)-wrapper$/, "$1");
- Drupal.HierarchicalSelect.initialize(hsid);
- });
- }
- };
- Drupal.HierarchicalSelect = {};
- Drupal.HierarchicalSelect.state = [];
- Drupal.HierarchicalSelect.context = function() {
- return $("form .hierarchical-select-wrapper");
- };
- Drupal.HierarchicalSelect.initialize = function(hsid) {
- // Prevent JS errors when Hierarchical Select is loaded dynamically.
- if (undefined == Drupal.settings.HierarchicalSelect || undefined == Drupal.settings.HierarchicalSelect.settings["hs-" + hsid]) {
- return false;
- }
- // If you set Drupal.settings.HierarchicalSelect.pretendNoJS to *anything*,
- // and as such, Hierarchical Select won't initialize its Javascript! It
- // will seem as if your browser had Javascript disabled.
- if (undefined != Drupal.settings.HierarchicalSelect.pretendNoJS) {
- return false;
- }
- var form = $('#hierarchical-select-'+ hsid +'-wrapper').parents('form');
- // Pressing the 'enter' key on a form that contains an HS widget, depending
- // on which browser, usually causes the first submit button to be pressed
- // (likely an HS button). This results in unpredictable behaviour. There is
- // no way to determine the 'real' submit button, so disable the enter key.
- form.find('input').keypress(function(event) {
- if (event.keyCode == 13) {
- event.preventDefault();
- return false;
- }
- });
- // Turn off Firefox' autocomplete feature. This causes Hierarchical Select
- // form items to be disabled after a hard refresh.
- // See http://drupal.org/node/453048 and
- // http://www.ryancramer.com/journal/entries/radio_buttons_firefox/
- if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
- form.attr('autocomplete', 'off');
- }
- // Enable *all* submit buttons in this form, as well as all input-related
- // elements of the current hierarchical select, in case we reloaded while
- // they were disabled.
- form.add('#hierarchical-select-' + hsid +'-wrapper .hierarchical-select .selects select')
- .add('#hierarchical-select-' + hsid +'-wrapper .hierarchical-select input')
- .attr('disabled', false);
- if (this.cache != null) {
- this.cache.initialize();
- }
- Drupal.settings.HierarchicalSelect.settings["hs-" + hsid]['updatesEnabled'] = true;
- if (undefined == Drupal.HierarchicalSelect.state["hs-" + hsid]) {
- Drupal.HierarchicalSelect.state["hs-" + hsid] = {};
- }
- this.transform(hsid);
- if (Drupal.settings.HierarchicalSelect.settings["hs-" + hsid].resizable) {
- this.resizable(hsid);
- }
- Drupal.HierarchicalSelect.attachBindings(hsid);
- if (this.cache != null && this.cache.status()) {
- this.cache.load(hsid);
- }
- Drupal.HierarchicalSelect.log(hsid);
- };
- Drupal.HierarchicalSelect.log = function(hsid, messages) {
- // Only perform logging if logging is enabled.
- if (Drupal.settings.HierarchicalSelect.initialLog == undefined || Drupal.settings.HierarchicalSelect.initialLog["hs-" + hsid] == undefined) {
- return;
- }
- else {
- Drupal.HierarchicalSelect.state["hs-" + hsid].log = [];
- }
- // Store the log messages. The first call to this function may not contain a
- // message: the initial log included in the initial HTML rendering should be
- // used instead..
- if (Drupal.HierarchicalSelect.state["hs-" + hsid].log.length == 0) {
- Drupal.HierarchicalSelect.state["hs-" + hsid].log.push(Drupal.settings.HierarchicalSelect.initialLog["hs-" + hsid]);
- }
- else {
- Drupal.HierarchicalSelect.state["hs-" + hsid].log.push(messages);
- }
- // Print the log messages.
- console.log("HIERARCHICAL SELECT " + hsid);
- var logIndex = Drupal.HierarchicalSelect.state["hs-" + hsid].log.length - 1;
- for (var i = 0; i < Drupal.HierarchicalSelect.state["hs-" + hsid].log[logIndex].length; i++) {
- console.log(Drupal.HierarchicalSelect.state["hs-" + hsid].log[logIndex][i]);
- }
- console.log(' ');
- };
- Drupal.HierarchicalSelect.transform = function(hsid) {
- var removeString = $('#hierarchical-select-'+ hsid +'-wrapper .dropbox .dropbox-remove:first', Drupal.HierarchicalSelect.context).text();
- $('#hierarchical-select-'+ hsid +'-wrapper', Drupal.HierarchicalSelect.context)
- // Remove the .nojs div.
- .find('.nojs').hide().end()
- // Find all .dropbox-remove cells in the dropbox table.
- .find('.dropbox .dropbox-remove')
- // Hide the children of these table cells. We're not removing them because
- // we want to continue to use the "Remove" checkboxes.
- .find('*').css('display', 'none').end() // We can't use .hide() because of collapse.js: http://drupal.org/node/351458#comment-1258303.
- // Put a "Remove" link there instead.
- .append('<a href="">'+ removeString +'</a>');
- };
- Drupal.HierarchicalSelect.resizable = function(hsid) {
- var $selectsWrapper = $('#hierarchical-select-' + hsid + '-wrapper .hierarchical-select .selects', Drupal.HierarchicalSelect.context);
- // No select wrapper present: the user is creating a new item.
- if ($selectsWrapper.length == 0) {
- return;
- }
- // Append the drag handle ("grippie").
- $selectsWrapper.append($('<div class="grippie"></div>'));
- // jQuery object that contains all selects in the hierarchical select, to
- // speed up DOM manipulation during dragging.
- var $selects = $selectsWrapper.find('select');
- var defaultPadding = parseInt($selects.slice(0, 1).css('padding-top').replace(/^(\d+)px$/, "$1")) + parseInt($selects.slice(0, 1).css('padding-bottom').replace(/^(\d+)px$/, "$1"));
- var defaultHeight = Drupal.HierarchicalSelect.state["hs-" + hsid].defaultHeight = $selects.slice(0, 1).height() + defaultPadding;
- var defaultSize = Drupal.HierarchicalSelect.state["hs-" + hsid].defaultSize = $selects.slice(0, 1).attr('size');
- defaultSize = (defaultSize == 0) ? 1 : defaultSize;
- var margin = Drupal.HierarchicalSelect.state["hs-" + hsid].margin = parseInt($selects.slice(0, 1).css('margin-bottom').replace(/^(\d+)px$/, "$1"));
- // Bind the drag event.
- $('.grippie', $selectsWrapper)
- .mousedown(startDrag)
- .dblclick(function() {
- if (Drupal.HierarchicalSelect.state["hs-" + hsid].resizedHeight == undefined) {
- Drupal.HierarchicalSelect.state["hs-" + hsid].resizedHeight = defaultHeight;
- }
- var resizedHeight = Drupal.HierarchicalSelect.state["hs-" + hsid].resizedHeight = (Drupal.HierarchicalSelect.state["hs-" + hsid].resizedHeight > defaultHeight + 2) ? defaultHeight : 4.6 / defaultSize * defaultHeight;
- Drupal.HierarchicalSelect.resize($selects, defaultHeight, resizedHeight, defaultSize, margin);
- });
- function startDrag(e) {
- staticOffset = $selects.slice(0, 1).height() - e.pageY;
- $selects.css('opacity', 0.25);
- $(document).mousemove(performDrag).mouseup(endDrag);
- return false;
- }
- function performDrag(e) {
- var resizedHeight = staticOffset + e.pageY;
- Drupal.HierarchicalSelect.resize($selects, defaultHeight, resizedHeight, defaultSize, margin);
- return false;
- }
- function endDrag(e) {
- var height = $selects.slice(0, 1).height();
- $(document).unbind("mousemove", performDrag).unbind("mouseup", endDrag);
- $selects.css('opacity', 1);
- if (height != Drupal.HierarchicalSelect.state["hs-" + hsid].resizedHeight) {
- Drupal.HierarchicalSelect.state["hs-" + hsid].resizedHeight = (height > defaultHeight) ? height : defaultHeight;
- }
- }
- };
- Drupal.HierarchicalSelect.resize = function($selects, defaultHeight, resizedHeight, defaultSize, margin) {
- if (resizedHeight == undefined) {
- resizedHeight = defaultHeight;
- }
- $selects
- .attr('size', (resizedHeight > defaultHeight) ? 2 : defaultSize)
- .height(Math.max(defaultHeight + margin, resizedHeight)); // Without the margin component, the height() method would allow the select to be sized to low: defaultHeight - margin.
- };
- Drupal.HierarchicalSelect.disableForm = function(hsid) {
- // Disable *all* submit buttons in this form, as well as all input-related
- // elements of the current hierarchical select.
- $('form:has(#hierarchical-select-' + hsid +'-wrapper) :submit')
- .add('#hierarchical-select-' + hsid +'-wrapper .hierarchical-select .selects select')
- .add('#hierarchical-select-' + hsid +'-wrapper .hierarchical-select :input')
- .attr('disabled', true);
- // Add the 'waiting' class. Default style: make everything transparent.
- $('#hierarchical-select-' + hsid +'-wrapper').addClass('waiting');
- // Indicate that the user has to wait.
- $('body').css('cursor', 'wait');
- };
- Drupal.HierarchicalSelect.enableForm = function(hsid) {
- // This method undoes everything the disableForm() method did.
- $e = $('form:has(#hierarchical-select-' + hsid +'-wrapper) :submit')
- .add('#hierarchical-select-' + hsid +'-wrapper .hierarchical-select :input:not(:submit)');
- // Don't enable the selects again if they've been disabled because the
- // dropbox limit was exceeded.
- dropboxLimitExceeded = $('#hierarchical-select-' + hsid +'-wrapper .hierarchical-select-dropbox-limit-warning').length > 0;
- if (!dropboxLimitExceeded) {
- $e = $e.add($('#hierarchical-select-' + hsid +'-wrapper .hierarchical-select .selects select'));
- }
- $e.removeAttr("disabled");
- // Don't enable the 'Add' button again if it's been disabled because the
- // dropbox limit was exceeded.
- if (dropboxLimitExceeded) {
- $('#hierarchical-select-' + hsid +'-wrapper .hierarchical-select :submit')
- .attr('disabled', true);
- }
- $('#hierarchical-select-' + hsid +'-wrapper').removeClass('waiting');
- $('body').css('cursor', 'auto');
- };
- Drupal.HierarchicalSelect.throwError = function(hsid, message) {
- // Show the error to the user.
- alert(message);
- // Log the error.
- Drupal.HierarchicalSelect.log(hsid, [ message ]);
- // Re-enable the form to allow the user to retry, but reset the selection to
- // the level label if possible, otherwise the "<none>" option if possible.
- var $select = $('#hierarchical-select-' + hsid +'-wrapper .hierarchical-select .selects select:first');
- var levelLabelOption = $('option[value^=label_]', $select).val();
- if (levelLabelOption !== undefined) {
- $select.val(levelLabelOption);
- }
- else {
- var noneOption = $('option[value=none]', $select).val();
- if (noneOption !== undefined) {
- $select.val(noneOption);
- }
- }
- Drupal.HierarchicalSelect.enableForm(hsid);
- };
- Drupal.HierarchicalSelect.prepareGETSubmit = function(hsid) {
- // Remove the name attributes of all form elements that end up in GET,
- // except for the "flat select" form element.
- $('#hierarchical-select-'+ hsid +'-wrapper', Drupal.HierarchicalSelect.context)
- .find('input, select')
- .not('.flat-select')
- .removeAttr('name');
- // Update the name attribute of the "flat select" form element
- var $flatSelect = $('#hierarchical-select-'+ hsid +'-wrapper .flat-select', Drupal.HierarchicalSelect.context);
- var newName = $flatSelect.attr('name').replace(/^([a-zA-Z0-9_\-]*)(?:\[flat_select\]){1}(\[\])?$/, "$1$2");
- $flatSelect.attr('name', newName);
- Drupal.HierarchicalSelect.triggerEvents(hsid, 'prepared-GET-submit', {});
- };
- Drupal.HierarchicalSelect.attachBindings = function(hsid) {
- var updateOpString = $('#hierarchical-select-'+ hsid +'-wrapper .update-button').val();
- var addOpString = $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .add-to-dropbox', Drupal.HierarchicalSelect.context).val();
- var createNewItemOpString = $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .create-new-item-create', Drupal.HierarchicalSelect.context).val();
- var cancelNewItemOpString = $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .create-new-item-cancel', Drupal.HierarchicalSelect.context).val();
- var data = {};
- data.hsid = hsid;
- $('#hierarchical-select-'+ hsid +'-wrapper', this.context)
- // "disable-updates" event
- .unbind('disable-updates').bind('disable-updates', data, function(e) {
- Drupal.settings.HierarchicalSelect.settings["hs-" + e.data.hsid]['updatesEnabled'] = false;
- })
- // "enforce-update" event
- .unbind('enforce-update').bind('enforce-update', data, function(e, extraPost) {
- Drupal.HierarchicalSelect.update(e.data.hsid, 'enforced-update', { opString: updateOpString, extraPost: extraPost });
- })
- // "prepare-GET-submit" event
- .unbind('prepare-GET-submit').bind('prepare-GET-submit', data, function(e) {
- Drupal.HierarchicalSelect.prepareGETSubmit(e.data.hsid);
- })
- // "update-hierarchical-select" event
- .find('.hierarchical-select .selects select').unbind().change(function(_hsid) {
- return function() {
- if (Drupal.settings.HierarchicalSelect.settings["hs-" + _hsid]['updatesEnabled']) {
- Drupal.HierarchicalSelect.update(_hsid, 'update-hierarchical-select', { opString: updateOpString, select_id : $(this).attr('id') });
- }
- };
- }(hsid)).end()
- // "create-new-item" event
- .find('.hierarchical-select .create-new-item .create-new-item-create').unbind().click(function(_hsid) {
- return function() {
- Drupal.HierarchicalSelect.update(_hsid, 'create-new-item', { opString : createNewItemOpString });
- return false; // Prevent the browser from POSTing the page.
- };
- }(hsid)).end()
- // "cancel-new-item" event"
- .find('.hierarchical-select .create-new-item .create-new-item-cancel').unbind().click(function(_hsid) {
- return function() {
- Drupal.HierarchicalSelect.update(_hsid, 'cancel-new-item', { opString : cancelNewItemOpString });
- return false; // Prevent the browser from POSTing the page (in case of the "Cancel" button).
- };
- }(hsid)).end()
- // "add-to-dropbox" event
- .find('.hierarchical-select .add-to-dropbox').unbind().click(function(_hsid) {
- return function() {
- Drupal.HierarchicalSelect.update(_hsid, 'add-to-dropbox', { opString : addOpString });
- return false; // Prevent the browser from POSTing the page.
- };
- }(hsid)).end()
- // "remove-from-dropbox" event
- // (anchors in the .dropbox-remove cells in the .dropbox table)
- .find('.dropbox .dropbox-remove a').unbind().click(function(_hsid) {
- return function() {
- var isDisabled = $('#hierarchical-select-'+ hsid +'-wrapper', Drupal.HierarchicalSelect.context).attr('disabled');
- // If the hierarchical select is disabled, then ignore this click.
- if (isDisabled) {
- return false;
- }
- // Check the (hidden, because JS is enabled) checkbox that marks this
- // dropbox entry for removal.
- $(this).parent().find('input[type=checkbox]').attr('checked', true);
- Drupal.HierarchicalSelect.update(_hsid, 'remove-from-dropbox', { opString: updateOpString });
- return false; // Prevent the browser from POSTing the page.
- };
- }(hsid));
- };
- Drupal.HierarchicalSelect.preUpdateAnimations = function(hsid, updateType, lastUnchanged, callback) {
- switch (updateType) {
- case 'update-hierarchical-select':
- // Drop out the selects of the levels deeper than the select of the
- // level that just changed.
- var animationDelay = Drupal.settings.HierarchicalSelect.settings["hs-" + hsid]['animationDelay'];
- var $animatedSelects = $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .selects select', Drupal.HierarchicalSelect.context).slice(lastUnchanged);
- if ($animatedSelects.size() > 0) {
- $animatedSelects.hide();
- for (var i = 0; i < $animatedSelects.size(); i++) {
- if (i < $animatedSelects.size() - 1) {
- $animatedSelects.slice(i, i + 1).hide("drop", { direction: "left" }, animationDelay);
- }
- else {
- $animatedSelects.slice(i, i + 1).hide("drop", { direction: "left" }, animationDelay, callback);
- }
- }
- }
- else if (callback) {
- callback();
- }
- break;
- default:
- if (callback) {
- callback();
- }
- break;
- }
- };
- Drupal.HierarchicalSelect.postUpdateAnimations = function(hsid, updateType, lastUnchanged, callback) {
- if (Drupal.settings.HierarchicalSelect.settings["hs-" + hsid].resizable) {
- // Restore the resize.
- Drupal.HierarchicalSelect.resize(
- $('#hierarchical-select-' + hsid + '-wrapper .hierarchical-select .selects select', Drupal.HierarchicalSelect.context),
- Drupal.HierarchicalSelect.state["hs-" + hsid].defaultHeight,
- Drupal.HierarchicalSelect.state["hs-" + hsid].resizedHeight,
- Drupal.HierarchicalSelect.state["hs-" + hsid].defaultSize,
- Drupal.HierarchicalSelect.state["hs-" + hsid].margin
- );
- }
- switch (updateType) {
- case 'update-hierarchical-select':
- var $createNewItemInput = $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .create-new-item-input', Drupal.HierarchicalSelect.context);
- // Hide the loaded selects after the one that was just changed, then
- // drop them in.
- var animationDelay = Drupal.settings.HierarchicalSelect.settings["hs-" + hsid]['animationDelay'];
- var $animatedSelects = $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .selects select', Drupal.HierarchicalSelect.context).slice(lastUnchanged);
- if ($animatedSelects.size() > 0) {
- $animatedSelects.hide();
- for (var i = 0; i < $animatedSelects.size(); i++) {
- if (i < $animatedSelects.size() - 1) {
- $animatedSelects.slice(i, i + 1).show("drop", { direction: "left" }, animationDelay);
- }
- else {
- $animatedSelects.slice(i, i + 1).show("drop", { direction: "left" }, animationDelay, callback);
- }
- }
- }
- else if (callback) {
- callback();
- }
- if ($createNewItemInput.size() == 0) {
- // Give focus to the level below the one that has changed, if it
- // exists.
- setTimeout(
- function() {
- $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .selects select', Drupal.HierarchicalSelect.context)
- .slice(lastUnchanged, lastUnchanged + 1)
- .focus();
- },
- animationDelay + 100
- );
- }
- else {
- // Give focus to the input field of the "create new item/level"
- // section, if it exists, and also select the existing text.
- $createNewItemInput.focus();
- $createNewItemInput[0].select();
- }
- break;
- case 'create-new-item':
- // Make sure that other Hierarchical Selects that represent the same
- // hierarchy are also updated, to make sure that they have the newly
- // created item!
- var cacheId = Drupal.settings.HierarchicalSelect.settings["hs-" + hsid].cacheId;
- for (var otherHsid in Drupal.settings.HierarchicalSelect.settings) {
- if (Drupal.settings.HierarchicalSelect.settings[otherHsid].cacheId == cacheId) {
- $('#hierarchical-select-'+ otherHsid +'-wrapper')
- .trigger('enforce-update');
- }
- }
- // TRICKY: NO BREAK HERE!
- case 'cancel-new-item':
- // After an item/level has been created/cancelled, reset focus to the
- // beginning of the hierarchical select.
- $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .selects select', Drupal.HierarchicalSelect.context)
- .slice(0, 1)
- .focus();
- if (callback) {
- callback();
- }
- break;
- default:
- if (callback) {
- callback();
- }
- break;
- }
- };
- Drupal.HierarchicalSelect.triggerEvents = function(hsid, updateType, settings) {
- $('#hierarchical-select-'+ hsid +'-wrapper', Drupal.HierarchicalSelect.context)
- .trigger(updateType, [ hsid, settings ]);
- };
- Drupal.HierarchicalSelect.update = function(hsid, updateType, settings) {
- var post = $('form:has(#hierarchical-select-' + hsid +'-wrapper)', Drupal.HierarchicalSelect.context).formToArray();
- var hs_current_language = Drupal.settings.HierarchicalSelect.hs_current_language;
- // Pass the hierarchical_select id via POST.
- post.push({ name : 'hsid', value : hsid });
- // Send the current language so we can use the same language during the AJAX callback.
- post.push({ name : 'hs_current_language', value : hs_current_language});
- // Emulate the AJAX data sent normally so that we get the same theme.
- post.push({ name : 'ajax_page_state[theme]', value : Drupal.settings.ajaxPageState.theme });
- post.push({ name : 'ajax_page_state[theme_token]', value : Drupal.settings.ajaxPageState.theme_token });
- // If a cache system is installed, let the server know if it's running
- // properly. If it is running properly, the server will send back additional
- // information to maintain a lazily-loaded cache.
- if (Drupal.HierarchicalSelect.cache != null) {
- post.push({ name : 'client_supports_caching', value : Drupal.HierarchicalSelect.cache.status() });
- }
- // updateType is one of:
- // - 'none' (default)
- // - 'update-hierarchical-select'
- // - 'enforced-update'
- // - 'create-new-item'
- // - 'cancel-new-item'
- // - 'add-to-dropbox'
- // - 'remove-from-dropbox'
- switch (updateType) {
- case 'update-hierarchical-select':
- var value = $('#'+ settings.select_id).val();
- var lastUnchanged = parseInt(settings.select_id.replace(/^.*-hierarchical-select-selects-(\d+)/, "$1")) + 1;
- var optionClass = $('#'+ settings.select_id).find('option[value="'+ value +'"]').attr('class');
- // Don't do anything (also no callback to the server!) when the selected
- // item is:
- // - the '<none>' option and the renderFlatSelect setting is disabled, or
- // - a level label, or
- // - an option of class 'has-no-children', and
- // (the renderFlatSelect setting is disabled or the dropbox is enabled)
- // and
- // (the createNewLevels setting is disabled).
- if ((value == 'none' && Drupal.settings.HierarchicalSelect.settings["hs-" + hsid]['renderFlatSelect'] == false)
- || value.match(/^label_\d+$/)
- || (optionClass == 'has-no-children'
- &&
- (
- (Drupal.settings.HierarchicalSelect.settings["hs-" + hsid]['renderFlatSelect'] == false
- || $('#hierarchical-select-'+ hsid +'-wrapper .dropbox').length > 0
- )
- &&
- Drupal.settings.HierarchicalSelect.settings["hs-" + hsid]['createNewLevels'] == false
- )
- )
- )
- {
- Drupal.HierarchicalSelect.preUpdateAnimations(hsid, updateType, lastUnchanged, function() {
- // Remove the sublevels.
- $('#hierarchical-select-'+ hsid +'-wrapper .hierarchical-select .selects select', Drupal.HierarchicalSelect.context)
- .slice(lastUnchanged)
- .remove();
- // The selection of this hierarchical select has changed!
- Drupal.HierarchicalSelect.triggerEvents(hsid, 'change-hierarchical-select', settings);
- });
- return;
- }
- post.push({ name : 'op', value : settings.opString });
- break;
- case 'enforced-update':
- post.push({ name : 'op', value : settings.opString });
- post = post.concat(settings.extraPost);
- break;
- case 'create-new-item':
- case 'cancel-new-item':
- case 'add-to-dropbox':
- case 'remove-from-dropbox':
- post.push({ name : 'op', value : settings.opString });
- break;
- default:
- break;
- }
- // Construct the URL the request should be made to.
- var url = Drupal.settings.HierarchicalSelect.settings["hs-" + hsid].ajax_url;
- // Construct the object that contains the options for a callback to the
- // server. If a client-side cache is found however, it's possible that this
- // won't be used.
- var ajaxOptions = $.extend({}, Drupal.ajax.prototype, {
- url: url,
- type: 'POST',
- dataType: 'json',
- data: post,
- effect: 'fade',
- wrapper: '#hierarchical-select-' + hsid + '-wrapper',
- beforeSend: function() {
- Drupal.HierarchicalSelect.triggerEvents(hsid, 'before-' + updateType, settings);
- Drupal.HierarchicalSelect.disableForm(hsid);
- },
- error: function (XMLHttpRequest, textStatus, errorThrown) {
- // When invalid HTML is received in Safari, jQuery calls this function.
- Drupal.HierarchicalSelect.throwError(hsid, Drupal.t('Received an invalid response from the server.'));
- },
- success: function(response, status) {
- // An invalid response may be returned by the server, in case of a PHP
- // error. Detect this and let the user know.
- if (response === null || response.length == 0) {
- Drupal.HierarchicalSelect.throwError(hsid, Drupal.t('Received an invalid response from the server.'));
- return;
- }
- // Execute all AJAX commands in the response. But pass an additional
- // hsid parameter, which is then only used by the commands written
- // for Hierarchical Select.
- // This is another hack because of the non-Drupal ajax implementation
- // of this module, one of the response that can come from a drupal
- // ajax command is insert, which expects a Drupal.ajax object as the first
- // arguments and assumes that certain functions/settings are available.
- // Because we are calling a Drupal.ajax.command but providing the regular
- // jQuery ajax object itself, we are allowing Drupal.ajax.prototype.commands
- // to misserably fail.
- //
- // This hack attempts to fix one issue with an insert command,
- // @see https://www.drupal.org/node/2393695, allowing it to work properly
- // Other hacks might be necessary for other ajax commands if they are added
- // by external modules.
- this.effect = 'none';
- this.getEffect = Drupal.ajax.prototype.getEffect;
- for (var i in response) {
- if (response[i]['command'] && Drupal.ajax.prototype.commands[response[i]['command']]) {
- Drupal.ajax.prototype.commands[response[i]['command']](this, response[i], status, hsid);
- }
- }
- // Attach behaviors. This is just after the HTML has been updated, so
- // it's as soon as we can.
- Drupal.attachBehaviors($('#hierarchical-select-' + hsid + '-wrapper').parents('div.form-type-hierarchical-select')[0]);
- // Transform the hierarchical select and/or dropbox to the JS variant,
- // make it resizable again and re-enable the disabled form items.
- Drupal.HierarchicalSelect.enableForm(hsid);
- Drupal.HierarchicalSelect.postUpdateAnimations(hsid, updateType, lastUnchanged, function() {
- // Update the client-side cache when:
- // - information for in the cache is provided in the response, and
- // - the cache system is available, and
- // - the cache system is running.
- if (response.cache != null && Drupal.HierarchicalSelect.cache != null && Drupal.HierarchicalSelect.cache.status()) {
- Drupal.HierarchicalSelect.cache.sync(hsid, response.cache);
- }
- if (response.log != undefined) {
- Drupal.HierarchicalSelect.log(hsid, response.log);
- }
- Drupal.HierarchicalSelect.triggerEvents(hsid, updateType, settings);
- if (updateType == 'update-hierarchical-select') {
- // The selection of this hierarchical select has changed!
- Drupal.HierarchicalSelect.triggerEvents(hsid, 'change-hierarchical-select', settings);
- }
- });
- }
- });
- // Use the client-side cache to update the hierarchical select when:
- // - the hierarchical select is being updated (i.e. no add/remove), and
- // - the renderFlatSelect setting is disabled, and
- // - the createNewItems setting is disabled, and
- // - the cache system is available, and
- // - the cache system is running.
- // Otherwise, perform a normal dynamic form submit.
- if (updateType == 'update-hierarchical-select'
- && Drupal.settings.HierarchicalSelect.settings["hs-" + hsid]['renderFlatSelect'] == false
- && Drupal.settings.HierarchicalSelect.settings["hs-" + hsid]['createNewItems'] == false
- && Drupal.HierarchicalSelect.cache != null
- && Drupal.HierarchicalSelect.cache.status())
- {
- Drupal.HierarchicalSelect.cache.updateHierarchicalSelect(hsid, value, settings, lastUnchanged, ajaxOptions);
- }
- else {
- Drupal.HierarchicalSelect.preUpdateAnimations(hsid, updateType, lastUnchanged, function() {
- // Adding current theme to prevent conflicts, @see ajax.js
- // @TODO, try converting to use Drupal.ajax instead.
- // Prevent duplicate HTML ids in the returned markup.
- // @see drupal_html_id()
- var ids = [];
- $('[id]').each(function () {
- ids.push(this.id);
- });
- ajaxOptions.data.push({ name : 'ajax_html_ids[]', value : ids });
- ajaxOptions.data.push({ name : 'ajax_page_state[theme]', value : Drupal.settings.ajaxPageState.theme });
- ajaxOptions.data.push({ name : 'ajax_page_state[theme_token]', value : Drupal.settings.ajaxPageState.theme_token });
- for (var key in Drupal.settings.ajaxPageState.css) {
- ajaxOptions.data.push({ name : 'ajax_page_state[css][' + key + ']', value : 1});
- }
- for (var key in Drupal.settings.ajaxPageState.js) {
- ajaxOptions.data.push({ name : 'ajax_page_state[js][' + key + ']', value : 1});
- }
- // Make it work with jquery update
- if (Drupal.settings.ajaxPageState.jquery_version) {
- ajaxOptions.data.push({ name : 'ajax_page_state[jquery_version]', value : Drupal.settings.ajaxPageState.jquery_version });
- }
- $.ajax(ajaxOptions);
- });
- }
- };
- Drupal.ajax.prototype.commands.hierarchicalSelectUpdate = function(ajax, response, status, hsid) {
- // Replace the old HTML with the (relevant part of) retrieved HTML.
- $('#hierarchical-select-'+ hsid +'-wrapper', Drupal.HierarchicalSelect.context)
- .parent('.form-item')
- .replaceWith($(response.output));
- };
- Drupal.ajax.prototype.commands.hierarchicalSelectSettingsUpdate = function(ajax, response, status, hsid) {
- Drupal.settings.HierarchicalSelect.settings["hs-" + response.hsid] = response.settings;
- };
- })(jQuery);
|