| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 | /** * @file * Attaches the behaviors for the Field UI module. */ (function($) {Drupal.behaviors.fieldUIFieldOverview = {  attach: function (context, settings) {    $('table#field-overview', context).once('field-overview', function () {      Drupal.fieldUIFieldOverview.attachUpdateSelects(this, settings);    });  }};Drupal.fieldUIFieldOverview = {  /**   * Implements dependent select dropdowns on the 'Manage fields' screen.   */  attachUpdateSelects: function(table, settings) {    var widgetTypes = settings.fieldWidgetTypes;    var fields = settings.fields;    // Store the default text of widget selects.    $('.widget-type-select', table).each(function () {      this.initialValue = this.options[0].text;    });    // 'Field type' select updates its 'Widget' select.    $('.field-type-select', table).each(function () {      this.targetSelect = $('.widget-type-select', $(this).closest('tr'));      $(this).bind('change keyup', function () {        var selectedFieldType = this.options[this.selectedIndex].value;        var options = (selectedFieldType in widgetTypes ? widgetTypes[selectedFieldType] : []);        this.targetSelect.fieldUIPopulateOptions(options);      });      // Trigger change on initial pageload to get the right widget options      // when field type comes pre-selected (on failed validation).      $(this).trigger('change', false);    });    // 'Existing field' select updates its 'Widget' select and 'Label' textfield.    $('.field-select', table).each(function () {      this.targetSelect = $('.widget-type-select', $(this).closest('tr'));      this.targetTextfield = $('.label-textfield', $(this).closest('tr'));      this.targetTextfield        .data('field_ui_edited', false)        .bind('keyup', function (e) {          $(this).data('field_ui_edited', $(this).val() != '');        });      $(this).bind('change keyup', function (e, updateText) {        var updateText = (typeof updateText == 'undefined' ? true : updateText);        var selectedField = this.options[this.selectedIndex].value;        var selectedFieldType = (selectedField in fields ? fields[selectedField].type : null);        var selectedFieldWidget = (selectedField in fields ? fields[selectedField].widget : null);        var options = (selectedFieldType && (selectedFieldType in widgetTypes) ? widgetTypes[selectedFieldType] : []);        this.targetSelect.fieldUIPopulateOptions(options, selectedFieldWidget);        // Only overwrite the "Label" input if it has not been manually        // changed, or if it is empty.        if (updateText && !this.targetTextfield.data('field_ui_edited')) {          this.targetTextfield.val(selectedField in fields ? fields[selectedField].label : '');        }      });      // Trigger change on initial pageload to get the right widget options      // and label when field type comes pre-selected (on failed validation).      $(this).trigger('change', false);    });  }};/** * Populates options in a select input. */jQuery.fn.fieldUIPopulateOptions = function (options, selected) {  return this.each(function () {    var disabled = false;    if (options.length == 0) {      options = [this.initialValue];      disabled = true;    }    // If possible, keep the same widget selected when changing field type.    // This is based on textual value, since the internal value might be    // different (options_buttons vs. node_reference_buttons).    var previousSelectedText = this.options[this.selectedIndex].text;    var html = '';    jQuery.each(options, function (value, text) {      // Figure out which value should be selected. The 'selected' param      // takes precedence.      var is_selected = ((typeof selected != 'undefined' && value == selected) || (typeof selected == 'undefined' && text == previousSelectedText));      html += '<option value="' + value + '"' + (is_selected ? ' selected="selected"' : '') + '>' + text + '</option>';    });    $(this).html(html).attr('disabled', disabled ? 'disabled' : false);  });};Drupal.behaviors.fieldUIDisplayOverview = {  attach: function (context, settings) {    $('table#field-display-overview', context).once('field-display-overview', function() {      Drupal.fieldUIOverview.attach(this, settings.fieldUIRowsData, Drupal.fieldUIDisplayOverview);    });  }};Drupal.fieldUIOverview = {  /**   * Attaches the fieldUIOverview behavior.   */  attach: function (table, rowsData, rowHandlers) {    var tableDrag = Drupal.tableDrag[table.id];    // Add custom tabledrag callbacks.    tableDrag.onDrop = this.onDrop;    tableDrag.row.prototype.onSwap = this.onSwap;    // Create row handlers.    $('tr.draggable', table).each(function () {      // Extract server-side data for the row.      var row = this;      if (row.id in rowsData) {        var data = rowsData[row.id];        data.tableDrag = tableDrag;        // Create the row handler, make it accessible from the DOM row element.        var rowHandler = new rowHandlers[data.rowHandler](row, data);        $(row).data('fieldUIRowHandler', rowHandler);      }    });  },  /**   * Event handler to be attached to form inputs triggering a region change.   */  onChange: function () {    var $trigger = $(this);    var row = $trigger.closest('tr').get(0);    var rowHandler = $(row).data('fieldUIRowHandler');    var refreshRows = {};    refreshRows[rowHandler.name] = $trigger.get(0);    // Handle region change.    var region = rowHandler.getRegion();    if (region != rowHandler.region) {      // Remove parenting.      $('select.field-parent', row).val('');      // Let the row handler deal with the region change.      $.extend(refreshRows, rowHandler.regionChange(region));      // Update the row region.      rowHandler.region = region;    }    // Ajax-update the rows.    Drupal.fieldUIOverview.AJAXRefreshRows(refreshRows);  },  /**   * Lets row handlers react when a row is dropped into a new region.   */  onDrop: function () {    var dragObject = this;    var row = dragObject.rowObject.element;    var rowHandler = $(row).data('fieldUIRowHandler');    if (typeof rowHandler !== 'undefined') {      var regionRow = $(row).prevAll('tr.region-message').get(0);      var region = regionRow.className.replace(/([^ ]+[ ]+)*region-([^ ]+)-message([ ]+[^ ]+)*/, '$2');      if (region != rowHandler.region) {        // Let the row handler deal with the region change.        refreshRows = rowHandler.regionChange(region);        // Update the row region.        rowHandler.region = region;        // Ajax-update the rows.        Drupal.fieldUIOverview.AJAXRefreshRows(refreshRows);      }    }  },  /**   * Refreshes placeholder rows in empty regions while a row is being dragged.   *   * Copied from block.js.   *   * @param table   *   The table DOM element.   * @param rowObject   *   The tableDrag rowObject for the row being dragged.   */  onSwap: function (draggedRow) {    var rowObject = this;    $('tr.region-message', rowObject.table).each(function () {      // If the dragged row is in this region, but above the message row, swap      // it down one space.      if ($(this).prev('tr').get(0) == rowObject.group[rowObject.group.length - 1]) {        // Prevent a recursion problem when using the keyboard to move rows up.        if ((rowObject.method != 'keyboard' || rowObject.direction == 'down')) {          rowObject.swap('after', this);        }      }      // This region has become empty.      if ($(this).next('tr').is(':not(.draggable)') || $(this).next('tr').length == 0) {        $(this).removeClass('region-populated').addClass('region-empty');      }      // This region has become populated.      else if ($(this).is('.region-empty')) {        $(this).removeClass('region-empty').addClass('region-populated');      }    });  },  /**   * Triggers Ajax refresh of selected rows.   *   * The 'format type' selects can trigger a series of changes in child rows.   * The #ajax behavior is therefore not attached directly to the selects, but   * triggered manually through a hidden #ajax 'Refresh' button.   *   * @param rows   *   A hash object, whose keys are the names of the rows to refresh (they   *   will receive the 'ajax-new-content' effect on the server side), and   *   whose values are the DOM element in the row that should get an Ajax   *   throbber.   */  AJAXRefreshRows: function (rows) {    // Separate keys and values.    var rowNames = [];    var ajaxElements = [];    $.each(rows, function (rowName, ajaxElement) {      rowNames.push(rowName);      ajaxElements.push(ajaxElement);    });    if (rowNames.length) {      // Add a throbber next each of the ajaxElements.      var $throbber = $('<div class="ajax-progress ajax-progress-throbber"><div class="throbber"> </div></div>');      $(ajaxElements)        .addClass('progress-disabled')        .after($throbber);      // Fire the Ajax update.      $('input[name=refresh_rows]').val(rowNames.join(' '));      $('input#edit-refresh').mousedown();      // Disabled elements do not appear in POST ajax data, so we mark the      // elements disabled only after firing the request.      $(ajaxElements).attr('disabled', true);    }  }};/** * Row handlers for the 'Manage display' screen. */Drupal.fieldUIDisplayOverview = {};/** * Constructor for a 'field' row handler. * * This handler is used for both fields and 'extra fields' rows. * * @param row *   The row DOM element. * @param data *   Additional data to be populated in the constructed object. */Drupal.fieldUIDisplayOverview.field = function (row, data) {  this.row = row;  this.name = data.name;  this.region = data.region;  this.tableDrag = data.tableDrag;  // Attach change listener to the 'formatter type' select.  this.$formatSelect = $('select.field-formatter-type', row);  this.$formatSelect.change(Drupal.fieldUIOverview.onChange);  return this;};Drupal.fieldUIDisplayOverview.field.prototype = {  /**   * Returns the region corresponding to the current form values of the row.   */  getRegion: function () {    return (this.$formatSelect.val() == 'hidden') ? 'hidden' : 'visible';  },  /**   * Reacts to a row being changed regions.   *   * This function is called when the row is moved to a different region, as a   * result of either :   * - a drag-and-drop action (the row's form elements then probably need to be   *   updated accordingly)   * - user input in one of the form elements watched by the   *   Drupal.fieldUIOverview.onChange change listener.   *   * @param region   *   The name of the new region for the row.   * @return   *   A hash object indicating which rows should be Ajax-updated as a result   *   of the change, in the format expected by   *   Drupal.displayOverview.AJAXRefreshRows().   */  regionChange: function (region) {    // When triggered by a row drag, the 'format' select needs to be adjusted    // to the new region.    var currentValue = this.$formatSelect.val();    switch (region) {      case 'visible':        if (currentValue == 'hidden') {          // Restore the formatter back to the default formatter. Pseudo-fields do          // not have default formatters, we just return to 'visible' for those.          var value = (typeof this.defaultFormatter !== 'undefined') ? this.defaultFormatter : this.$formatSelect.find('option').val();        }        break;      default:        var value = 'hidden';        break;    }    if (value != undefined) {      this.$formatSelect.val(value);    }    var refreshRows = {};    refreshRows[this.name] = this.$formatSelect.get(0);    return refreshRows;  }};})(jQuery);
 |