I want to use the "update" function that queries the current value of the slider, transfers it to
Meter. Span "Value: [current value]". If the current
value is at least 85, the indicator color should be set to #ffff00, otherwise the color is
#808080.
<form onchange="update();" oninput="update();">
<input type="range" name="power" min="0" max="100" value="0">
<br>
<span>value:0</span>
</form>
<meter id="output" value="88" low="85" max="100" optimum="85"> </meter>
<div class="indicator"></div>
<script>
function update() {
let indicatorColors = ['#808080', 'ffff00'];
// here I would have to access the indicator
let indicator =
// here I would have to access indicatorColors
indicator.style.backgroundColor =
}
</script>
<!-- css part -->
<style>
#output{
height: 20px;
width: 200px;
}
.indicator{
height: 50px;
width: 50px;
border-radius: 50%;
background-color: #808080;
position: absolute;
top: 40px;
left: 210px;
}
</style>
How to get the value?
In your html, add update to <input /> instead of <form /> as input is what actually changes.
pass this into update() function (update(this)). this here refers to the element itself that onchange() is called on, which is the <input />
Now, in your js code, you can access the input's value in update() function.
const valueCounter = document.querySelector(".value-counter");
const indicator = document.querySelector(".indicator");
function update(input) { // here the input parameter gets whatever u pass to update function in your html
const value = input.value;
valueCounter.textContent = `value:${value}`;
indicator.style.backgroundColor = value >= 85 ? "#ffff00" : "#808080";
}
.indicator { /* just to view the changes */
width: 50px;
height: 50px;
}
<input type="range" name="power" min="0" max="100" value="0" onchange="update(this)">
<br>
<span class="value-counter">value:0</span>
<div class="indicator"></div>
Related
I am having one link as 'Add more' which adds input element as many as I want. I want to call blur function on that.
Following html gets added while click on 'Add more' link:
<input required="" class="form-control js-validate-hoursToAdd timetoadd" step="0.01" name="calculations[settingIndex][hoursToAdd][calculationIndex]" type="number" value="">
Blur event works only for first element which is there in DOM by default. When I add new element, blur event doesn't get bind to the element.
Following is the javascript code.
$(document).ready(function() {
$(".timetoadd").blur(function(){
this.value = parseFloat(this.value).toFixed(2);
});
)};
It is in separate file called as backend.js. I am using webpack to minify the file and it is included in html file.
How to do that? Please help me out.
Use jQuery's on() method on a parent element with an additional selector as the second argument:
$(document).ready(function() {
$("#btnAdd").click(function() {
$('<br/><input required="" class="form-control js-validate-hoursToAdd timetoadd" step="0.01" name="calculations[settingIndex][hoursToAdd][calculationIndex]" type="number" value="">').appendTo(document.body);
});
$(document.body).on('blur', '.timetoadd', function(){
this.value = parseFloat(this.value).toFixed(2);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" id="btnAdd">Add more</button>
<br/><input required="" class="form-control js-validate-hoursToAdd timetoadd" step="0.01" name="calculations[settingIndex][hoursToAdd][calculationIndex]" type="number" value="">
Instead of document.body, you could also use any other parent that contains the inputs.
By adding the html attribute onblur and some javascript...
function myFunc(input) {
input.value = 0;
}
<input required="" class="form-control js-validate-hoursToAdd timetoadd" step="0.01" name="calculations[settingIndex][hoursToAdd][calculationIndex]" type="number" value="" onblur="myFunc(this)">
Here's an example I've made for you. Do this for your input. It should work fine
function GetValue(e){
alert(e.target.value);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="inputgroup">
<input type="text" name="Dynamic_0" onblur="GetValue(event)">
<input type="text" name="Dynamic_1" onblur="GetValue(event)">
<input type="text" name="Dynamic_2" onblur="GetValue(event)">
</div>
// find elements
var id = $("#id > div")
var id1 = $("#id1")
var input = $("input")
var inputCopy;
var button = $("button")
// handle click and add class
button.on("click", function() {
$('<input required="" class="form-control js-validate-hoursToAdd timetoadd" step="0.01" name="calculations[settingIndex][hoursToAdd][calculationIndex]" type="number" value=""><br>').appendTo(id);
/* addMore(e.currentTarget, e.currentTarget.value);
console.log('new input', e.currentTarget); */
})
$(document.body).on("blur", '.timetoadd', function() {
this.value = parseFloat(this.value).toFixed(2);
inputCopy = input;
})
function addMore(e, value) {
inputCopy = e.clone()
id.prepend($(inputCopy));
}
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#id {
background: #fff;
border-radius: 4px;
padding: 20px;
font-size: 25px;
text-align: center;
transition: all 0.2s;
margin: 0 auto;
width: 300px;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
#id.alt {
background: #0084ff;
color: #fff;
margin-top: 40px;
width: 200px;
}
#id.alt button {
background: #fff;
color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="id">
<button>Add more</button>
<div>
<input required class="form-control js-validate-hoursToAdd timetoadd" step="0.01" name="calculations[settingIndex][hoursToAdd][calculationIndex]" type="number" value="">
</div>
</div>
JSFiddle: https://jsfiddle.net/kutec/c4pvLoua/
I have made a color changer. but now I want to add a form to it.
if you change the dropdown it must show the color change directly.
what is the best way to do this?
Below I have added my code for the color changer
$im = b.gif;
$index = imagecolorclosest ( $im, 128,128,128); // old color
imagecolorset($im,$index,$color[0],$color[1],$color[2]); // new color
$imgname = "result.gif";
imagegif($im, $imgname ); // save image as gif
imagedestroy($im);
If you do not want to use <input type="color" />, you could use 3 <input type="range"> add change listeners to them and update the style of element you wish whenever one of them is changed. (The event change will trigger after you release the input, the event input will trigger whenever the value is changed, even if you are still holding the input). I made the coloring gets and sets using Object.defineProperty to make it easier to test.
["red", "green", "blue", "opacity"].forEach(function(colorType) {
Object.defineProperty(this, colorType, {
get: function() {
return +document.querySelector("#" + colorType).value;
}
});
document.querySelector("#" + colorType).addEventListener("input", onChange);
});
Object.defineProperty(this, "result", {
set: function(newColor) {
document.querySelector("#result").setAttribute("style", "background-color: rgba(" + newColor + ");");
}
});
onChange();
function onChange() {
result = [red, green, blue, opacity].join(", ");
}
#result {
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
<form id="result">
<input type="range" id="red" name="red" min="0" max="255" />
<input type="range" id="green" name="green" min="0" max="255" />
<input type="range" id="blue" name="blue" min="0" max="255" />
<input type="range" id="opacity" name="opacity" min="0" max="1" step="0.01" />
</form>
Object.defineProperty(this, "color", {
get: function() {
return document.querySelector("#color").value;
}
});
document.querySelector("#color").addEventListener("input", onChange);
Object.defineProperty(this, "result", {
set: function(newColor) {
document.querySelector("#result").setAttribute("style", "background-color: " + newColor + ";");
}
});
onChange();
function onChange() {
result = color;
}
#result {
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
<form id="result">
<input type="color" id="color" name="color" />
</form>
I have an audio element on a webpage and I need to add an id tag "player" to the element. I am using getElementById("player").
The element in quesiton:
<audio id="player" controls loop>
<source src="Out_of_the_Skies_Under_the_Earth.mp3" type="audio/mp3">
</audio>
I am using the 'player' tag to make the next two lines useful, using the Web Audio API:
var mediaElement = document.getElementById('player');
var sourceNode = context.createMediaElementSource(mediaElement);
This is the only place I am using the id 'player,' and I am open to any alternatives.
When I add the id tag the audio does not play in Chrome (it will play without the tag). It will play fine in Safari and Opera but not Chrome. I have tried bouncing the file to a smaller bit/sample rate, using .ogg, using getElementByClassName instead, but nothing seems to be working.
EDIT:
Also, I'd like to note that the player does show the correct length of the audio file (6:03) and it shows the progress bar moving and the time updating correctly. It's just as if the sound is muted.
This snippet isn't necessarily the exact problem I was having since my audio file is local.
Since posting this I have noticed that I get the error: 'MediaElementAudioSource outputs zeroes due to CORS access restrictions for [local file]' I think that hosting the file under my own domain with the required CORS header might fix the issue. I don't have time to implement this right now but I will update the post my solution in the answers below.
But in the mean time, any suggestions would be great.
var ctx = window.AudioContext || window.webkitAudioContext;
var context = new ctx();
var mediaElement = document.getElementById('player');
var sourceNode = context.createMediaElementSource(mediaElement);
// create the equalizer. It's a set of biquad Filters
var filters = [];
// Set filters
[60, 170, 350, 1000, 3500, 10000].forEach(function(freq, i) {
var eq = context.createBiquadFilter();
eq.frequency.value = freq;
eq.type = "peaking";
eq.gain.value = 0;
filters.push(eq);
});
// Connect filters in serie
sourceNode.connect(filters[0]);
for(var i = 0; i < filters.length - 1; i++) {
filters[i].connect(filters[i+1]);
}
// connect the last filter to the speakers
filters[filters.length - 1].connect(context.destination);
function changeGain(sliderVal,nbFilter) {
var value = parseFloat(sliderVal);
filters[nbFilter].gain.value = value;
// update output labels
var output = document.querySelector("#gain"+nbFilter);
output.value = value + " dB";
}
div audio {
display: block;
margin-bottom:10px;
}
.eq {
margin: 32px;
border:1px solid;
border-radius:15px;
background-color:lightGrey;
padding:10px;
width:300px;
box-shadow: 10px 10px 5px grey;
text-align:center;
font-family: "Open Sans";
font-size: 12px;
}
div.controls:hover {
color:blue;
font-weight:bold;
}
div.controls label {
display: inline-block;
text-align: center;
width: 50px;
}
div.controls label, div.controls input, output {
vertical-align: middle;
padding: 0;
margin: 0;
font-family: "Open Sans",Verdana,Geneva,sans-serif,sans-serif;
font-size: 12px;
}
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>Equalizer with Bi-Quad Filters</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<html lang="en">
<head>
</head>
<body>
<div class="eq">
<audio id="player" controls crossorigin="anonymous" loop>
<source src="https://vocaroo.com/i/s1lfs67BmoTC">
</audio>
<div class="controls">
<label>60Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 0);"></input>
<output id="gain0">0 dB</output>
</div>
<div class="controls">
<label>170Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 1);"></input>
<output id="gain1">0 dB</output>
</div>
<div class="controls">
<label>350Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 2);"></input>
<output id="gain2">0 dB</output>
</div>
<div class="controls">
<label>1000Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 3);"></input>
<output id="gain3">0 dB</output>
</div>
<div class="controls">
<label>3500Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 4);"></input>
<output id="gain4">0 dB</output>
</div>
<div class="controls">
<label>10000Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 5);"></input>
<output id="gain5">0 dB</output>
</div>
</div>
</body>
</html>
<script src="js/index.js"></script>
</body>
</html>
The URL set at <source> element src attribute is not served with CORS headers and is not an .mp3 file.
To avoid
MediaElementAudioSource outputs zeroes due to CORS access restrictions for <URL>
error, you can use fetch(), Body.blob() to fetch a resource which is served with Access-Control-Allow-Origin header, URL.createObjectURL() to convert the Blob to a Blob URL, then set the <audio> element src to the Blob URL.
Note also that <input> tag is self-closing; and filters should be defined globally.
var ctx = window.AudioContext || window.webkitAudioContext;
var context = new ctx();
var url = "https://ia600305.us.archive.org/30/items/return_201605/return.mp3";
var filters = [];
fetch(url)
.then(response => response.blob())
.then(blob => {
var blobURL = URL.createObjectURL(blob);
var mediaElement = document.getElementById('player');
mediaElement.src = blobURL;
var sourceNode = context.createMediaElementSource(mediaElement);
// create the equalizer. It's a set of biquad Filters
// Set filters
[60, 170, 350, 1000, 3500, 10000].forEach(function(freq, i) {
var eq = context.createBiquadFilter();
eq.frequency.value = freq;
eq.type = "peaking";
eq.gain.value = 0;
filters.push(eq);
});
// Connect filters in serie
sourceNode.connect(filters[0]);
for (var i = 0; i < filters.length - 1; i++) {
filters[i].connect(filters[i + 1]);
}
// connect the last filter to the speakers
filters[filters.length - 1].connect(context.destination);
});
function changeGain(sliderVal, nbFilter) {
var value = parseFloat(sliderVal);
filters[nbFilter].gain.value = value;
// update output labels
var output = document.querySelector("#gain" + nbFilter);
output.value = value + " dB";
}
div audio {
display: block;
margin-bottom: 10px;
}
.eq {
margin: 32px;
border: 1px solid;
border-radius: 15px;
background-color: lightGrey;
padding: 10px;
width: 300px;
box-shadow: 10px 10px 5px grey;
text-align: center;
font-family: "Open Sans";
font-size: 12px;
}
div.controls:hover {
color: blue;
font-weight: bold;
}
div.controls label {
display: inline-block;
text-align: center;
width: 50px;
}
div.controls label,
div.controls input,
output {
vertical-align: middle;
padding: 0;
margin: 0;
font-family: "Open Sans", Verdana, Geneva, sans-serif, sans-serif;
font-size: 12px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Equalizer with Bi-Quad Filters</title>
</head>
<body>
<div class="eq">
<audio id="player" controls crossorigin="anonymous" loop></audio>
<div class="controls">
<label>60Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 0);">
<output id="gain0">0 dB</output>
</div>
<div class="controls">
<label>170Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 1);">
<output id="gain1">0 dB</output>
</div>
<div class="controls">
<label>350Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 2);">
<output id="gain2">0 dB</output>
</div>
<div class="controls">
<label>1000Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 3);">
<output id="gain3">0 dB</output>
</div>
<div class="controls">
<label>3500Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 4);">
<output id="gain4">0 dB</output>
</div>
<div class="controls">
<label>10000Hz</label>
<input type="range" value="0" step="1" min="-30" max="30" oninput="changeGain(this.value, 5);">
<output id="gain5">0 dB</output>
</div>
</div>
</body>
</html>
I've been researching for a few days methods of controlling UI with checkboxes and with the help of some members on Stack' I've come really quite far. But my balding doesn't quite stop yet. I've been trying to further tweak my code snippet, by including a numeric value alongside my UI controller. (This value will be of use later inside the web-java applet.)
For example, when a checkbox is checked var total is ammended from 0 to 30. If a Checkbox is unchecked the value returns to '0'.
(Main Build JS Fiddle),
(Checkbox Example).
The second fiddle allows the use of data attributes, however these will need to be injected into the HTML via, JS. As like before I have 'NO' access to the CSS or HTML source files.
(Original Post)
- This post is a follow on from another question asked here on stack, due to the nature of the question changing, and the comments getting fairly confusing I was asked to open a new thread.
Below I'll post two snippets, one is of the original build, built with the aid of user #acontell. The other is an example of the type of result I am after, built with the aid of, user #Rajesh. Link to (Example Source).
The Base Build
// Control UI...
(function(domElements, cbState) {
// Number increment
var total = 0 + ' mm';
document.getElementById('adjvar').value = total;
function clickCallback() {
toggleElements(this.className);
}
function toggleElements(className, initialShow) {
var checkNumber = ((/ editoropt(\d*) /).exec(className))[1],
checkBox = document.getElementById('checkboxopt' + checkNumber),
division = document.querySelectorAll('.editoraccvar' + checkNumber)[0],
isShown = initialShow === undefined ? window.getComputedStyle(division).display === 'none' : initialShow;
division.style.display = isShown ? 'block' : 'none';
checkBox.checked = isShown;
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// increment count...
var val = 30;
total += (+val * (checkBox.checked ? 1 : -1));
document.getElementById('adjvar').value = total + ' mm';
document.getElementsByClassName('adjvar').value = checkBox.checked ? val : 0 + ' mm';
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
domElements
.filter(function(el) {
return el.className.indexOf('editoropt') !== -1;
})
.forEach(function(el, index) {
el.addEventListener('click', clickCallback, false);
toggleElements(el.className, cbState[index]);
});
})([].slice.call(document.querySelectorAll('.seq-box-form-field')), [false, false]);
// Default Checked...
if (document.getElementById('checkboxopt').checked) {
// do nothing
} else {
document.getElementById('checkboxopt').click();
}
// inject style
function ctSe() {
var css = "input[type='checkbox'] { float:left; margin-right: 1em !important;}",
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
console.log(head)
console.log(style)
console.log(css)
};
ctSe();
.editoraccvar {
width: 300px;
background: #f0f;
padding: .5em;
}
.editoropt {
width: 300px;
background: #0f0;
padding: .5em;
}
.editoraccvar1 {
width: 300px;
background: #0ff;
padding: .5em;
}
.editoropt1 {
width: 300px;
background: #ff0;
padding: .5em;
}
textarea {
display: block;
width: 95%;
resize: none;
padding: .5em;
}
<!-- I'm trying to hide & show this entire division... -->
<div class="seq-box-form-field field-summernote editoraccvar ">
<label for="accvar1">Ground Floor Info</label>
<div class="clearfix"></div>
<textarea id="richaccvar1" name="richaccvar1" class="summernote"></textarea>
<input type="hidden" name="accvar1" id="accvar1" value="" />
</div>
<!-- Using only what the system has supplied. -->
<div class="seq-box-form-field editoropt ">
<label for="opt1"><span style="padding-right: 10px; vertical-align: 1px;">Ground Floor </span>
<input type="checkbox" name="checkboxopt" id="checkboxopt" value="true" checked="true" />
<input type="hidden" name="opt1" id="opt1" value="true" />
</label>
</div>
<!-- Secondary Division -->
<div class="seq-box-form-field field-summernote editoraccvar1 ">
<label for="accvar1">First Floor</label>
<div class="clearfix"></div>
<textarea id="richaccvar1" name="richaccvar1" class="summernote"></textarea>
<input type="hidden" name="accvar1" id="accvar1" value="" />
</div>
<!-- Secondary Checkbox -->
<div class="seq-box-form-field editoropt1 ">
<label for="opt1"><span style="padding-right: 10px; vertical-align: 1px;">First Floor </span>
<input type="checkbox" name="checkboxopt1" id="checkboxopt1" value="true" checked="true" />
<input type="hidden" name="opt1" id="opt1" value="true" />
</label>
</div>
<input name="adjvar" id="adjvar" readonly>
The Example
(function() {
var total = 0;
function calculate(index) {
var el = document.getElementsByClassName('checkbox-input')[index];
var val = el.getAttribute("data-value");
total += (+val * (el.checked ? 1 : -1));
document.getElementById('pnvar').value = total;
document.getElementsByClassName('pnvar')[index].value = el.checked ? val : 0;
}
function registerEvents() {
var cbs = document.querySelectorAll('[type="checkbox"]');
[].forEach.call(cbs, function(cb, i) {
cb.addEventListener("click", function() {
calculate(i);
});
});
document.getElementById('pnvar').addEventListener('keydown', function(event) {
if (event.keyCode == 13) {
event.preventDefault();
return false;
}
})
}
window.addEventListener('load', function() {
registerEvents();
calculate(0)
})
})()
.editoropt {
font-family: Calibri, sans-serif;
width: 160px;
background: #f8f8ff;
padding: .5em;
border: solid 1px #ddd;
}
#checkboxopt {
float: left;
margin-right: 1em;
margin-top: 4px;
}
#checkboxopt1 {
float: left;
margin-right: 1em;
margin-top: 4px;
}
.pnvar {
width: 95%;
}
input:-moz-read-only {
/* For Firefox */
background-color: transparent;
border: none;
border-width: 0px;
}
input:read-only {
background-color: transparent;
border: none;
border-width: 0px;
}
<div class="seq-box-form-field editoropt ">
<label for="opt1">
<span style="padding-right: 10px; vertical-align: 1px;">Default 80mm </span>
<input type="checkbox" class="checkbox-input" data-value="80" name="checkboxopt" id="checkboxopt" value="true" checked />
<input type="hidden" name="opt1" id="opt1" value="true" />
</label>
</div>
<div class="seq-box-form-field editoropt ">
<label for="opt1">
<span style="padding-right: 10px; vertical-align: 1px;">Add 30mm </span>
<input type="checkbox" class="checkbox-input" name="checkboxopt1" data-value="30" id="checkboxopt1" value="true" />
<input type="hidden" name="opt2" id="opt2" value="true" />
</label>
</div>
<div class="editoropt">
<input id="pnvar" name="pnvar" placeholder="Null" onkeydown="" value="" class="required" type="text">
<input name="adjvar" class="pnvar" id="adjvar" readonly value="0">
<input name="adjvar" class="pnvar" id="adjvar2" readonly value="0">
</div>
As I mentioned in my previous post, I'm not a JS Whizz and I'm just finding my feet, however I am abitious to learn and further my knowledge. Any assistance would be greatly appreciated.
Note : All tags, classes and names, must remain the same for consistancy with another application.
I might be mistaken but I think that this two lines of code:
// Default Checked...
if (document.getElementById('checkboxopt').checked) {
// do nothing
} else {
document.getElementById('checkboxopt').click();
}
Could be avoided if you passed [true, false] as the initial states of the checkboxes:
([].slice.call(document.querySelectorAll('.seq-box-form-field')), [true, false]);
I might be wrong, you might be doing something else or the state of the page could require that click, I don't know.
Going back to the issue, if you want to increase/decrease by 30 when the checkbox is checked/unchecked, you could do as follows:
Create a function that retrieves the value of the input an updates it with a quantity added to it. The value of the input is a string of the form 'x mm' so a bit of tinkering is necessary to get the integer part of the value.
function updateInputValue(n) {
var actual = +document.getElementById('adjvar').value.split(' mm')[0] || 0;
document.getElementById('adjvar').value = (actual + n) + ' mm';
}
Inside toggleElement call this function in order to update the input value.
var increment = isShown ? 30 : -30;
updateInputValue(initialShow === undefined ? increment : +initialShow * 30);
It gets a bit complicated because you have to control the initial state of the inputs, but it's not that hard: if it's the initial state, initialShow is different from undefined so we transform the value (it's a boolean) into a number a multiply it by 30 (when it's checked, it'd be 1 * 30, when it's unchecked it'd be 0 * 30). When it's not the initial state, we increment/decrement depending on whether it's checked or not.
And here's the fiddle (I also commented out the part that clicked the checkbox). Hope it helps.
I posted a similar question yesterday, but this is new problem.
I have dynamically created Check Boxes on a page. On is the Parent Check Box and the rest are the child check boxes. Each Child Check Box is wrapped in a <div>. I have a drop down list. When I select an item from the list, the Check Boxes gets checked or unchecked. When the check box state changes, the <div> in witch it is wrapped background colour changes or when I check or uncheck it.
My problem. When I check/uncheck the parent check box it also checks/unchecks the child ones, but the background colour of the child check boxes' <div> does not change.
I need it to still work as it is currently working but also to have the new feature as required.
My Code:
1. CSS:
<style>
div.sch_cal_row {
margin-top: 0px;
margin-left: 0px;
width: 300px;
border-radius: 3px;
border-color: white;
height: 20px;
}
div.highlight {
width: 300px;
height: 20px;
background-color: #78EF5A;
/*background-color: #E0FBD9;*/
/*background-color: green;*/
}
div.high1 {
width: 300px;
height: 20px;
background-color: #F24F40;
/*background-color: #FFA07A;*/
/*background-color: red;*/
}
div.available {
width: 100px;
height: 46px;
background-color: #A8A69C;
}
</style>
2. JS:
<script type="text/javascript">
$(".childChk").each(function(){
check($(this));
});
$(".childChk").click(function () {
check($(this));
});
function check(chkElem) {
if (chkElem.is(':checked')) {
chkElem.parent().removeClass();
chkElem.parent().addClass("highlight");
} else {
chkElem.parent().removeClass("highlight");
chkElem.parent().addClass("high1");
}
}
</script>
3. HTML/Razor:
<div id="Priv">
#for (var i = 0; i < Model.Categories.Count; i++)
{
<div>
#Html.CheckBoxFor(m => Model.Categories[i].AllChecked, new { id = Model.Categories[i].CategoryID, #class = "parentChk" })
#Html.HiddenFor(m => Model.Categories[i].CategoryName)
<strong>#Model.Categories[i].CategoryName</strong>
<br />
#*#Html.JTDisplayTextFor(m => Model.Categories[i].CategoryName, "")*#
#for (var p = 0; p < Model.Categories[i].Privileges.Count; p++)
{
<div class="sch_cal_row">
#Html.HiddenFor(m => Model.Categories[i].Privileges[p].PrivilegeID)
#Html.HiddenFor(m => Model.Categories[i].Privileges[p].PrivilegeName)
#Html.CheckBoxFor(m => Model.Categories[i].Privileges[p].Checked, new { #class = "childChk" })
#Html.JTDisplayTextFor(m => Model.Categories[i].Privileges[p].PrivilegeName, "")
</div>
}
<br />
</div>
}
</div>
UPDATE as per comment:
<input class="parentChk" data-val="true" data-val-required="The AllChecked field is required." id="4" name="Categories[0].AllChecked" type="checkbox" value="true">
<input name="Categories[0].AllChecked" type="hidden" value="false">
<input id="Categories_0__CategoryName" name="Categories[0].CategoryName" type="hidden" value="Account">
<strong>Account</strong>
<br>
<div class="sch_cal_row high1">
<input data-val="true" data-val-number="The field PrivilegeID must be a number." data-val-required="The PrivilegeID field is required." id="Categories_0__Privileges_0__PrivilegeID" name="Categories[0].Privileges[0].PrivilegeID" type="hidden" value="8">
<input id="Categories_0__Privileges_0__PrivilegeName" name="Categories[0].Privileges[0].PrivilegeName" type="hidden" value="AccountAddEdit">
<input class="childChk" data-val="true" data-val-required="The Checked field is required." id="Categories_0__Privileges_0__Checked" name="Categories[0].Privileges[0].Checked" type="checkbox" value="true"><input name="Categories[0].Privileges[0].Checked" type="hidden" value="false">
AccountAddEdit<br>
</div>
This is only the parent and one child.
You right your javascript code in document.ready
$(document).ready(function(e) {
$(".childChk").each(function(){
check($(this));
});
$(".childChk").click(function () {
check($(this));
});
});
function check(chkElem) {
if (chkElem.is(':checked')) {
chkElem.parent().removeClass();
chkElem.parent().addClass("highlight");
} else {
chkElem.parent().removeClass("highlight");
chkElem.parent().addClass("high1");
}
}
Try this code...
$('.childChk').on("click", function(){
var thisParent = $(this).parent();
if(thisParent.hasClass("highlight")) {
thisParent.removeClass("highlight")
} else {
thisParent.addClass("highlight")
}
});