6

Here is the XML for a particular form field:

    <field type="text" name="first-name" id="first-name" label="MOD_LABEL_FIRST_NAME" 
required="required" maxlength="27" color="yellow" />

My problem is that when displaying the form as HTML, the attributes are being filtered in some way. For example, the attribute type is displayed as part of the markup but attributes like required and color are not. (Color is a dummy attribute I have created for testing purposes, but required is important as I want to use the HTML5 required behaviour.)

Here is the markup output for the specific field described in the XML above:

<label id="first-name-label" for="first-name">First name</label>
<input type="text" name="first-name" id="first-name" maxlength="27"/>

I know custom attributes like color exist as part of the object - here is the result from a var_dump of $oForm->getField('first-name') :

object(JFormFieldText)#773 (19) {
  ["type":protected]=>
  string(4) "Text"
  ["element":protected]=>
  object(JXMLElement)#772 (1) {
    ["@attributes"]=>
    array(9) {
      ["type"]=>
      string(4) "text"
      ["name"]=>
      string(15) "first-name"
      ["id"]=>
      string(15) "first-name"
      ["label"]=>
      string(30) "MOD_LABEL_FIRST_NAME"
      ["required"]=>
      string(8) "required"
      ["maxlength"]=>
      string(2) "27"
      ["color"]=>
      string(6) "yellow"
    }
  }

Further, I have tried following the methods described in the answer to this question as they seemed relevant, but it hasn't worked in my case, as I just get syntax errors:

$oField = $oForm->getField('first-name');
  echo $oField->type; // returns 'Text'
  echo $oField->element->["color"]; // returns syntax error

While it would be interesting to know how to access/manipulate custom attributes in this case, my main question is why are only some attributes displayed in the markup?

1 Answer 1

4

Though the XML file and the rendered HTML both call them attributes, there is not a direct pass through of values. Hence, only some attributes make it to the HTML (and some extra attributes are added).

All of this is based on the class that you can see here: https://github.com/joomla/joomla-cms/blob/staging/libraries/joomla/form/fields/text.php#L163

So for every field, you specify a type, in this case text. This leads to the JFormFieldText class handling the rendering. JForm will call getInput on the field class to actually get back the input html. Glancing through this code, it should be very obvious why your custom attributes are not passed through:

protected function getInput()
{
    // Translate placeholder text
    $hint = $this->translateHint ? JText::_($this->hint) : $this->hint;
    // Initialize some field attributes.
    $size         = !empty($this->size) ? ' size="' . $this->size . '"' : '';
    $maxLength    = !empty($this->maxLength) ? ' maxlength="' . $this->maxLength . '"' : '';
    $class        = !empty($this->class) ? ' class="' . $this->class . '"' : '';
    $readonly     = $this->readonly ? ' readonly' : '';
    $disabled     = $this->disabled ? ' disabled' : '';
    $required     = $this->required ? ' required aria-required="true"' : '';
    $hint         = $hint ? ' placeholder="' . $hint . '"' : '';
    $autocomplete = !$this->autocomplete ? ' autocomplete="off"' : ' autocomplete="' . $this->autocomplete . '"';
    $autocomplete = $autocomplete == ' autocomplete="on"' ? '' : $autocomplete;
    $autofocus    = $this->autofocus ? ' autofocus' : '';
    $spellcheck   = $this->spellcheck ? '' : ' spellcheck="false"';
    $pattern      = !empty($this->pattern) ? ' pattern="' . $this->pattern . '"' : '';
    $inputmode    = !empty($this->inputmode) ? ' inputmode="' . $this->inputmode . '"' : '';
    $dirname      = !empty($this->dirname) ? ' dirname="' . $this->dirname . '"' : '';
    // Initialize JavaScript field attributes.
    $onchange = !empty($this->onchange) ? ' onchange="' . $this->onchange . '"' : '';
    // Including fallback code for HTML5 non supported browsers.
    JHtml::_('jquery.framework');
    JHtml::_('script', 'system/html5fallback.js', false, true);
    $datalist = '';
    $list     = '';
    /* Get the field options for the datalist.
    Note: getSuggestions() is deprecated and will be changed to getOptions() with 4.0. */
    $options  = (array) $this->getSuggestions();
    if ($options)
    {
        $datalist = '<datalist id="' . $this->id . '_datalist">';
        foreach ($options as $option)
        {
            if (!$option->value)
            {
                continue;
            }
            $datalist .= '<option value="' . $option->value . '">' . $option->text . '</option>';
        }
        $datalist .= '</datalist>';
        $list     = ' list="' . $this->id . '_datalist"';
    }
    $html[] = '<input type="text" name="' . $this->name . '" id="' . $this->id . '"' . $dirname . ' value="'
        . htmlspecialchars($this->value, ENT_COMPAT, 'UTF-8') . '"' . $class . $size . $disabled . $readonly . $list
        . $hint . $onchange . $maxLength . $required . $autocomplete . $autofocus . $spellcheck . $inputmode . $pattern . ' />';
    $html[] = $datalist;
    return implode($html);
}

There are a lot of attributes that you can set: size, maxlength, class, readonly, disabled, required, and more! But if it's not defined in that class, it won't be in the final html.

If the attribute you need isn't there you have two options: submit a pull request against Joomla to get it added or make a custom form field type that does render the attribute that you need.

The docs should have all you need to create that custom field type: https://docs.joomla.org/Creating_a_custom_form_field_type

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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