When Phone processes an individual form element in phone_element_process($element, &$form_state, $form), it blows away any existing stuff stored in the $element variable.

This specifically breaks compatibility with the field_placeholder module, which adds an HTML5 placeholder attribute to the element. Field_placeholder adds the attribute in a form_alter hook that gets run before phone_element_process():

$element[$placeholder]['#attributes']['placeholder'] = check_plain($instance['placeholder']);
// where $placeholder = 'number'

So when Phone processes the field it replaces whatever was inside the element with its own attributes:

$element['number'] = array(
  ...
);

A good way to handle this is seen in Drupal's core text module by doing an array union with whatever is already there like so:

$element['number'] = $element['number'] + array(
  ...
);

Of course since we're referencing an array element we should ensure ahead of time that $element['number'] will be set.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

aptorian’s picture

This patch should fix things.

cdale’s picture

As the phone module defines these fields, I'm not sure it should care about what other modules are doing. A better approach, would be for field place-holder to use an after_build callback, or even better, as it's just adding in #attributes, would be to use a #pre_render callback to add in the attributes later in the form build cycle. It would be best to add the pre render callback onto the top level element in the form alter, and then do processing in the pre render. Most, if not all modules shouldn't blow away a pre render on the top level element. At least I don't believe they should, as it's quite possible that core will add it's own #after_build or #pre/post_render callbacks.