annotate core/modules/quickedit/js/util.es6.js @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 /**
Chris@0 2 * @file
Chris@0 3 * Provides utility functions for Quick Edit.
Chris@0 4 */
Chris@0 5
Chris@17 6 (function($, Drupal) {
Chris@0 7 /**
Chris@0 8 * @namespace
Chris@0 9 */
Chris@0 10 Drupal.quickedit.util = Drupal.quickedit.util || {};
Chris@0 11
Chris@0 12 /**
Chris@0 13 * @namespace
Chris@0 14 */
Chris@0 15 Drupal.quickedit.util.constants = {};
Chris@0 16
Chris@0 17 /**
Chris@0 18 *
Chris@0 19 * @type {string}
Chris@0 20 */
Chris@17 21 Drupal.quickedit.util.constants.transitionEnd =
Chris@17 22 'transitionEnd.quickedit webkitTransitionEnd.quickedit transitionend.quickedit msTransitionEnd.quickedit oTransitionEnd.quickedit';
Chris@0 23
Chris@0 24 /**
Chris@0 25 * Converts a field id into a formatted url path.
Chris@0 26 *
Chris@0 27 * @example
Chris@0 28 * Drupal.quickedit.util.buildUrl(
Chris@0 29 * 'node/1/body/und/full',
Chris@0 30 * '/quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode'
Chris@0 31 * );
Chris@0 32 *
Chris@0 33 * @param {string} id
Chris@0 34 * The id of an editable field.
Chris@0 35 * @param {string} urlFormat
Chris@0 36 * The Controller route for field processing.
Chris@0 37 *
Chris@0 38 * @return {string}
Chris@0 39 * The formatted URL.
Chris@0 40 */
Chris@17 41 Drupal.quickedit.util.buildUrl = function(id, urlFormat) {
Chris@0 42 const parts = id.split('/');
Chris@0 43 return Drupal.formatString(decodeURIComponent(urlFormat), {
Chris@0 44 '!entity_type': parts[0],
Chris@0 45 '!id': parts[1],
Chris@0 46 '!field_name': parts[2],
Chris@0 47 '!langcode': parts[3],
Chris@0 48 '!view_mode': parts[4],
Chris@0 49 });
Chris@0 50 };
Chris@0 51
Chris@0 52 /**
Chris@0 53 * Shows a network error modal dialog.
Chris@0 54 *
Chris@0 55 * @param {string} title
Chris@0 56 * The title to use in the modal dialog.
Chris@0 57 * @param {string} message
Chris@0 58 * The message to use in the modal dialog.
Chris@0 59 */
Chris@17 60 Drupal.quickedit.util.networkErrorModal = function(title, message) {
Chris@0 61 const $message = $(`<div>${message}</div>`);
Chris@14 62 const networkErrorModal = Drupal.dialog($message.get(0), {
Chris@0 63 title,
Chris@0 64 dialogClass: 'quickedit-network-error',
Chris@0 65 buttons: [
Chris@0 66 {
Chris@0 67 text: Drupal.t('OK'),
Chris@0 68 click() {
Chris@0 69 networkErrorModal.close();
Chris@0 70 },
Chris@0 71 primary: true,
Chris@0 72 },
Chris@0 73 ],
Chris@0 74 create() {
Chris@17 75 $(this)
Chris@17 76 .parent()
Chris@17 77 .find('.ui-dialog-titlebar-close')
Chris@17 78 .remove();
Chris@0 79 },
Chris@0 80 close(event) {
Chris@0 81 // Automatically destroy the DOM element that was used for the dialog.
Chris@0 82 $(event.target).remove();
Chris@0 83 },
Chris@0 84 });
Chris@0 85 networkErrorModal.showModal();
Chris@0 86 };
Chris@0 87
Chris@0 88 /**
Chris@0 89 * @namespace
Chris@0 90 */
Chris@0 91 Drupal.quickedit.util.form = {
Chris@0 92 /**
Chris@0 93 * Loads a form, calls a callback to insert.
Chris@0 94 *
Chris@0 95 * Leverages {@link Drupal.Ajax}' ability to have scoped (per-instance)
Chris@0 96 * command implementations to be able to call a callback.
Chris@0 97 *
Chris@0 98 * @param {object} options
Chris@0 99 * An object with the following keys:
Chris@0 100 * @param {string} options.fieldID
Chris@0 101 * The field ID that uniquely identifies the field for which this form
Chris@0 102 * will be loaded.
Chris@0 103 * @param {bool} options.nocssjs
Chris@0 104 * Boolean indicating whether no CSS and JS should be returned (necessary
Chris@0 105 * when the form is invisible to the user).
Chris@0 106 * @param {bool} options.reset
Chris@0 107 * Boolean indicating whether the data stored for this field's entity in
Chris@0 108 * PrivateTempStore should be used or reset.
Chris@0 109 * @param {function} callback
Chris@0 110 * A callback function that will receive the form to be inserted, as well
Chris@0 111 * as the ajax object, necessary if the callback wants to perform other
Chris@0 112 * Ajax commands.
Chris@0 113 */
Chris@0 114 load(options, callback) {
Chris@0 115 const fieldID = options.fieldID;
Chris@0 116
Chris@0 117 // Create a Drupal.ajax instance to load the form.
Chris@0 118 const formLoaderAjax = Drupal.ajax({
Chris@17 119 url: Drupal.quickedit.util.buildUrl(
Chris@17 120 fieldID,
Chris@17 121 Drupal.url(
Chris@17 122 'quickedit/form/!entity_type/!id/!field_name/!langcode/!view_mode',
Chris@17 123 ),
Chris@17 124 ),
Chris@0 125 submit: {
Chris@0 126 nocssjs: options.nocssjs,
Chris@0 127 reset: options.reset,
Chris@0 128 },
Chris@0 129 error(xhr, url) {
Chris@0 130 // Show a modal to inform the user of the network error.
Chris@0 131 const fieldLabel = Drupal.quickedit.metadata.get(fieldID, 'label');
Chris@17 132 const message = Drupal.t(
Chris@17 133 '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.',
Chris@17 134 { '@field-label': fieldLabel },
Chris@17 135 );
Chris@17 136 Drupal.quickedit.util.networkErrorModal(
Chris@17 137 Drupal.t('Network problem!'),
Chris@17 138 message,
Chris@17 139 );
Chris@0 140
Chris@0 141 // Change the state back to "candidate", to allow the user to start
Chris@0 142 // in-place editing of the field again.
Chris@0 143 const fieldModel = Drupal.quickedit.app.model.get('activeField');
Chris@0 144 fieldModel.set('state', 'candidate');
Chris@0 145 },
Chris@0 146 });
Chris@0 147 // Implement a scoped quickeditFieldForm AJAX command: calls the callback.
Chris@17 148 formLoaderAjax.commands.quickeditFieldForm = function(
Chris@17 149 ajax,
Chris@17 150 response,
Chris@17 151 status,
Chris@17 152 ) {
Chris@0 153 callback(response.data, ajax);
Chris@0 154 Drupal.ajax.instances[this.instanceIndex] = null;
Chris@0 155 };
Chris@0 156 // This will ensure our scoped quickeditFieldForm AJAX command gets
Chris@0 157 // called.
Chris@0 158 formLoaderAjax.execute();
Chris@0 159 },
Chris@0 160
Chris@0 161 /**
Chris@0 162 * Creates a {@link Drupal.Ajax} instance that is used to save a form.
Chris@0 163 *
Chris@0 164 * @param {object} options
Chris@0 165 * Submit options to the form.
Chris@0 166 * @param {bool} options.nocssjs
Chris@0 167 * Boolean indicating whether no CSS and JS should be returned (necessary
Chris@0 168 * when the form is invisible to the user).
Chris@0 169 * @param {Array.<string>} options.other_view_modes
Chris@0 170 * Array containing view mode IDs (of other instances of this field on the
Chris@0 171 * page).
Chris@0 172 * @param {jQuery} $submit
Chris@0 173 * The submit element.
Chris@0 174 *
Chris@0 175 * @return {Drupal.Ajax}
Chris@0 176 * A {@link Drupal.Ajax} instance.
Chris@0 177 */
Chris@0 178 ajaxifySaving(options, $submit) {
Chris@0 179 // Re-wire the form to handle submit.
Chris@0 180 const settings = {
Chris@0 181 url: $submit.closest('form').attr('action'),
Chris@0 182 setClick: true,
Chris@0 183 event: 'click.quickedit',
Chris@0 184 progress: false,
Chris@0 185 submit: {
Chris@0 186 nocssjs: options.nocssjs,
Chris@0 187 other_view_modes: options.other_view_modes,
Chris@0 188 },
Chris@0 189
Chris@0 190 /**
Chris@0 191 * Reimplement the success handler.
Chris@0 192 *
Chris@0 193 * Ensure {@link Drupal.attachBehaviors} does not get called on the
Chris@0 194 * form.
Chris@0 195 *
Chris@0 196 * @param {Drupal.AjaxCommands~commandDefinition} response
Chris@0 197 * The Drupal AJAX response.
Chris@0 198 * @param {number} [status]
Chris@0 199 * The HTTP status code.
Chris@0 200 */
Chris@0 201 success(response, status) {
Chris@17 202 Object.keys(response || {}).forEach(i => {
Chris@14 203 if (response[i].command && this.commands[response[i].command]) {
Chris@0 204 this.commands[response[i].command](this, response[i], status);
Chris@0 205 }
Chris@14 206 });
Chris@0 207 },
Chris@0 208 base: $submit.attr('id'),
Chris@0 209 element: $submit[0],
Chris@0 210 };
Chris@0 211
Chris@0 212 return Drupal.ajax(settings);
Chris@0 213 },
Chris@0 214
Chris@0 215 /**
Chris@0 216 * Cleans up the {@link Drupal.Ajax} instance that is used to save the form.
Chris@0 217 *
Chris@0 218 * @param {Drupal.Ajax} ajax
Chris@0 219 * A {@link Drupal.Ajax} instance that was returned by
Chris@0 220 * {@link Drupal.quickedit.form.ajaxifySaving}.
Chris@0 221 */
Chris@0 222 unajaxifySaving(ajax) {
Chris@0 223 $(ajax.element).off('click.quickedit');
Chris@0 224 },
Chris@0 225 };
Chris@17 226 })(jQuery, Drupal);