3

I'm building a plugin that relies on Javascript to function correctly. Having tried different methods, I can't get the ID names to remain consistent.

Here's an example of the code that is being output.

<input type="text"
id="fields-slider-output"
name="fields[slider]"
value="539">

<span id="fields-value"></span>

<input
id="fields-input"
type="range"
name="fields[slider]"
value="539"  min="0 max="1000" step="0">

The first input is a text input, and displays the ID as you would expect. The span element below only contains "fields-", and leaves out the name of the field. The same happens with the range input, which is the most surprising, as it's a form input with a name.

When using JavaScript, the "fields-" namespace is left out entirely, which means that the Javascript can't bind to an element.

$("#slider-input")[0].oninput = function () {
    $('#slider-value').html(this.value);
};

I'm using this code from the Craft docs.

$id = craft()->templates->formatInputId($name);
$namespacedId = craft()->templates->namespaceInputId($id);

I've also looked into the namespacing HTML docs (http://buildwithcraft.com/docs/apis/templatesservice#namespacing-html) with little success.

Does anyone know a possible solution to this? Bearing in mind this Fieldtype requires Matrix support, so using a class instead of an ID is not an option.

Thanks.

2
  • Have you read through this? buildwithcraft.com/docs/plugins/field-types#binding-javascript Commented Jul 16, 2014 at 17:55
  • That was one of the things I looked at first of all, but the file can't be included externally, or using includeJs in fieldtype.php, because it uses variables in the template file to do things like change the input value. If I added the JS in the fieldtype.php file, these values wouldn't exist yet. I think that's where I'm getting stuck. Commented Jul 16, 2014 at 19:19

1 Answer 1

4

It’s not enough to simply define $namespacedId – you need to actually use it in your Javascript code.

If you’re defining the javascript code in your template, you’ll need to pass the namespaced ID to your template, along with name, id, and value:

return craft()->templates->render("myplugin/my_input_template", array(
    'name'         => $name,
    'id'           => $id,
    'namespacedId' => $namespacedId,
    'value'        => $value
));

Then in your template, use the id variable within id= attributes, and the namespacedId variable within Javascript code:

<input type="text" id="{{ id }}-output" name="{{ name }}" value="{{ value }}">
<span id="{{ id }}-value"></span>
<input id="{{ id }}-input" type="range" value="{{ value }}" min="0" max="1000" step="0">

{% set js %}
    $("#{{ namespacedId }}-input")[0].oninput = function () {
        $('#{{ namespacedId }}-value').html(this.value);
    };
{% endset %}

{% includeJs js %}

(I’ve cleaned up your HTML a little, besides the formatting – I added a missing quote after min="0, and removed the entire name= attribute from the 3rd input, since the first input seems like it will already take care of that.)

2
  • Thanks Brandon, that works perfectly. I appreciate you cleaning up the source too. Although this isn't the exact code I'm using, it's more of a late night cut and paste job. As usual, awesome support from the Craft team! Thanks. Commented Jul 16, 2014 at 20:44
  • More than 5 years later, this is still relevant, even for Craft 3 👏
    – nstCactus
    Commented Jan 22, 2020 at 19:13

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.