javascriptjqueryreactjsbookmarklet

jQuery ID selection with React generate components


I'm trying to make a few bookmarkets for Zendesk -- One of the problems I am running across is using jQuery for ID selection.

Given the following HTML:

<label data-garden-id="forms.input_label" data-garden-version="8.69.11" id="64val-field_2.1.0--label" for="64val-field_2.1.0--input" data-garden-container-id="containers.field" data-garden-container-version="2.1.0" class="sc-1gau0qu-1 gGZrXf StyledLabel-sc-2utmsz-0 bYrRLL">Project ID</label>
<input data-garden-id="forms.input" data-garden-version="8.69.11" aria-invalid="false" id="64val-field_2.1.0--input" aria-labelledby="64val-field_2.1.0--label" data-test-id="ticket-fields-text-field" data-tracking-id="ticket-fields-text-field" type="text" class="sc-1gau0qu-2 gEiOHk StyledTextInput-sc-k12n8x-0 bXXlCE" value="foo">

I figure the easiest way for me to find the input field value is to use the label for attribute.

$("label:contains('Project ID')").attr("for") // returns '65val-field_2.1.0--input'

I would assume I could use this as the direct ID selector by prepending '#'.

But it fails with the direct id selector:

$('#' + $("label:contains('Project ID')").attr("for")); // the length is `0`

This works with:

document.getElementById($("label:contains('Project ID')").attr("for"));

It also works with:

$('input[id="'+ $("label:contains('Project ID')").attr("for") + '"]')[0]

While I can workaround this issue with getElementByID, I'm curious why the jQuery selector won't work -- am I missing something obvious?


Solution

  • You need to escape the selector. The culprit is the 64val-field_2.1.0--input (dot characters in the id and for attribute values).

    Here is a jQuery plugin I created that returns an input associated with a label.

    (function() {
      $.formElementByLabel = function(label) {
        var $label = $('label:contains("' + label + '")');
        var formElementId = $label.attr("for");
        return $('#' + $.escapeSelector(formElementId));
      };
    })(jQuery)
    
    const $input = $.formElementByLabel("Project ID");
    
    console.log($input.val()); // foo
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <label class="sc-1gau0qu-1 gGZrXf StyledLabel-sc-2utmsz-0 bYrRLL" id="64val-field_2.1.0--label" for="64val-field_2.1.0--input" data-garden-id="forms.input_label" data-garden-version="8.69.11" data-garden-container-id="containers.field" data-garden-container-version="2.1.0">Project ID</label>
    <input type="text" class="sc-1gau0qu-2 gEiOHk StyledTextInput-sc-k12n8x-0 bXXlCE" id="64val-field_2.1.0--input" value="foo" data-garden-id="forms.input" data-garden-version="8.69.11" aria-invalid="false" aria-labelledby="64val-field_2.1.0--label" data-test-id="ticket-fields-text-field"
      data-tracking-id="ticket-fields-text-field">