简体   繁体   中英

How to apply css styles to dynamic JavaScript array?

I'm trying to apply CSS styles to input elements that are added to the HTML DOM dynamically via a JSON object.

Essentially an Ajax call receives a JSON payload with an array of data. Some KnockoutJS code then foreach's over the DOM to dynamically add rows.

I'm trying to add styles to inputs where a value is less than a required value. The bottom line is, I know the elements are dynamic to the DOM, and I'm having trouble accessing them so I can apply the style. I've tried both jQuery and pure JavaScript, and I can't access the newly added fields.

How would I do this?

I have a very complex fiddle created that creates the inputs. But I can't figure out how to style those inputs whose values are less than the current year.

I'm trying to add the .k-invalid style to the NextPaymentDate input whose value is less than the current year.

var $incomeWrapper = $("#income-wrapper");
$incomeWrapper.find("input#iNextPaymentDate_" + i).removeClass("k-valid").addClass("k-invalid");

The above doesn't work.

http://jsfiddle.net/kahanu/rdb00n76/9/

You could add a filter function to your selector like this:

$('input[id^="iNextPaymentDate_"]').filter(function(index) {
    return parseInt($(this).val().split('/')[2]) < new Date().getFullYear();
}).addClass('k-invalid');

Fiddle: http://jsfiddle.net/rdb00n76/10/

The above code selects all inputs whose ids start with iNextPaymentDate_ , then applies a filter that evaluates the current element against the current full year. To do this I split the date string on / and take the 3rd item which should be the year. Then I cast the value to int and compare the the current year.

Your actual filter function should probably be a lot more solid than the one above. For example, you could include moment.js for comparisons.

I think the forEach loop inside ListDateValidation is being executed too soon. If my understanding from your jsfiddle is correct, you're running it as soon as you instantiate the FinancialViewModel, but even though the call comes after everything else, Knockout may not have updated the DOM by this point.

There are several ways you could check this and if correct, guard against this.

But for now, to check if this is the case, I would suggest placing some logic immediately prior to the self.ListDateValidation() method call: in this logic you should just have a quick and dirty way of determining if any of those elements are present - can you temporarily (just for debugging) give these elements id attributes (just increment an int) and then run something like

if (document.getElementById("test-id-1") !== null) {
    console.log("element found");
}

This will tell you if you're running the date validation too soon.

If you need a method of determining when the elements have been added then search for "javascript poll dom element added". If you can't be bothered, here's a crude method:

var elmnt,
    elmntId = "YOUR ELEMENT'S ID HERE",
    tmr = window.setInterval(function() {
        elmnt = document.getElementById(elmntId);
        if (elmnt) {
            window.clearInterval(tmr); // stop the search
            // do something
        }
    }, 15);

This method polls the DOM every 15ms, then stops when it finds that the element with the specified ID is present. 15ms corresponds to the minimum tie increment in which a browser will run - if this has since been lowered then great, but no-one would notice the difference in this context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM