i am making simple HEX to RGB / RGB to HEX converter and I have problem updating values with range input. On manual input everything is how it should be but when I move slider value is not updated until I move other one or input something on the page. for example if you move slider to 255 (any color) it should result that color to be FF but I am getting FA until I move another one then first one change to FF. I also have number input that need to be sync with slider and maybe is problem between them.
HTML
<input type="range" min="0" max="255" class="rgb-slider" id="rgb-r-slider" spellcheck="false" value="255">
<input type="number" min="0" max="255" class="rgb" id="rgb-r" value="255">
JS
$('.rgb-slider').on('input change', function() {
$('#rgb-r').val($('#rgb-r-slider').val());
$('#rgb-g').val($('#rgb-g-slider').val());
$('#rgb-b').val($('#rgb-b-slider').val());
});
$('.rgb').on('input change', function() {
$('#rgb-r-slider').val($('#rgb-r').val());
$('#rgb-g-slider').val($('#rgb-g').val());
$('#rgb-b-slider').val($('#rgb-b').val());
});
and here is JSFiddle file
https://jsfiddle.net/9qynd4pn/9/
It's not opti but it work well ;)
$(function() {
$('.rgb-slider').on('input change', function() {
$(this).siblings(".rgb").val( $(this).val() );
updateHexaInput();
});
$('.rgb').on('input change', function() {
$(this).siblings(".rgb-slider").val( $(this).val() );
updateHexaInput();
});
});
var updateHexaInput = function() {
var str = "";
$('.rgb').each(function() {
str += parseInt($(this).val(), 10).toString(16);
});
$("#hex").val( str.toUpperCase() );
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<section id="color-converter" class="color-converter">
<!-- HEX Input -->
<div class="hex-group">
<input type="text" id="hex" spellcheck="false" value="FFFFFF"><span></span>
</div>
<!-- HEX Input End -->
<!-- RGB Input -->
<div class="rgb-group">
<p>R:
<input type="range" min="0" max="255" class="rgb-slider" id="rgb-r-slider" spellcheck="false" value="255">
<input type="number" min="0" max="255" class="rgb" id="rgb-r" value="255">
</p>
<p>G:
<input type="range" min="0" max="255" class="rgb-slider" id="rgb-g-slider" spellcheck="false" value="255">
<input type="number" min="0" max="255" class="rgb" id="rgb-g" value="255">
</p>
<p>B:
<input type="range" min="0" max="255" class="rgb-slider" id="rgb-b-slider" spellcheck="false" value="255">
<input type="number" min="0" max="255" class="rgb" id="rgb-b" value="255">
</p>
</div>
<!-- RGB Input End -->
</section>
</body>
Related
I'm totally learning here! I'm still playing with JS.
When checkbox is altered I want the range slider to be inactive AND the output to be zero.
function outputUpdate(obj) {
obj.previousElementSibling.value = obj.value;
}
function handleClick(obj) {
obj.previousElementSibling.value = obj.value;
}
<fieldset>
<legend><h3>Engine</h3></legend>
<output for="engine" id="engine">0</output>
<input id="engine" type="range" min="0" max="10" value="0" step="1" list="0-10" oninput="outputUpdate(this)">
<input type="checkbox" name="engine-closed" id="engine-closed" onclick='handleClick(this);' value="0" /><label for="engine-closed">Closed</label>
</fieldset>
I'm not sure how to make the range slider inactive / invisible on checkbox.
Then when unchecked make slider active / visible again.
Further, how to make the output zero when checkbox changes?
So far, with above code, slider works great and it updates output.
When checkbox checked the slider goes to zero as wanted, but not output.
edit: there are about 20 different form sliders with outputs. So it would be nice to use the id that called the function rather than declaring a var...
Remove all the inline javascript and use addEventListener instead.
Then you can just get the elements, bind the events in a loop, and reference the other elements by using this and getting the siblings etc.
var ranges = document.querySelectorAll('fieldset input[type=range]');
var boxes = document.querySelectorAll('fieldset input[type=checkbox]');
[].slice.call(ranges).forEach(function(range) {
range.addEventListener('input', function() {
this.previousElementSibling.value = this.value;
});
});
[].slice.call(boxes).forEach(function(box) {
box.addEventListener('change', function() {
var range = this.previousElementSibling;
var event = new Event('input');
range.value = 0;
range.dispatchEvent(event);
range.disabled = this.checked;
});
});
<fieldset>
<legend><h3>Engine</h3></legend>
<output for="engine" id="engine">0</output>
<input id="engine" type="range" min="0" max="10" value="0" step="1" list="0-10">
<input type="checkbox" name="engine-closed" id="engine-closed" value="0" />
<label for="engine-closed">Closed</label>
</fieldset>
Here, with minimal changes to your code :)
function outputUpdate(obj) {
obj.previousElementSibling.value = obj.value;
}
function handleClick(obj) {
obj.previousElementSibling.value = obj.value;
obj.previousElementSibling.disabled = obj.checked;
}
<fieldset>
<legend>
<h3>Engine</h3>
</legend>
<output for="engine" id="engine">0</output>
<input id="engine" type="range" min="0" max="10" value="0" step="1" list="0-10" oninput="outputUpdate(this)">
<input type="checkbox" name="engine-closed" id="engine-closed" onclick='handleClick(this); outputUpdate(this.previousElementSibling);' value="0" />
<label for="engine-closed">Closed</label>
</fieldset>
You can add the visibility toggle part if you want to.
If you're happy to put your checkbox before the range slider you can do this very simply with just CSS by using the Adjacent Sibling Selector and the :checked pseudo class to target sibling elements after a checked input:
function outputUpdate(obj) {
obj.previousElementSibling.value = obj.value;
}
function handleClick(obj) {
obj.previousElementSibling.value = obj.value;
}
#engine-closed:checked ~ #engine {display:none;}
<fieldset>
<legend><h3>Engine</h3></legend>
<input type="checkbox" name="engine-closed" id="engine-closed" onclick='handleClick(this);' value="0" />
<output for="engine" id="engine">0</output>
<input id="engine" type="range" min="0" max="10" value="0" step="1" list="0-10" oninput="outputUpdate(this)">
<label for="engine-closed">Closed</label>
</fieldset>
If you want a JS solution then simply toggle the elements visibility when the checkbox is set like so: (UPDATED to cope with multiple instances)
(function(){
function initWierdCloseRangeThingThatMakesNoSense(el){
var engine = el.querySelector("input[type='range']"),
output = el.querySelector("output"),
engineClosed = el.querySelector("input[type='checkbox']"),
setOutput = function(){
output.value = engine.value;
},
openClose = function(){
engine.style.display = (this.checked)?"none":"";
engine.value = "0";
setOutput();
};
engine.addEventListener("change", setOutput, false);
engineClosed.addEventListener("change", openClose, false);
};
// for every fieldset:
var fieldsets = document.querySelectorAll("fieldset");
for (i=0; i<fieldsets.length; ++i){
var fs = fieldsets[i];
initWierdCloseRangeThingThatMakesNoSense(fs);
}
})();
<fieldset>
<legend><h3>Engine</h3></legend>
<output for="engine" id="output">0</output>
<input id="engine" type="range" min="0" max="10" value="0" step="1" list="0-10">
<input type="checkbox" name="engine-closed" id="engine-closed" value="0" />
<label for="engine-closed">Closed</label>
</fieldset>
<fieldset>
<legend><h3>Engine 2</h3></legend>
<output for="engine2">0</output>
<input type="range" min="0" max="10" value="0" step="1" list="0-10">
<input type="checkbox" name="engine-2-closed" value="0" />
<label for="engine-3-closed">Closed</label>
</fieldset>
<fieldset>
<legend><h3>Engine 3</h3></legend>
<output for="engine3">0</output>
<input type="range" min="0" max="10" value="0" step="1" list="0-10">
<input type="checkbox" name="engine-3-closed" value="0" />
<label for="engine-3-closed">Closed</label>
</fieldset>
Better still, if you're going for a JS solution use #adeneo's because it's superior ;)
Essentially this:
function outputUpdate(obj) {
obj.previousElementSibling.value = obj.value;
}
function handleClick(obj) {
// grab the slider element (a.k.a. engine)
var engine = obj.previousElementSibling;
// grab the result element (a.k.a. output)
var output = engine.previousElementSibling;
// grab the checkbox's name
var checkBoxName = obj.name;
console.log('Name:', checkBoxName)
// these are both grabbed relative to the
// the checkbox, so you can have as many
// of these fieldsets as you want, and
// they will not interfere with each other.
// set the out to zero
output.value = 0
if (obj.checked) { // "closed" is checked
engine.disabled = true; // hide the slider
} else {
engine.disabled = false; // otherwise, show it
}
obj.previousElementSibling.value = obj.value;
}
<fieldset>
<legend><h3>Engine</h3></legend>
<output for="engine">0</output>
<input type="range" min="0" max="10" value="0" step="1" list="0-10" oninput="outputUpdate(this)">
<input type="checkbox" name="engine-closed" onclick='handleClick(this);' value="0" /> <label for="engine-closed">Closed</label>
</fieldset>
<fieldset>
<legend><h3>Dash / Console</h3></legend>
<output for="dask-console" id="dask-console">0</output>
<input id="dash-console" type="range" min="0" max="10" value="0" step="1" list="0-10" oninput="outputUpdate(this)">
<input type="checkbox" name="dash-console-closed" onclick='handleClick(this);' value="0"><label for="dash-console-closed">Closed</label>
</fieldset>
Is there a way to link the values of a <input type="range"> and an <input type="number">?
I would like to make changes to either the slider or to the numerical input and have both fields be updated. For some reason I have only been able to get an undefined value from the range element as of yet.
Here is my current JavaScript and HTML for this part of the document:
function updateTextInput1(val) {
alert(val);
document.getElementById('num1').value = val;
}
<input class="inputRange" type="range" min="0" max="100" onchange="updateTextInput1(this.val)" />
<input class="inputNumber" id="num1" min="0" max="100" type="number" value="0" />
It's not working because updateTextInput1(this.val) should be updateTextInput1(this.value):
function updateTextInput1(val) {
document.getElementById('num1').value = val;
}
<input class="inputRange" type="range" min="0" max="100" onchange="updateTextInput1(this.value)" />
<input class="inputNumber" id="num1" min="0" max="100" type="number" value="0" />
However, I'd suggest using unobtrusive JavaScript, though.
Just attach an input event to each element. In doing so, both elements will be in sync.
var range = document.querySelector('.inputRange');
var field = document.getElementById('num1');
range.addEventListener('input', function (e) {
field.value = e.target.value;
});
field.addEventListener('input', function (e) {
range.value = e.target.value;
});
<input class="inputRange" type="range" min="0" max="100" value="0" />
<input class="inputNumber" id="num1" min="0" max="100" type="number" value="0" />
Or you could use a more compact approach and select the sibling element:
document.querySelector('.inputRange').addEventListener('input', updateValue);
document.getElementById('num1').addEventListener('input', updateValue);
function updateValue (e) {
var sibling = e.target.previousElementSibling || e.target.nextElementSibling;
sibling.value = e.target.value;
}
<input class="inputRange" type="range" min="0" max="100" value="0"/>
<input class="inputNumber" id="num1" min="0" max="100" type="number" value="0" />
To display everytime the range or input text is changing you can use oninput and onchange on the input range, and also onkeypress and onchange on the input type text :
function updateTextInput1(val) {
val = val > 100 ? 100 : val;
val = val < 0 ? 0 : val;
document.getElementById('range').value = val;
document.getElementById('num1').value = val;
}
<input class="inputRange" id="range" type="range" min="0" max="100" oninput="updateTextInput1(this.value)" onchange="updateTextInput1(this.value)" />
<input class="inputNumber" id="num1" min="0" max="100" type="number" value="0" onkeypress="updateTextInput1(this.value)" onchange="updateTextInput1(this.value)" />
The error is: this.val instead of this.value
function updateTextInput1(val) {
alert(val);
document.getElementById('num1').value = val;
}
<input class="inputRange" type="range" min="0" max="100" onchange="updateTextInput1(this.value)" />
<input class="inputNumber" id="num1" min="0" max="100" type="number" value="0" />
You should bind event using js/jq. And to link both, you could target specific sibling element (or any other relevant transversal method):
$('.inputRange, .inputNumber').on('input', function(){
$(this).siblings('.inputRange, .inputNumber').val(this.value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input class="inputRange" type="range" min="0" max="100" value="0"/>
<input class="inputNumber" id="num1" min="0" max="100" type="number" value="0" />
I have a range in my html.....
Now my problem is that I want to print the value of the range back in my
html
This is the html for my range
<form oninput="amount.value=rangeInput.value">
<input type="range" id="rangeInput" name="rangeInput" min="0" max="100">
<output name="amount" for="rangeInput">0</output>
</form>
And i have a button to confirm the value
<div id="bevestig">
<h1>Bevestig</h1>
</div>
Has anyone an idea how to print the value of the range back in my html after you click on the h1?
You'll need to add some javascript to accomplish this.
document.getElementById("bevestig").addEventListener("click", function () {
var input = document.getElementById('rangeInput');
var output = document.getElementById('results');
output.innerHTML = input.value;
});
<form onchange="amount.value=rangeInput.value">
<input type="range" id="rangeInput" name="rangeInput" min="0" max="100" value="0" />
<output name="amount" for="rangeInput">0</output>
</form>
<div id="bevestig">
<h1>Bevestig</h1>
</div>
<p id="results"></p>
changeI have two numeric inputs and would like to limit the max or min of the second one based on the changes of the first one. So....
<input id="input1" type="number" min="0" max="10" value="5" change="OnChangeNumeric()" >
<input id="input2" type="number" min="0" max="10" value="1" >
<script>
function OnChangeNumeric() {
//how to actually change the values is where i am stuck
$('#input2').max = 5;
}
</script>
how to actually change the values is where i am stuck
Thanks for your suggestions
$(function() {
$('#input1').on('change',function() {
var thisVal = this.value;
/*calculate newMin, and newMax for #input2 according to your rules
based on thisVal ........
$('#input2').attr('min', newMin).attr('max', newMax);*/
console.log( $('#input2')[0] );
});
});
No need for inline JS:
<input id="input1" type="number" min="0" max="10" value="5"/>
<input id="input2" type="number" min="0" max="10" value="1"/>
JS FIDDLE DEMO
Currently, if you set the slider max value 100, when you type in 150 in the input box it automatically adjusts to 100.
I want the max value only applies to the slider bar but not the related input box, anyway I can do that?
updated...
after trying out a few options, this could be one solution
$(document).ready(function() {
$('.testSlider').bind('change', function() {
var val = $(this).val();
$(this).siblings('.testInput').val(val);
});
});
.ui-slider-input {
display: none !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input type="text" class="testInput" style="width:20px; float: left" />
<input type="range" class="testSlider" name="slider" id="slider-0" value="60" min="0" max="100" />
</div>
<div>
<input type="text" style="width:20px;float: left" class="testInput" />
<input type="range" class="testSlider" name="slider" id="slider-0" value="60" min="0" max="100" />
</div>