3 * Provides utility functions for Quick Edit.
6 (function ($, Drupal) {
13 Drupal.quickedit.util = Drupal.quickedit.util || {};
18 Drupal.quickedit.util.constants = {};
24 Drupal.quickedit.util.constants.transitionEnd = 'transitionEnd.quickedit webkitTransitionEnd.quickedit transitionend.quickedit msTransitionEnd.quickedit oTransitionEnd.quickedit';
27 * Converts a field id into a formatted url path.
30 * Drupal.quickedit.util.buildUrl(
31 * 'node/1/body/und/full',
32 * '/quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode'
36 * The id of an editable field.
37 * @param {string} urlFormat
38 * The Controller route for field processing.
43 Drupal.quickedit.util.buildUrl = function (id, urlFormat) {
44 var parts = id.split('/');
45 return Drupal.formatString(decodeURIComponent(urlFormat), {
46 '!entity_type': parts[0],
48 '!field_name': parts[2],
49 '!langcode': parts[3],
50 '!view_mode': parts[4]
55 * Shows a network error modal dialog.
57 * @param {string} title
58 * The title to use in the modal dialog.
59 * @param {string} message
60 * The message to use in the modal dialog.
62 Drupal.quickedit.util.networkErrorModal = function (title, message) {
63 var $message = $('<div>' + message + '</div>');
64 var networkErrorModal = Drupal.dialog($message.get(0), {
66 dialogClass: 'quickedit-network-error',
71 networkErrorModal.close();
77 $(this).parent().find('.ui-dialog-titlebar-close').remove();
79 close: function (event) {
80 // Automatically destroy the DOM element that was used for the dialog.
81 $(event.target).remove();
84 networkErrorModal.showModal();
90 Drupal.quickedit.util.form = {
93 * Loads a form, calls a callback to insert.
95 * Leverages {@link Drupal.Ajax}' ability to have scoped (per-instance)
96 * command implementations to be able to call a callback.
98 * @param {object} options
99 * An object with the following keys:
100 * @param {string} options.fieldID
101 * The field ID that uniquely identifies the field for which this form
103 * @param {bool} options.nocssjs
104 * Boolean indicating whether no CSS and JS should be returned (necessary
105 * when the form is invisible to the user).
106 * @param {bool} options.reset
107 * Boolean indicating whether the data stored for this field's entity in
108 * PrivateTempStore should be used or reset.
109 * @param {function} callback
110 * A callback function that will receive the form to be inserted, as well
111 * as the ajax object, necessary if the callback wants to perform other
114 load: function (options, callback) {
115 var fieldID = options.fieldID;
117 // Create a Drupal.ajax instance to load the form.
118 var formLoaderAjax = Drupal.ajax({
119 url: Drupal.quickedit.util.buildUrl(fieldID, Drupal.url('quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode')),
121 nocssjs: options.nocssjs,
124 error: function (xhr, url) {
125 // Show a modal to inform the user of the network error.
126 var fieldLabel = Drupal.quickedit.metadata.get(fieldID, 'label');
127 var message = Drupal.t('Could not load the form for <q>@field-label</q>, either due to a website problem or a network connection problem.<br>Please try again.', {'@field-label': fieldLabel});
128 Drupal.quickedit.util.networkErrorModal(Drupal.t('Network problem!'), message);
130 // Change the state back to "candidate", to allow the user to start
131 // in-place editing of the field again.
132 var fieldModel = Drupal.quickedit.app.model.get('activeField');
133 fieldModel.set('state', 'candidate');
136 // Implement a scoped quickeditFieldForm AJAX command: calls the callback.
137 formLoaderAjax.commands.quickeditFieldForm = function (ajax, response, status) {
138 callback(response.data, ajax);
139 Drupal.ajax.instances[this.instanceIndex] = null;
141 // This will ensure our scoped quickeditFieldForm AJAX command gets
143 formLoaderAjax.execute();
147 * Creates a {@link Drupal.Ajax} instance that is used to save a form.
149 * @param {object} options
150 * Submit options to the form.
151 * @param {bool} options.nocssjs
152 * Boolean indicating whether no CSS and JS should be returned (necessary
153 * when the form is invisible to the user).
154 * @param {Array.<string>} options.other_view_modes
155 * Array containing view mode IDs (of other instances of this field on the
157 * @param {jQuery} $submit
158 * The submit element.
160 * @return {Drupal.Ajax}
161 * A {@link Drupal.Ajax} instance.
163 ajaxifySaving: function (options, $submit) {
164 // Re-wire the form to handle submit.
166 url: $submit.closest('form').attr('action'),
168 event: 'click.quickedit',
171 nocssjs: options.nocssjs,
172 other_view_modes: options.other_view_modes
176 * Reimplement the success handler.
178 * Ensure {@link Drupal.attachBehaviors} does not get called on the
181 * @param {Drupal.AjaxCommands~commandDefinition} response
182 * The Drupal AJAX response.
183 * @param {number} [status]
184 * The HTTP status code.
186 success: function (response, status) {
187 for (var i in response) {
188 if (response.hasOwnProperty(i) && response[i].command && this.commands[response[i].command]) {
189 this.commands[response[i].command](this, response[i], status);
193 base: $submit.attr('id'),
197 return Drupal.ajax(settings);
201 * Cleans up the {@link Drupal.Ajax} instance that is used to save the form.
203 * @param {Drupal.Ajax} ajax
204 * A {@link Drupal.Ajax} instance that was returned by
205 * {@link Drupal.quickedit.form.ajaxifySaving}.
207 unajaxifySaving: function (ajax) {
208 $(ajax.element).off('click.quickedit');