/** * @file * Provides utility functions for Quick Edit. */ (function ($, Drupal) { "use strict"; Drupal.quickedit.util = Drupal.quickedit.util || {}; Drupal.quickedit.util.constants = {}; Drupal.quickedit.util.constants.transitionEnd = "transitionEnd.quickedit webkitTransitionEnd.quickedit transitionend.quickedit msTransitionEnd.quickedit oTransitionEnd.quickedit"; /** * Converts a field id into a formatted url path. * * @param String id * The id of an editable field. For example, 'node/1/body/und/full'. * @param String urlFormat * The Controller route for field processing. For example, * '/quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode'. */ Drupal.quickedit.util.buildUrl = function (id, urlFormat) { var parts = id.split('/'); return Drupal.formatString(decodeURIComponent(urlFormat), { '!entity_type': parts[0], '!id': parts[1], '!field_name': parts[2], '!langcode': parts[3], '!view_mode': parts[4] }); }; /** * Shows a network error modal dialog. * * @param String title * The title to use in the modal dialog. * @param String message * The message to use in the modal dialog. */ Drupal.quickedit.util.networkErrorModal = function (title, message) { var $message = $('
' + message + '
'); var networkErrorModal = Drupal.dialog($message.get(0), { title: title, dialogClass: 'quickedit-network-error', buttons: [ { text: Drupal.t('OK'), click: function () { networkErrorModal.close(); }, primary: true } ], create: function () { $(this).parent().find('.ui-dialog-titlebar-close').remove(); }, close: function (event) { // Automatically destroy the DOM element that was used for the dialog. $(event.target).remove(); } }); networkErrorModal.showModal(); }; Drupal.quickedit.util.form = { /** * Loads a form, calls a callback to insert. * * Leverages Drupal.ajax' ability to have scoped (per-instance) command * implementations to be able to call a callback. * * @param Object options * An object with the following keys: * - jQuery $el: (required) DOM element necessary for Drupal.ajax to * perform AJAX commands. * - String fieldID: (required) the field ID that uniquely identifies the * field for which this form will be loaded. * - Boolean nocssjs: (required) boolean indicating whether no CSS and JS * should be returned (necessary when the form is invisible to the user). * - Boolean reset: (required) boolean indicating whether the data stored * for this field's entity in TempStore should be used or reset. * @param Function callback * A callback function that will receive the form to be inserted, as well as * the ajax object, necessary if the callback wants to perform other AJAX * commands. */ load: function (options, callback) { var $el = options.$el; var fieldID = options.fieldID; // Create a Drupal.ajax instance to load the form. var formLoaderAjax = new Drupal.ajax(fieldID, $el, { url: Drupal.quickedit.util.buildUrl(fieldID, Drupal.url('quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode')), event: 'quickedit-internal.quickedit', submit: { nocssjs: options.nocssjs, reset: options.reset }, progress: { type: null }, // No progress indicator. error: function (xhr, url) { $el.off('quickedit-internal.quickedit'); // Show a modal to inform the user of the network error. var fieldLabel = Drupal.quickedit.metadata.get(fieldID, 'label'); var message = Drupal.t('Could not load the form for @field-label, either due to a website problem or a network connection problem.
Please try again.', { '@field-label': fieldLabel }); Drupal.quickedit.util.networkErrorModal(Drupal.t('Sorry!'), message); // Change the state back to "candidate", to allow the user to start // in-place editing of the field again. var fieldModel = Drupal.quickedit.app.model.get('activeField'); fieldModel.set('state', 'candidate'); } }); // Implement a scoped quickeditFieldForm AJAX command: calls the callback. formLoaderAjax.commands.quickeditFieldForm = function (ajax, response, status) { callback(response.data, ajax); $el.off('quickedit-internal.quickedit'); formLoaderAjax = null; }; // This will ensure our scoped quickeditFieldForm AJAX command gets called. $el.trigger('quickedit-internal.quickedit'); }, /** * Creates a Drupal.ajax instance that is used to save a form. * * @param Object options * An object with the following keys: * - nocssjs: (required) boolean indicating whether no CSS and JS should be * returned (necessary when the form is invisible to the user). * - other_view_modes: (required) array containing view mode IDs (of other * instances of this field on the page). * @return Drupal.ajax * A Drupal.ajax instance. */ ajaxifySaving: function (options, $submit) { // Re-wire the form to handle submit. var settings = { url: $submit.closest('form').attr('action'), setClick: true, event: 'click.quickedit', progress: { type: null }, submit: { nocssjs: options.nocssjs, other_view_modes: options.other_view_modes }, // Reimplement the success handler to ensure Drupal.attachBehaviors() does // not get called on the form. success: function (response, status) { for (var i in response) { if (response.hasOwnProperty(i) && response[i].command && this.commands[response[i].command]) { this.commands[response[i].command](this, response[i], status); } } } }; return new Drupal.ajax($submit.attr('id'), $submit[0], settings); }, /** * Cleans up the Drupal.ajax instance that is used to save the form. * * @param Drupal.ajax ajax * A Drupal.ajax instance that was returned by * Drupal.quickedit.form.ajaxifySaving(). */ unajaxifySaving: function (ajax) { $(ajax.element).off('click.quickedit'); } }; })(jQuery, Drupal);