Dan Dan - 2 months ago 6
Javascript Question

Manipulate HTML elements added dynamically with 'vanilla' javascript

I'm creating a JavaScript plug-in which needs a fairly large/complex HTML structure to be rendered on the web page, before being manipulated via JavaScript. I don't want to use jQuery at all in this.

I'd like to be able to bundle all of the required code in a single JS file, which can be loaded into a parent web page and it'll 'do its thing'. I'd rather the parent page did not have to include any additional HTML/CSS in order to work - I want everything to come from the single JS resource.

Currently I have the large chunk of HTML in a JavaScript variable as a string:

var templateBirthday = '\
<section class="pwag-clearfix pwag-birthday-groups">\
<div class="pwag-clearfix pwag-birthday-groups__inner">\
<div class="pwag-birthday-group">\
<p class="pwag-birthday-group__instruction">Enter the year of your birth</p>\
<div class="pwag-date-box pwag-date-box--valid pwag-date-box--0">\
<span class="pwag-date-box__value">1</span>\
<span class="pwag-date-box__placeholder">Y</span>\
<input type="number" class="pwag-date-box__input" />\
</div>\
<div class="pwag-date-box pwag-date-box--valid pwag-date-box--1">\
<span class="pwag-date-box__value">9</span>\
<span class="pwag-date-box__placeholder">Y</span>\
<input type="number" class="pwag-date-box__input" />\
</div>\
<div class="pwag-date-box pwag-date-box--2">\
<span class="pwag-date-box__value"></span>\
<span class="pwag-date-box__placeholder">Y</span>\
<input type="number" class="pwag-date-box__input" />\
</div>\
<div class="pwag-date-box pwag-date-box--3">\
<span class="pwag-date-box__value"></span>\
<span class="pwag-date-box__placeholder">Y</span>\
<input type="number" class="pwag-date-box__input" />\
</div>\
</div>\
<div class="pwag-birthday-group">\
<p class="pwag-birthday-group__instruction">Enter the month of your birth</p>\
<div class="pwag-date-box pwag-date-box--4">\
<span class="pwag-date-box__value"></span>\
<span class="pwag-date-box__placeholder">M</span>\
<input type="number" class="pwag-date-box__input" />\
</div>\
<div class="pwag-date-box pwag-date-box--5">\
<span class="pwag-date-box__value"></span>\
<span class="pwag-date-box__placeholder">M</span>\
<input type="number" class="pwag-date-box__input" />\
</div>\
</div>\
<div class="pwag-birthday-group">\
<p class="pwag-birthday-group__instruction">Enter the day of your birth</p>\
<div class="pwag-date-box pwag-date-box--6">\
<span class="pwag-date-box__value"></span>\
<span class="pwag-date-box__placeholder">D</span>\
<input type="number" class="pwag-date-box__input" />\
</div>\
<div class="pwag-date-box pwag-date-box--7">\
<span class="pwag-date-box__value"></span>\
<span class="pwag-date-box__placeholder">D</span>\
<input type="number" class="pwag-date-box__input" />\
</div>\
</div>\
</div>\
<div class="pwag-clearfix pwag-feedback">\
<span class="pwag-feedback__message pwag-feedback__message--year">The year you entered is invalid</span>\
<span class="pwag-feedback__message pwag-feedback__message--month">The month you entered is invalid</span>\
<span class="pwag-feedback__message pwag-feedback__message--day">The day you entered is invalid</span>\
<span class="pwag-feedback__message pwag-feedback__message--notLegal">You are not old enough to enter this site</span>\
</div>\
</section>\
';


I'm then rendering this into the parent page as follows:

function appendHtml(el, str) {
var div = document.createElement('div');
div.innerHTML = str;
while (div.children.length > 0) {
el.appendChild(div.children[0]);
}
}

appendHtml(document.body, templateBirthday);


It works fine; I see the HTML on the page. However, now I need to be able to manipulate the various HTML elements from the same JS file. So for example, I want do to this:

document.querySelectorAll('.pwag-date-box')[0].style.border = '10px solid #f00';


However, because the HTML is being dynamically inserted it doesn't appear to be accessible by using the standard
document.querySelectorAll
type of methods in vanilla JS.

I fear my only option may be to create that massive chunk of HTML as 'proper' JavaScript objects rather than a string. I was hoping there was a way to cheat and use a string for the HTML.

Does anyone know if it's possible to work with standard JS selectors on HTML which has been inserted into the DOM as a string?

Many thanks,

Dan

Answer

Simple solution is using document.getElementsByClassName(). Hope it helps...

var templateBirthday = '\
    <section class="pwag-clearfix pwag-birthday-groups">\
        <div class="pwag-clearfix pwag-birthday-groups__inner">\
            <div class="pwag-birthday-group">\
                <p class="pwag-birthday-group__instruction">Enter the year of your birth</p>\
                <div class="pwag-date-box pwag-date-box--valid pwag-date-box--0">\
                    <span class="pwag-date-box__value">1</span>\
                    <span class="pwag-date-box__placeholder">Y</span>\
                    <input type="number" class="pwag-date-box__input" />\
                </div>\
                <div class="pwag-date-box pwag-date-box--valid pwag-date-box--1">\
                    <span class="pwag-date-box__value">9</span>\
                    <span class="pwag-date-box__placeholder">Y</span>\
                    <input type="number" class="pwag-date-box__input" />\
                </div>\
                <div class="pwag-date-box pwag-date-box--2">\
                    <span class="pwag-date-box__value"></span>\
                    <span class="pwag-date-box__placeholder">Y</span>\
                    <input type="number" class="pwag-date-box__input" />\
                </div>\
                <div class="pwag-date-box pwag-date-box--3">\
                    <span class="pwag-date-box__value"></span>\
                    <span class="pwag-date-box__placeholder">Y</span>\
                    <input type="number" class="pwag-date-box__input" />\
                </div>\
            </div>\
            <div class="pwag-birthday-group">\
                <p class="pwag-birthday-group__instruction">Enter the month of your birth</p>\
                <div class="pwag-date-box pwag-date-box--4">\
                    <span class="pwag-date-box__value"></span>\
                    <span class="pwag-date-box__placeholder">M</span>\
                    <input type="number" class="pwag-date-box__input" />\
                </div>\
                <div class="pwag-date-box pwag-date-box--5">\
                    <span class="pwag-date-box__value"></span>\
                    <span class="pwag-date-box__placeholder">M</span>\
                    <input type="number" class="pwag-date-box__input" />\
                </div>\
            </div>\
            <div class="pwag-birthday-group">\
                <p class="pwag-birthday-group__instruction">Enter the day of your birth</p>\
                <div class="pwag-date-box pwag-date-box--6">\
                    <span class="pwag-date-box__value"></span>\
                    <span class="pwag-date-box__placeholder">D</span>\
                    <input type="number" class="pwag-date-box__input" />\
                </div>\
                <div class="pwag-date-box pwag-date-box--7">\
                    <span class="pwag-date-box__value"></span>\
                    <span class="pwag-date-box__placeholder">D</span>\
                    <input type="number" class="pwag-date-box__input" />\
                </div>\
            </div>\
        </div>\
        <div class="pwag-clearfix pwag-feedback">\
            <span class="pwag-feedback__message pwag-feedback__message--year">The year you entered is invalid</span>\
            <span class="pwag-feedback__message pwag-feedback__message--month">The month you entered is invalid</span>\
            <span class="pwag-feedback__message pwag-feedback__message--day">The day you entered is invalid</span>\
            <span class="pwag-feedback__message pwag-feedback__message--notLegal">You are not old enough to enter this site</span>\
        </div>\
    </section>\
';

function appendHtml(el, str) {
    var div = document.createElement('div');
    div.innerHTML = str;
    while (div.children.length > 0) {
        el.appendChild(div.children[0]);
    }
}

appendHtml(document.body, templateBirthday);

//using document.getElementsByClassName() instead of document.querySelectorAll()
document.getElementsByClassName('pwag-date-box')[0].style.border = '10px solid #f00'
<body> </body>

Comments