Reputation: 493
I have a page that contains a whole bunch of input boxes of type number. These can be individually changed, or a set of them can be changed by a selector.
I would like to show the user which input boxes have values greater than 0 in them by changing the class of the input box.
I cannot use JQuery. It has to be done with pure Javascript.
I understand I will need to use an event listener to attach a function to it?
Anyway... here's a piece of html as an example:
<input name="qty1" type="number" min="0" value="0">
<input name="qty2" type="number" min="0" value="0">
<input name="qty3" type="number" min="0" value="0">
<input name="qty4" type="number" min="0" value="0">
<input name="qty5" type="number" min="0" value="0">
Here's some Javascript I think should go with this:
function changeInputClass(element){
if(element.value > 0){
//add class 'bold-text' to this element
}
else {
//remove class 'bold-text' from this element
}
}
var myElements = document.getElementsByTagName('input');
for(var i=0; i<myElements.length; i++){
if(myElements[i].type == 'number') {
// add event listener here to call function changeInputClass()
}
}
Appreciate the help.
Update of more realistic representation of the html:
<div id="selections" class="selections">
<div class="images-container">
<div>
<div class="image-options">
<div class="product-option">
<div class="qty"><input name="qty1" type="number" min="0" value="0"></div>
<div>Product Description 1</div>
</div>
<div class="product-option">
<div class="qty"><input name="qty2" type="number" min="0" value="0"></div>
<div >Product Description 2</div>
</div>
<div class="product-option">
<div class="qty"><input name="qty3" type="number" min="0" value="0"></div>
<div >Product Description 3</div>
</div>
</div>
<div class="image-options">
<div class="product-option">
<div class="qty"><input name="qty4" type="number" min="0" value="0"></div>
<div >Product Description 4</div>
</div>
<div class="product-option">
<div class="qty"><input name="qty5" type="number" min="0" value="0"></div>
<div >Product Description 5</div>
</div>
<div class="product-option">
<div class="qty"><input name="qty6" type="number" min="0" value="0"></div>
<div >Product Description 6</div>
</div>
</div>
</div>
</div>
</div>
Created a fiddle http://jsfiddle.net/narfie/g3gbqaxz/14/
Upvotes: 0
Views: 736
Reputation: 1894
Now I made an array of all the input elements by going through the first child of the element with class qty
. Made a single function to check changes to that element array. Added the onchange
to any higher ancestor
of the input element.
var inputs = new Array();
window.onload = function () {
var qtys = document.getElementsByClassName("qty");
for (var i = qtys.length - 1; i >= 0; i--) {
inputs[i] = qtys[i].children[0];
};
}
function check() {
for (var i = inputs.length - 1; i >= 0; i--) {
if(inputs[i].value>0){
inputs[i].classList.add("has-value");
}
else{
inputs[i].classList.remove("has-value");
}
};
}
Rest at fiddle : http://jsfiddle.net/1jcyhpyL/8/
Upvotes: 1
Reputation: 23492
Here is an example of using modern methods that handle most situations. You still have the problem where a value is changed programatically (even mutation observers do not handle this), as described by @RobG. But this should give a fair demonstration of the common situations.
function changeClass(e) {
var target = e.target || e;
if (target.nodeName === 'INPUT' && target.type === 'number') {
if (target.valueAsNumber > 0) {
target.classList.remove('noValue');
target.classList.add('hasValue');
} else {
target.classList.add('noValue');
target.classList.remove('hasValue');
}
}
}
[].forEach.call(document.querySelectorAll('input[type="number"]'), changeClass);
new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.type === 'childList') {
[].forEach.call(mutation.addedNodes, changeClass);
}
});
}).observe(document, {
attributes: false,
attributeOldValue: false,
characterData: false,
characterDataOldValue: false,
childList: true,
subtree: true
});
document.addEventListener('change', changeClass, false);
document.querySelector('[name="qty5"]').value = 1;
var newinput = document.createElement('input');
newinput.name = 'qty6';
newinput.type = 'number';
newinput.min = 0;
newinput.value = 1;
document.body.appendChild(newinput);
var qty4 = document.querySelector('[name="qty4"]');
qty4.value = 1;
changeClass(qty4);
.noValue {
background: red;
}
.hasValue {
background: yellow;
}
<input name="qty1" class="noValue" type="number" min="0" value="0">
<input name="qty2" class="noValue" type="number" min="0" value="0">
<input name="qty3" class="noValue" type="number" min="0" value="0">
<input name="qty4" class="noValue" type="number" min="0" value="0">
<input name="qty5" class="noValue" type="number" min="0" value="0">
Upvotes: 0
Reputation: 147453
I have a page that contains a whole bunch of input boxes of type number. These can be individually changed
For that you can use a change listener on each element. You could delegate to an ancestor, but the change event doesn't bubble in all browsers.
or a set of them can be changed by a selector.
If you change values by script, that will not cause a change event to be dispatched, so you can either manually call the listener, or dispatch your own change event (and make it bubble).
In modern browsers (probably IE 9+) you can do:
function changeInputClass(){
[].forEach.call(document.querySelectorAll('input[name^=qty]'), function(element) {
if (element.value > 0) {
element.classList.add('bold-text');
} else {
element.classList.remove('bold-text');
}
});
}
In less modern browsers (even IE 6) you can do:
function changeInputClass(){
var node, nodes = document.getElementsByTagName('input');
var nameRE = /^qty/;
for (var i=0, iLen=nodes.length; i<iLen; i++) {
node = nodes[i];
if (nameRE.test(node.name)) {
if (node.value > 0) {
node.className = 'bold-text';
} else {
node.className = '';
}
}
}
}
Upvotes: 0
Reputation: 214
<html>
<body>
<input name="qty1" type="number" min="0" value="0" onchange="changeInputClass(this)">
<input name="qty2" type="number" min="0" value="0" onchange="changeInputClass(this)">
<input name="qty3" type="number" min="0" value="0" onchange="changeInputClass(this)">
<input name="qty4" type="number" min="0" value="0" onchange="changeInputClass(this)">
<input name="qty5" type="number" min="0" value="0" onchange="changeInputClass(this)">
<script>
function changeInputClass(element) {
if (element.value > 0){
element.style.fontWeight = 'bold';
}
else {
element.style.fontWeight = 'normal';
}
}
</script>
</body>
</html>
Upvotes: 0