I am attempting to create a new custom source that uses a link to display a ctools modal form where an image can be searched for using Apache Solr. However, I'm having a problem getting my source field and link (defined in my process callbcack) to display only when the appropriate option is selected. Instead, my fields are displayed for all enabled filefield_sources on the node edit page. Here's my code:

/**
 * Implements hook_filefield_sources_info().
 */
function nb_alters_filefield_sources_info() {
  $source = array();

  $source['image_search'] = array(
    'name' => t('Image search with Solr'),
    'label' => t('Image Search'),
    'description' => t('Search for an existing image using Apache Solr'),
    'process' => 'nb_alters_image_search_process',
    'value' => 'nb_alters_image_search_value',
    'weight' => 1,
    'file' => 'includes/image_search.inc',
  );

  return $source;
}

function nb_alters_filefield_sources_widgets() {
  // Add any widgets that your module supports here.
  return array('image_search');
}

/**
 * A #process callback to extend the filefield_widget element type.
 */
function nb_alters_image_search_process($element, &$form_state, $form) {
  $test = 'a';

  $element['image_search'] = array(
    '#weight' => 100.5,
    '#theme' => 'nb_alters_image_search_element',
    '#filefield_source' => TRUE, // Required for proper theming.
    '#filefield_sources_hint_text' => 's3://cartoons/my-cartoon.gif',
  );

  $element['image_search']['url'] = array(
    '#type' => 'textfield',
    '#maxlength' => NULL,
  );

  $element['image_search']['search'] = array(
    '#type' => 'markup',
    '#markup' => '<div id="image-search"><a href="">Search for Image</a></div>',
  );

  return $element;
}

function nb_alters_image_search_value($element, &$item) {

}


/**
 * Implements hook_theme().
 */
function nb_alters_image_search_theme() {
  return array(
    'nb_alters_image_search_element' => array(
      'render element' => 'element',
      'file' => 'includes/image_search.inc',
    ),
  );
}

/**
 * Theme the output of the image_search field.
 */
function theme_nb_alters_image_search_element($variables) {
  $element = $variables['element'];

  $element['url']['#field_suffix'] = drupal_render($element['search']);
  return '<div class="filefield-source filefield-source-image_search clear-block">' . drupal_render($element['url']) . '</div>';
}

I've modeled this after the other sources in the /sources folder, so I'm not sure what I'm missing. What do I need to do so that my fields are only displayed when my Image Search option is selected?

Thanks.

EDIT: I moved my hook_theme to my module file (it was in includes/image_search.inc), and my theme function is now being found, but now I have a different problem. The theme function is returning the output, but now the fields won't show at all, even when I click on the Image Search link in the list of sources.

Comments

wonder95’s picture

Issue summary: View changes
wonder95’s picture

Title: Custom source fields displayed for any selected source » Custom source fields not displayed for selected custom source
Status: Active » Closed (fixed)

After a couple hours and some debugging, I finally got this figured out. The secret is in these two lines from the fileFieldSources behavior in filefield_sources.js:

var fileFieldSourceClass = this.className.match(/filefield-source-[0-9a-z]+/i)[0];

$fileFieldElement.find('div.' + fileFieldSourceClass).css('display', '');

and this code from my theme function:

return '<div class="filefield-source filefield-source-imgsearch clear-block">' . drupal_render($element['file_url']) . '</div>';

The regex that is used to define the fileFieldSourceClass var limits the text after 'filefield-source-' to just letters and numbers. That meant that in my case, since I was using a class of filefield-source-image_search, the returned value was 'filefield-source-image'. Then, the second line above wouldn't find my div and remove the display:none from the css, because it was looking for 'filefield-source-image' and what was actually there was filefield-source-image_source. Changing my theme function to use the filefield-source-imgsearch class fixed the problem.

On a similar note, I also discovered that if you want your hint text to display in your custom fields, the class name (at least the part after 'filefield-source-') I just updated above needs to match the key name used for your fields in your process function (defined in your hook_filefield_sources_info() hook implementation). The reason is this code from Drupal.filefieldsources.updateHintText:

      var matches = this.className.match(/filefield-source-([a-z]+)/);
      var sourceType = matches[1];
      var defaultText = '';
      var textfield = $(this).find('input.form-text:first').get(0);
      var defaultText = (Drupal.settings.fileFieldSources && Drupal.settings.fileFieldSources[sourceType]) ? Drupal.settings.fileFieldSources[sourceType].hintText : '';

As you can see, the matches var is the wrapped set determined by the class from the theme function, and the sourceType matches to the key from the arrays added to $element in the process function.