(function ($) { /** * Attach the machine-readable name form element behavior. */ Drupal.behaviors.machineName = { /** * Attaches the behavior. * * @param settings.machineName * A list of elements to process, keyed by the HTML ID of the form element * containing the human-readable value. Each element is an object defining * the following properties: * - target: The HTML ID of the machine name form element. * - suffix: The HTML ID of a container to show the machine name preview in * (usually a field suffix after the human-readable name form element). * - label: The label to show for the machine name preview. * - replace_pattern: A regular expression (without modifiers) matching * disallowed characters in the machine name; e.g., '[^a-z0-9]+'. * - replace: A character to replace disallowed characters with; e.g., '_' * or '-'. * - standalone: Whether the preview should stay in its own element rather * than the suffix of the source element. * - field_prefix: The #field_prefix of the form element. * - field_suffix: The #field_suffix of the form element. */ attach: function (context, settings) { var self = this; $.each(settings.machineName, function (source_id, options) { var $source = $(source_id, context).addClass('machine-name-source'); var $target = $(options.target, context).addClass('machine-name-target'); var $suffix = $(options.suffix, context); var $wrapper = $target.closest('.form-item'); // All elements have to exist. if (!$source.length || !$target.length || !$suffix.length || !$wrapper.length) { return; } // Skip processing upon a form validation error on the machine name. if ($target.hasClass('error')) { return; } // Figure out the maximum length for the machine name. options.maxlength = $target.attr('maxlength'); // Hide the form item container of the machine name form element. $wrapper.hide(); // Determine the initial machine name value. Unless the machine name form // element is disabled or not empty, the initial default value is based on // the human-readable form element value. if ($target.is(':disabled') || $target.val() != '') { var machine = $target.val(); } else { var machine = self.transliterate($source.val(), options); } // Append the machine name preview to the source field. var $preview = $('' + options.field_prefix + Drupal.checkPlain(machine) + options.field_suffix + ''); $suffix.empty(); if (options.label) { $suffix.append(' ').append('' + options.label + ':'); } $suffix.append(' ').append($preview); // If the machine name cannot be edited, stop further processing. if ($target.is(':disabled')) { return; } // If it is editable, append an edit link. var $link = $('' + Drupal.t('Edit') + '') .click(function () { $wrapper.show(); $target.focus(); $suffix.hide(); $source.unbind('.machineName'); return false; }); $suffix.append(' ').append($link); // Preview the machine name in realtime when the human-readable name // changes, but only if there is no machine name yet; i.e., only upon // initial creation, not when editing. if ($target.val() == '') { $source.bind('keyup.machineName change.machineName', function () { machine = self.transliterate($(this).val(), options); // Set the machine name to the transliterated value. if (machine != '') { if (machine != options.replace) { $target.val(machine); $preview.html(options.field_prefix + Drupal.checkPlain(machine) + options.field_suffix); } $suffix.show(); } else { $suffix.hide(); $target.val(machine); $preview.empty(); } }); // Initialize machine name preview. $source.keyup(); } }); }, /** * Transliterate a human-readable name to a machine name. * * @param source * A string to transliterate. * @param settings * The machine name settings for the corresponding field, containing: * - replace_pattern: A regular expression (without modifiers) matching * disallowed characters in the machine name; e.g., '[^a-z0-9]+'. * - replace: A character to replace disallowed characters with; e.g., '_' * or '-'. * - maxlength: The maximum length of the machine name. * * @return * The transliterated source string. */ transliterate: function (source, settings) { var rx = new RegExp(settings.replace_pattern, 'g'); return source.toLowerCase().replace(rx, settings.replace).substr(0, settings.maxlength); } }; })(jQuery);