Local Storage form in HTML5 - javascript

I'm trying to store numbers into local storage for a type website with a type of shopping cart... I found examples where storing text/email works but when I try to store as numbers instead of text or change the form names it doesn't seem to work.
This is my form I made on the site to capture the data, followed by the javascript that should fill in saved data from another session, capture data, and (currently reset on submit) data.
<form id="localStorageCart" method="post" action="">
<label>Rooster:</label>
<input type="number" name="roosterQ" id="roosterQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Cow:</label>
<input type="number" name="cowQ" id="cowQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Cat:</label>
<input type="number" name="catQ" id="catQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Sheep:</label>
<input type="number" name="sheepQ" id="sheepQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Dumpster:</label>
<input type="number" name="dumpsterQ" id="dumpsterQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Dog:</label>
<input type="number" name="dogQ" id="dogQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<label>Horse:</label>
<input type="number" name="horseQ" id="horseQ" class="stored" min="0" max="99" step="1" value ="0" /><br>
<input type="submit" class="submitOrder" value="Submit" />
</form><br>
<br>
<script type="text/javascript">
$(document).ready(function () {
function init() { /* checks for stored data and fills in... */
if (localStorage["roosterQ"]) {
$('#roosterQ').val(localStorage["roosterQ"]);
}
if (localStorage["cowQ"]) {
$('#cowQ').val(localStorage["cowQ"]);
}
if (localStorage["catQ"]) {
$('#catQ').val(localStorage["catQ"]);
}
if (localStorage["sheepQ"]) {
$('#sheepQ').val(localStorage["sheepQ"]);
}
if (localStorage["dumpsterQ"]) {
$('#dumpsterQ').val(localStorage["dumpsterQ"]);
}
if (localStorage["dogQ"]) {
$('#dogQ').val(localStorage["dogQ"]);
}
if (localStorage["horseQ"]) {
$('#horseQ').val(localStorage["horseQ"]);
}
}
init();
});
$('.stored').keyup(function () { /* keyup runs when key is pressed in a form with "stored"... Write to LS */
localStorage[$(this).attr('name')] = $(this).val();
});
$('#localStorageCart').submit(function() { /* currently resets all LS data*/
localStorage.clear();
});
</script>

localStorage can only hold strings, therefore if you want to store numbers you need to type convert
var num = 1.5, str;
// Number to string, would be done implicitly by localStorage
str = num.toString();
// String to number
num = +str; // note nothing infront of the + sign.
// OR
// num = window.parseFloat(str,10); // or parseInt if you want integers
console.log(num, str);
// 1.5 "1.5"
or change the form names it doesn't seem to work
Are you updating your init, too? To avoid having to do this in the future, it should loop over .stored rather than get each individually by id.

If you still want to do it via localstorage, you might want to check json.stringify before storing the variables
var obj = { 'a': 1, 'b': 2, 'c': 3 };
localStorage.setItem('obj', JSON.stringify(obj));
What do you intent to do anyway? are you just trying to retain the field for next use or reload of page?
if so, you might want to try this plugin, Sisyphus
http://simsalabim.github.com/sisyphus/

Related

Iterate through N number of input boxes, updating each to their max value

Is there a way to give a bunch of inputs the same ID, and then iterate over them, when a checkbox is checked, and update their respective values to the MAX attribute? For example, with the following HTML:
CHECK ALL: <input type="checkbox" id="someIDname">
<input type="number" max="80" id="anotherIDname">
<input type="number" max="90" id="anotherIDname">
<input type="number" max="99" id="anotherIDname">
<input type="number" max="65" id="unrelated">
<input type="number" max="75" id="unrelated">
... and the JS is like this:
<script type="text/javascript">
$(document).ready(function() {
$('#someIDname').click(function(event) {
if(this.checked) {
$('#anotherIDname').each( function() {
var maxValue = $("#anotherIDname").attr("max");
document.getElementById("anotherIDname").value = maxValue;
});
}
});
});
</script>
I'd like to, when the checkbox is checked, have it fill in all of the MAX attributes from anything with the "anotherIDname" ID. (I'd then have three boxes, onewith 80, one with 90, one with 99. The other two are different IDs, so it would leave those alone.)
Total beginner with JS / jQuery here... The above script works on the 1st box, but does not update the others with the "anotherIDname" ID. (I thought maybe that ".each" would make it do them all, one at a time, but ... I guess that's not how it works. (I'm more of a PHP guy, normally, and that would be how something like this could maybe work if it was server-side.) Any thoughts appreciated.
There are few things wrong
id is always unique in the page.Same class is assigned to elements having same features
You should use $(this).val() to set the value
$(document).ready(function() {
$('#someIDname').click(function(event) {
if(this.checked) {
$('.anotherIDname').each( function() {
var maxValue = $(this).attr("max");
console.log(maxValue);
$(this).val(maxValue)
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" id="someIDname">
<input type="number" max="80" class="anotherIDname">
<input type="number" max="90" class="anotherIDname">
<input type="number" max="99" class="anotherIDname">
<input type="number" max="65" class="unrelated">
<input type="number" max="75" class="unrelated">
Added a class name and used querySelectorAll. Does this work as you want?
$(document).ready(function() {
$('#someIDname').click(function(event) {
if(this.checked) {
document.querySelectorAll('.max').forEach(a => {
a.value = a.max;
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
CHECK ALL: <input type="checkbox" id="someIDname">
<input type="number" max="80" id="anotherIDname" class="max">
<input type="number" max="90" id="anotherIDname" class="max">
<input type="number" max="99" id="anotherIDname" class="max">
<input type="number" max="65" id="unrelated" class="max">
<input type="number" max="75" id="unrelated" class="max">
The id must be unique in the page. So, you can't use same id in several places. However, you can use same class in several places.
So, you'll need to change the id to class for eg.:
<input type="number" max="80" class="maxinput" />
And to set the value from max attribute:
$('.maxinput').val(function() {
return $(this).attr('max')
});
However, I would suggest to use data-* instead of simple attribute:
<input type="number" data-max="80" class="maxinput" />
And get the data value:
$('.maxinput').val(function() {
return $(this).data('max')
});
But I am still in surprise why you aren't simply setting their values initially?
<input type="number" class="maxinput" value="80" />

Force input number decimal places natively

I'd like to force an <input type="number" step="0.01" /> to always have 2 decimals to enter accounting data.
I've managed to do that using JavaScript
document.getElementById('input').addEventListener('change', force2decimals);
function force2decimals(event) {
event.target.value = Number(Math.round(event.target.value * 100) / 100).toFixed(2);
}
<input type="number" step="0.01" id="input" value="1.00" />
Is there any way to handle this natively?
I know about the step attribute, the "duplicate answer" doesn't reply to my question.
It could be done by this:
document.getElementById('input').addEventListener('change', force2decimals);
function force2decimals(event) {
event.target.value = parseFloat(event.target.value).toFixed(2);
}
<input type="number" step="0.01" id="input" value="1.00" />
There is no way to do this "natively" in HTML5.
You can use this:
function force2decimals(event) {
var value = $(event).val();
var format_val = parseFloat(value).toFixed(2);
$(event).val(format_val);
}
<input type="number" step="0.01" id="input" onchange="force2decimals(this)" value="1.00" />
I hope this was helpful.

How to pass value of an input range to a variable in JS?

How do you get the value of an input range slider into a variable? Below is the range I'm using. Suppose I drag the range to 12, then I need "12" as the variable that I want to then pass to a function.
<input type="range" min="1" max="30" value="15" />
Edit: I don't want a button to confirm the value or something, I want that everytime the value is changed, it gets passed to the function, so it'll be dynamic!
PS: It may not be the best question out there, but I've honestly tried looking for an answer before posting the question.
You just need to bind to the change event:
<input type="range" min="1" max="30" value="15" />
$("input").change(function(){
var value = $(this).val();
alert(value);
})
If you give an id to your field:
<input id="myRange" type="range" min="1" max="30" value="15" />
then:
$('#myRange').val();
First step it is not really required, but it makes things easier.
You can do this in every form field element:
$('selector').val();
And you will get its value.
UPDATE FOR YOUR QUESTION:
Use .change event to bind a function that make whatever you want to do with this value, for example:
$('#myRange').change(function(){
var myVar = $(this).val();
alert(myVar);
});
Just use register an event on the input:
<input type="range" min="1" max="30" value="15" oninput="alert(this.value)" />
you could of course also call a function in the oninput field.
jsfiddle
<input id="field" type="range" min="1" max="30" value="15" />
var input = document.getElementById('field');
console.info(input.defaultValue); // value default (15)
input.onchange = function () {
console.info(input.value); // value change
};
You can do this simply by adding a listener to the field's input event, updating your variable every time it fires.
var input=document.querySelector("input"),
value=input.value;
console.log(value);
input.addEventListener("input",function(){
value=this.value;
console.log(value);
},0);
<input max="30" min="1" type="range" value="15">
Give the input an Id. Then use
For JQuery
Var a = $('#whateverId').val();
For JavaScript
Var a = getElementById('whateverID).innerHtml;

How to swap values by changing one of them via javascript?

There are three fields with numbers from 1 to 3. I am trying to make it so if a person uses only the arrows there should always be one "1", one "2", and one "3". Why is it not always working and how could I make it work?
jQuery(document).ready(function($) {
var prevNumber;
$(".numbers").focus(function() {
prevNumber = $(this).val();
}).change(function() {
curNumber = $(this).val();
$('.numbers[value="' + curNumber + '"]:not(:focus)').first().val(prevNumber);
prevNumber = curNumber;
});
});
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Here is a jsfiddle.
Why that approach doesn't work
The value attribute is not connected to the value of the input. I know that sound surprising. :-) The value attribute is the default value of the input. It doesn't change (unless you use setAttribute("value", x); or .defaultValue = x; to change it).
Your selector uses the attribute:
$('.numbers[value="' + curNumber + '"]')...
So it'll work on inputs whose value hasn't been changed by the user, but will fail once they have, selecting the wrong input.
How you could fix it
You could change the default value as well as the value by setting both defaultValue and value (being sure to update the defaultValue on the one that changed, too), like this (see comments):
jQuery(document).ready(function($) {
var prevNumber;
$(".numbers").focus(function() {
prevNumber = $(this).val();
}).change(function() {
// Get the element wrapper
var $this = $(this);
// Get the current value
var curNumber = $this.val();
// Make sure the default value on this element is updated
this.defaultValue = curNumber;
// Update both the value and default value on the other
// input that used to have this number
$('.numbers[value="' + curNumber + '"]:not(:focus)').first().val(prevNumber).prop("defaultValue", prevNumber);
prevNumber = curNumber;
});
});
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
What I'd do instead (maybe -- your approach is growing on me)
I think I'd approach it without trying to remember state, e.g., just in the change: Get the number of the one that changed, then assign any other numbers to its siblings. See the comments:
var numbers = $(".numbers").map(function() { return this.value; }).get();
jQuery(document).ready(function($) {
$(".numbers").change(function() {
// Get a wrapper for this input
var $this = $(this);
// Get this number
var thisNumber = $this.val();
// Get the unused numbers
var unused = numbers.filter(function(num) { return num != thisNumber; });
// Assign them to the siblings, in order
$this.siblings().val(function(index) {
return unused[index];
});
});
});
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I kept that general, rather than assuming the values would only be 1, 2, and 3 (and rather than assuming there'd only be three numbers).
The problem in your code is that the "value" attribute contains the initial value for the input. When you use the following selector:
$('.numbers[value="' + curNumber + '"]:not(:focus)')
you are selecting the element that initially had the given value, and not has this value now.
Try this selector instead, and all will work fine:
$('.numbers:not(:focus)').filter(function(index, element){
return $(element).val() == curNumber;
})
Here is a jsfiddle. ;)
I'd like to propose you a more elaborate solution that might help you as your application grows: you should store the JS value apart from the <input /> controlling it (this way, adding multiple <input>s or modifying the value from your code becomes easier. The most important thing is that you should have a single trusted data storage independent from the DOM that is always in a valid state (in this case: without duplicates).
Given your problem (the values should be unique and only swaps should be possible), it's easier to handle it as a pure JS problem (and do not try to do everything in jQuery - though I agree it's a great lib, it's not necessarily the best tool for everything).
Here is my commented solution:
jQuery(document).ready(function($) {
// This array the current values of the inputs
var numbers = [1, 2, 3];
// numbers should not be modified directly but trough
// setNumber: this function ensures that numbers is ALWAYS
// a swap of the original value ([1, 2, 3]).
// When a value is set, this function returns the previous
// index of the value
function setNumber(index, newVal) {
// find other index
var prevIndex = numbers.indexOf(newVal);
if (prevIndex < 0) {
alert('Invalid value, please enter 1, 2 or 3');
}
// swap
numbers[prevIndex] = numbers[index];
numbers[index] = newVal;
return prevIndex;
}
// This function updates the inputs to ensure
// that their displayed value match the one stored in numbers
function updateNumbersView() {
$(".numbers").each(function(idx, elem) {
elem = $(elem);
if (parseInt(elem.val(), 10) !== numbers[idx]) {
elem.val(numbers[idx]);
}
});
}
$(".numbers").change(function() {
var self = $(this);
var curNumber = parseInt(self.val(), 10);
var curIndex = $(".numbers").index(self);
if (curNumber === numbers[curIndex]) {
return false; // no change
}
// update model:
var changedIndex = setNumber(curIndex, curNumber);
// updateView:
$('.numbers').eq(changedIndex).val(numbers[changedIndex]);
// or to be more generic (ie. multiple inputs for the same value):
// updateNumbersView();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />
I would solve this by adding another property to each node.
jQuery(document).ready(function($) {
var $numbers = $('.numbers'),
off = false;
$numbers.each(function () {
this.prev = this.value;
});
$numbers.change(function () {
var source = this;
if (off) return; // this algorithm is already running
off = true;
$numbers.each(function () {
if (this !== source && this.value === source.value) { // if conflict
this.prev = this.value = source.prev; // swap with old value
}
});
this.prev = this.value; // update for next time
off = false; // re-enable
});
});
<input type="number" value="1" min="1" max="3" step="1" class="numbers" />
<input type="number" value="2" min="1" max="3" step="1" class="numbers" />
<input type="number" value="3" min="1" max="3" step="1" class="numbers" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

How to create slider with decimal values using html

I want to create a slider showing decimal values like 0.0 to 0.1 using html or html5.
Add step="0.1" in your input range tag like this: <input type="range" min="0.1" max="1.0" step="0.1" value="1"> Example:
document.getElementById("scale").oninput = function() {
document.getElementById("spanscale").innerHTML = this.value;
}
<input type="range" min="0.1" max="3.0" step="0.1" value="1" id="scale">Scale:<text id="spanscale" style="inline">1</text>
If you want to show a decimal place in integer numbers you can add this piece of code in the value output: Number(this.value).toFixed(1)
document.getElementById("scale").oninput = function() {
document.getElementById("spanscale").innerHTML = Number(this.value).toFixed(1);
}
<input type="range" min="0.1" max="3.0" step="0.1" value="1.0" id="scale">Scale:<text id="spanscale" style="inline">1.0</text>
It sounds like you want an input field that the user can click arrows to increment/decrement a value in steps of 0.1. If that's the case, you want to use an HTML5 numeric input element:
<input type="number" min="0" max="1" step="0.1" value="0.5" />
Find out more here at HTML5 Goodies.
As you precise HTML5, then you can use the new input type range :
<input type="range" name="things" min="1" max="10">
Demonstration
Be aware that it doesn't work on IE9-,though.
For setting this dynamically using JavaScript:
document.getElementById("my_slider").setAttribute("step", "0.1");

Categories