0

I'm working on a custom webform component to essentially look up entity properties in an autocomplete field.

All works perfectly in Firefox, but I'm just seeing an plain old textfield in Chrome and Safari. Nothing is printed to the console, and nothing is printed to watchdog.

This is what the field looks like on Chrome/Safari:

enter image description here

This is what is looks like in Firefox:

enter image description here

I'm wondering if this has something to do with my code, so I've extracted the relevant snippets below:

Form Definition:

  $ac_field_id = drupal_html_id('field_autocomplete');
  $element['field_autocomplete'] = array(
    '#type' => 'textfield',
    '#title' => $component['name'],
    '#description' => t($component['extra']['description']),
    '#default_value' => $value['field_autocomplete'],
    '#required' => $component['required'],
    '#autocomplete_path' => 'entity-auto-comp/' . $field_entity_type .
                                '/' . $field_entity_prop . '/' . $field_number_of_items_to_return .
                                '/' . $search_type . '/autocomplete',
    '#attributes' => array(
      'data-entity-auto-id' => $ac_field_id,
    ),
  );

How Autocomplete Path is being Handled:

 /**
  * Implements hook_menu() - this provides a URL route for our
  * entity data source
  */
 function entity_auto_comp_menu() {
    $items['entity-auto-comp/%/%/%/%/autocomplete'] = array(
      'page callback' => 'entity_auto_comp_autocomplete',
      'page arguments' => array(1, 2, 3, 4),
      'access arguments' => array('view published content'),
      'type' => MENU_CALLBACK,
    );
    return $items;
}

/**
 * Implements hook_autocomplete() - which allows us to return data
 * to the form field as JSON.
 */
function entity_auto_comp_autocomplete($entity_type, $entity_prop, $max_results = 5, $search_type = 'STARTS_WITH', $string = '') {

  //Get all relevant entity IDs
  $efq = new EntityFieldQuery();
  $efq->entityCondition('entity_type', $entity_type, '=');
  $efq->propertyCondition($entity_prop, $string, $search_type);
  $efq->range(0, $max_results);
  $efq_result = $efq->execute();
  $efq_keys = array_keys($efq_result[$entity_type]);

  //Load entities from database
  $entities = entity_load($entity_type, $efq_keys, false);

  $prop_values = array();
  foreach($entities as $entity){
    $prop_values[$entity->$entity_prop] = $entity->$entity_prop;
  }

  //If we couldn't find anything, say so
  if(count($prop_values) == 0){
    $prop_values[""] = "No results were found...";
  }

  drupal_json_output($prop_values);

}

Some JS I'm using to detect changes and populate a hidden form field:

(function ($) {
    Drupal.behaviors.ol_webform_manage_map_default = {
        attach:function (context, settings) {

          //Get the autocomplete field as a jQuery object
          var $autocomplete_field = jQuery('input[data-entity-auto-id="'+Drupal.settings['ac_field_id']+'"]', context);
          var $autocomplete_value = jQuery('#'+Drupal.settings['ac_field_id'], context);

          //Event listener for option selection
          $autocomplete_field.bind('autocompleteSelect', function(event) {
            $autocomplete_value.val(jQuery(this).val());
          });

        }
    };
})(jQuery);


I'm stumped. So I would appreciate any help you can provide!

Thanks,

Strainy

Update

Scratch that. Nothing to do with browsers. It's got something to do with how I'm handling permissions at either the form field level or the autocomplete path. Realised that I can only use autocomplete if I'm logged in!

  • Actually, you don't need to be logged in, as long as the anonymous role has the 'view published content' permission Depending upon what data you're exposing, this may be completely reasonable. – Torenware Networks Jan 26 '16 at 4:07
  • The anonymous role does have that perm however. Otherwise they wouldn't even be able to see the webform. – Strainy Jan 26 '16 at 4:08
0

If it works on Firefox, I suspect that the issue is with the javascript. Here, the question you should be asking is: do you really need to write your own.

In Drupal 7, there's a default implementation of the javascript you need for this in misc/autocomplete.js. In fact, by defining your callback via '#autocomplete_path', you are likely asking for trouble: both your javascript handler from your .js file and the javascript from misc/autocomplete.js may well be completing with each other to handle the textfield. I would not be in the least surprised if the behavior you saw was browser dependent.

Unless there's a specific reason you need the javascript you've written, I'd just use the default javascript, which will get automatically loaded for you when you use the '#autocomplete_path' Form API key. AFAICT, your callback and your hook_menu definitions are just fine.

However, you can find a nice sample in the Examples Module (https://www.drupal.org/project/examples). Where your implementation differs, the simpler implementation in the Examples code may well be more cross-browser compatible.

  • Hi Torenware, I'm merely attaching the js to the form and assigning a Drupal core event listener - so this shouldn't be an issue. See my update, it's a permissions issue. – Strainy Jan 26 '16 at 4:07
  • I see your implementation of Drupal.behaviors.ol_webform_manage_map_default. Just be aware that simply by using the '#autocomplete_path' key in a Form API array that you are causing two things to happen in addition to your javascript: first, your textfield widget will get the CSS class 'autocomplete' added to its classes array, and as a consequence, the javascript code in Drupal.behaviors.autocomplete will also want to manipulate the widget. My guess is that behavior in that case will be somewhat unpredictable. – Torenware Networks Jan 26 '16 at 4:18
0

The problem was with my menu hook. I was using 'view published content' as an access argument, where the argument should have actually been 'access content'.

 /**
  * Implements hook_menu() - this provides a URL route for our
  * entity data source
  */
 function entity_auto_comp_menu() {
    $items['entity-auto-comp/%/%/%/%/autocomplete'] = array(
      'page callback' => 'entity_auto_comp_autocomplete',
      'page arguments' => array(1, 2, 3, 4),
      'access arguments' => array('access content'),
      'type' => MENU_CALLBACK,
    );
    return $items;
}

This, and more about access arguments, can be found in the Drupal documentation: https://www.drupal.org/node/553368

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.