• My pdb_record page has buttons that run JS scripts that access input fields using document.getElementById(). The ids of the fields used to be of the form “pdb-some_field” but they are now of the form “pdb-some_field-2”, so the scripts no longer work because they can’t find any of the elements.

    Looking at PDB source code this seems to be because it now appends $instance_index to all the ids, which is an “index for tracking multiple instances of a shortcode”. However the page just has one instance of the shortcode:

    [pdb_record template=bootstrap groups=main,admin,admin_history,profile,address,contact]

    Looking at the page’s HTML source code there seems to be only one instance of each id, so why do they all have “-2” added?

    I could just change all the calls to be of the form document.getElementById('pdb-some_field-2'), but am reluctant to do so in case the ids change again. I could try using getElementsByName('some_field'), and hope that the first one returned is the correct input field, would this always be the case? Also I assume this is less efficient than getElementById(), which is the normal way of finding an element.

    What is needed is a reliable way to get the input field element corresponding to the field’s name. Would it be possible for PDB to generate a JS function (e.g.pdb_getElement('some_field')) that generates the correct id and uses this in calling getElementById()?

    What the best long term solution to accessing input fields whose ids might change again in the future?

    • This topic was modified 5 years, 8 months ago by wonderer0.
    • This topic was modified 5 years, 8 months ago by wonderer0.
Viewing 3 replies - 1 through 3 (of 3 total)
  • Plugin Author xnau webdesign

    (@xnau)

    Thanks for the feedback, it was a necessary solution for users who were putting multiple shortcodes on a page and getting validation errors. I’m sorry about the impact on your code.

    These won’t change again, this is not the kind of thing I change without a lot of consideration of the impacts. However, if you want the code to be more robust, you’ll find that there is a hidden field in the form named “instance_index” that will provide the instance number. You can use that value to build your selector (the ID string) that you can be sure will be correct.

    Again, my apologies for the inconvenience, I hope you understand that I’d rather not change this again.

    Thread Starter wonderer0

    (@wonderer0)

    Thanks for your prompt reply.

    I have replaced the direct calls to getElementById by calls to my own function that appends the “instance_index”. The buttons are working OK now thanks.

    Unfortunately it might be more tricky to fix the #id selectors in the CSS, which is used to control the appearance of the fields displayed by the bootstrap based template. They are specified in a SCSS file that is compiled to CSS by the Gantry 5 framework, so can’t be modified to take into account the instance_index at run-time.

    SCSS supports $variables for values (e.g. color: $dark-1), but when I tried using one in an id selector it failed to compile (e.g. #pdb-some_field$pdb-suffix).

    There are several possible solutions, in decreasing order of risking name clashes:

    • Use the elements’ names as selectors [name=some_field]. But as the name doesn’t begin with “pdb-” there is a danger of clashing with other elements with the same name. WP pages are quite complex, and I aren’t familiar with all the elements generated.
    • Give each field an additional pdb class based on its name, then just replace #pdb-some_field selectors with .pdb-some_field ones. But do you generate any pdb-something classes that could clash with the ones for fields?
    • Give each element an additional pdb-name="some_field" attribute, then use [pdb-name=some_field] selectors. This completely avoids the risk of name clashes, but are browsers slower using general attribute selectors than identity or class selectors?

    I think it’s got to be one of the last two to avoid the risk of name clashes. If so it would be useful if PDB could automatically add either the class or pdb-name attribute. In the meantime I shall do one of those manually myself, but would like to do it the same way that PDB might be going. What are your thoughts on the matter? You might have a better way of fixing the CSS now that the fields’ ids can change.

    P.S.
    You might want to move this to a new topic as the subject has changed from JS to CSS.

    • This reply was modified 5 years, 8 months ago by wonderer0.
    Plugin Author xnau webdesign

    (@xnau)

    You should be able to taget the CSS selectors on the inputs reliably if you include a classname from the foem or from the form wrapper, that will restrict the scope fo the name selector to that one form… for example:

    .pdb-record [name=input_name]{}

    Really depends on the context. Usually, you can go up the hierachy to find a classanme that will elimiate ambiguity in the selector.

Viewing 3 replies - 1 through 3 (of 3 total)

The topic ‘JS scripts fail because input field ids have changed’ is closed to new replies.