Search code examples
javascriptjquerydomdom-manipulation

Change DOM position of dynamically created labels


I need to style some CMS generated labels and input fields. This is the markup for each element(there are five in total).

<br>
<label>City of birth:</label>
<br>
<input type="text" maxlength="200" name="os5">

I need to add class to each of the inputs, that is easy. I also need to put each label right after the corresponding input. I am able to target each label with this code, just for example.

$('label:nth-of-type(2)').css('color','blue');

This way I can target each five labels, but I can't find a way to move each label, right after the corresponding input field.


Solution

  • You can iterate through the collection to get each one individually using .each, at which point .nextAll will let you find the appropriate following <input> and .after can be used to move its label.

    $('label:nth-of-type(2)')
        .css('color', 'blue')
        .each(function () {
            var $label = $(this);
            var $input = $label.nextAll('input').eq(0);
    
            $input.after($label);
        });
    

    Keep in mind that the appropriate thing to do is probably identify your labels better, and make sure that they’re associated with the form fields using <label>’s for attribute (but pick a better class name):

    <label class="move-label" for="city-of-birth">City of birth:</label>
    ⋮
    <input type="text" name="os5" id="city-of-birth" maxlength="200" />
    

    And then you can do this, which I think is better =)

    var labels = Array.prototype.slice.call(
            document.getElementsByClassName('move-label')
        );
    
    labels.forEach(function (label) {
        var associatedElement = document.getElementById(label.htmlFor);
    
        label.parentNode.insertBefore(associatedElement, label.nextSibling);
    });
    

    … though jQuery works too:

    $('.move-label').each(function () {
        var $input = $(document.getElementById(this.htmlFor));
    
        $input.after(this);
    });
    

    … and if you were golfing it:

    $('.move-label').each(function () {
        $('#' + this.htmlFor).after(this);
    });