I have this code im making, and im wondering if i could prevent the localstorage from saving unless the required inputs in my form is filled out correctly. Right now the localstorage works with my submit button, but still saves if it gives me the "Please fill this field" message. Any help would be appriciated ! Here is the function i use to save the data.
let writeDate = () => {
if (isLocalStorageEnabled) {
$("confirmBtn").addEventListener("click", () => {
let getItem = localStorage.getItem('bookingDate');
let bookingDate = getItem ? JSON.parse(getItem) : [];
let bk = Object.assign({}, bookingInfo);
bk.name = $("fname").value;
bk.amount = $("famount").value;
bk.date = $("fdate").value;
bk.time = $("ftime").value;
bookingDate.push(bk);
let date = JSON.stringify(bookingDate);
localStorage.setItem("bookingDate", date);
});
};};
Toby, you can implement it as following.
I tried to keep variable name as same as your question.
html
<div>
<form onsubmit="return onSubmit(event)">
<label for="fname">Name:
<input type="text" id="fname" name="fname" required />
</label>
<label for="famount">Amount:
<input type="number" id="famount" name="famount" required />
</label>
<label for="fdate">Date:
<input type="date" id="fdate" name="fdate" required />
</label>
<label for="ftime">Time:
<input type="time" id="ftime" name="ftime" required />
</label>
<button type="submit">Confirm</button>
</form>
</div>
javascript
const onSubmit = (e) => {
e.preventDefault()
const prevBookingDate = localStorage.getItem('bookingDate');
let bookingDate = prevBookingDate ? JSON.parse(prevBookingDate) : [];
const { fname, famount, fdate, ftime } = e.target
const bk = {
name: fname.value,
amount: famount.value,
date: fdate.value,
time: ftime.value
};
bookingDate.push(bk);
let date = JSON.stringify(bookingDate);
localStorage.setItem("bookingDate", date);
}
Related
I have a form in HTML and I want to display the form text input data on the same page but before pressing the submit button.
Mean, When Users put the data in the form it must display below the form on same page.
It's mean that I want to show all data before submitting the form.
I know this code will not work as i want
var strText = document.getElementById("textone");
document.write(strText.value);
var strText1 = document.getElementById("textTWO");
document.write(strText1.value);
}
This is how I would do it by directly manipulating the DOM:
const input = document.getElementById('textInput');
const textElement = document.getElementById('displayText');
function updateValue(e) {
textElement.textContent = e.target.value;
}
input.addEventListener('input', updateValue);
<input type="text" id="textInput">
<p>value from input:</p>
<div id="displayText"></div>
There are also javascript libraries like VueJS and ReactJS that can help you do this more easily and efficiently.
This is an example of something like what you would want to do in VueJS: https://v2.vuejs.org/v2/examples/index.html
I've prepared an example of general functioning, I hope you like it. It may not be exactly what you want, but if it is, please tell me.
const myForm = document.getElementById("myForm");
const nameInput = document.getElementById("nameInput");
const emailInput = document.getElementById("emailInput");
const nameOutput = document.getElementById("nameOutput");
const emailOutput = document.getElementById("emailOutput");
let nameSpan = document.getElementById("name");
let emailSpan = document.getElementById("email");
myForm.addEventListener("submit", e => {
e.preventDefault();
alert(`NAME: ${nameInput.value}, EMAİL : ${emailInput.value}`)
// select name , mail
nameSpan.innerText = nameInput.value;
emailSpan.innerText = emailInput.value;
// clear ınputs
nameInput.value = "";
emailInput.value = ""
})
showData();
function showData() {
nameInput.addEventListener("keyup", e => {
nameOutput.value = e.target.value;
})
emailInput.addEventListener("keyup", e => {
emailOutput.value = e.target.value;
})
}
<form id="myForm">
<input type="text" id="nameInput" placeholder="your name">
<input type="text" id="emailInput" placeholder="your email">
<button type="submit" id="getInputValue"> Get Input Value </button>
</form>
<div id="values" style="margin-top: 100px;">
<input type="text" placeholder="NAME" id="nameOutput">
<input type="text" placeholder="EMAİL" id="emailOutput">
</div>
<div>
<p>Your name : <span id="name"></span></p>
<p>Your email : <span id="email"></span></p>
</div>
I have seen this method of serializing a form to JSON and it's working fine. My question is: How can I achieve this with pure JavaScript, without using any jQuery code? I am sorry if the question is dumb, but I'm still learning so if anyone can help me, I'll be grateful.
(function ($) {
$.fn.serializeFormJSON = function () {
var objects = {};
var anArray = this.serializeArray();
$.each(anArray, function () {
if (objects[this.name]) {
if (!objects[this.name].push) {
objects[this.name] = [objects[this.name]];
}
objects[this.name].push(this.value || '');
} else {
objects[this.name] = this.value || '';
}
});
return objects;
};
})(jQuery);
$('form').submit(function (e) {
e.preventDefault();
var data = $(this).serializeFormJSON();
console.log(data);
/* Object
email: "value"
name: "value"
password: "value"
*/
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post">
<div>
<label for="name">Name</label>
<input type="text" name="name" id="name" />
</div>
<div>
<label for="email">Email</label>
<input type="text" name="email" id="email" />
</div>
<div>
<label for="password">Password</label>
<input type="password" name="password" id="password" />
</div>
<p>
<input type="submit" value="Send" />
</p>
</form>
P.S.
Also in jQuery is this the right way to send multiple JSON objects from user input as One String, because I am searching for a way to do that?
You can try something like this:
function formToJson(){
var formElement = document.getElementsByTagName("form")[0],
inputElements = formElement.getElementsByTagName("input"),
jsonObject = {};
for(var i = 0; i < inputElements.length; i++){
var inputElement = inputElements[i];
jsonObject[inputElement.name] = inputElement.value;
}
return JSON.stringify(jsonObject);
}
This solution works only if you have a single form on the page, to make it more general the function could e.g. take the form element as an argument.
You can use Array.reduce, something like
// get array of all fields and/or selects (except the button)
const getFields = () => Array.from(document.querySelectorAll("input, select"))
.filter(field => field.type.toLowerCase() !== "button");
// get id, name or create random id from field properties
const getKey = field => field.name
|| field.id
|| `unknown-${Math.floor(1000 * Math.random()).toString(16)}`;
// get data, simple object
const getFormData = () => getFields()
.reduce( (f2o, field) => ({...f2o, [getKey(field)]: field.value}), {} );
// log the result
const logResult = txt => document.querySelector("#result").textContent = txt;
// get data, array of field objects
const getMoreFormData = () => getFields()
.reduce( (f2o, field) =>
f2o.concat({
id: field.id || "no id",
name: field.name || "no name",
idGenerated: getKey(field),
type: field.type,
value: field.value }
),
[] );
// handling for buttons
document.addEventListener("click", evt => {
if (evt.target.nodeName.toLowerCase() === "button") {
console.clear();
logResult(/simple/.test(evt.target.textContent)
? JSON.stringify(getFormData(), null, " ")
: JSON.stringify(getMoreFormData(), null, " ")
);
}
} );
<form action="#" method="post">
<div>
<label for="name">Name</label>
<input type="text" name="name" id="name" value="Pete"/>
</div>
<div>
<label for="email">Email</label>
<input type="text" name="email" id="email" value="pete#here.com"/>
</div>
<div>
<label for="password">Password</label>
<input type="password" name="password" id="password" />
</div>
<div>
<label>Field without name or id</label>
<input type="number" value="12345" />
</div>
</form>
<p>
<button>Data simple object</button> <button>Data fields array</button>
</p>
<pre id="result"></pre>
Remember that for checkboxes, value attribute can be either on or off string. This is unwanted. Here is my solution, based on this codepen.
let json = Array.from(form.querySelectorAll('input, select, textarea'))
.filter(element => element.name)
.reduce((json, element) => {
json[element.name] = element.type === 'checkbox' ? element.checked : element.value;
return json;
}, {});
OR
let json = {};
Array.from(form.querySelectorAll('input, select, textarea'))
.filter(element => element.name)
.forEach(element => {
json[element.name] = element.type === 'checkbox' ? element.checked : element.value;
});
OR (with typescript)
export type FormJson = {[key: string]: boolean | string};
export const toJson = (form: HTMLFormElement): FormJson =>
Array.from(form.querySelectorAll<HTMLFormElement>('input, select, textarea'))
.filter(element => element.name)
.reduce<FormJson>((json, element) => {
json[element.name] = element.type === 'checkbox' ? element.checked : element.value;
return json;
}, {});
To serialize your form you can do this (note that I added an onsubmit in the form tag):
HTML and JavaScript:
function serializeForm(e) {
e.preventDefault(); // prevent the page to reload
let form = e.target; // get the form itself
let data = new FormData(form); // serialize input names and values
let objSerializedForm = {}; // creating a new object
for (let [name, value] of data) { // iterating the FormData data
objSerializedForm[name] = value; // appending names and values to obj
}
console.log(objSerializedForm);
}
<form action="#" method="post" onsubmit="serializeForm(event)">
<div>
<label for="name">Name</label>
<input type="text" name="name" id="name" />
</div>
<div>
<label for="email">Email</label>
<input type="text" name="email" id="email" />
</div>
<div>
<label for="password">Password</label>
<input type="password" name="password" id="password" />
</div>
<p>
<input type="submit" value="Send" />
</p>
</form>
Than you can do whatever you want with your objSerializedForm, getting each value by calling objSerializedForm.name.
So, let's say I have an HTML form like this:
<form id="myForm">
<input type="text" name="dummy">
<input type="text" name="people[0][first_name]" value="John">
<input type="text" name="people[0][last_name]" value="Doe">
<input type="text" name="people[1][first_name]" value="Jane">
<input type="text" name="people[1][last_name]" value="Smith">
</form>
And I want to get a JavaScript array that matches the values of real. For example:
// If there was a sweet function for this...
var people = getFormDataByInputName( 'people' );
// Value of `people` is...
// [
// {
// 'first_name' : 'John',
// 'last_name' : 'Doe'
// },
// {
// 'first_name' : 'Jane',
// 'last_name' : 'Smith'
// }
// ]
Is there any easy way of doing that for just a specific form item (in this case, people)? Or would I have to serialize the entire form an then just extract the element I want?
I also thought of potentially using the following approach:
var formData = new FormData( document.querySelector( '#myForm' ) );
var people = formData.get( 'people' );
But that doesn't appear to work; people is just null after that.
You could do this with plain js using reduce method and return each person is one object.
const form = document.querySelectorAll('#myForm input');
const data = [...form].reduce(function(r, e) {
const [i, prop] = e.name.split(/\[(.*?)\]/g).slice(1).filter(Boolean)
if (!r[i]) r[i] = {}
r[i][prop] = e.value
return r;
}, [])
console.log(data)
<form id="myForm">
<input type="text" name="dummy">
<input type="text" name="people[0][first_name]" value="John">
<input type="text" name="people[0][last_name]" value="Doe">
<input type="text" name="people[1][first_name]" value="Jane">
<input type="text" name="people[1][last_name]" value="Smith">
</form>
function getObject(name, key) {
if(key.includes(name)) {
var splitStr = key.split(/\[|\]/g);
return {
index: splitStr[1],
key: splitStr[3],
}
}
return null;
}
function getFormDataByInputName(name) {
var formData = new FormData( document.querySelector('#myForm'));
var results = [];
for (var key of formData.keys()) {
var obj = getObject(name, key);
if (obj) {
if (results[obj.index]) results[obj.index][obj.key] = formData.get(key);
else results[obj.index] = { [obj.key]: formData.get(key) };
}
}
return results;
}
var people = getFormDataByInputName('people');
console.log(people);
<form id="myForm">
<input type="text" name="dummy">
<input type="text" name="people[0][first_name]" value="John">
<input type="text" name="people[0][last_name]" value="Doe">
<input type="text" name="people[1][first_name]" value="Jane">
<input type="text" name="people[1][last_name]" value="Smith">
</form>
Your code won't work because to HTML/JS name is just a string that it sends to the server when the form is submitted (the name in the name/value pairs). You might think it is arrays, but HTML/JS doesn't.
So no one-liner to get the job done. Try this: In your HTML, add <div class="name"> ...
(UPDATE: thanks for the idea, #Nenad, I've never tried one of these snippets)
var people = [];
$('.name').each(function() {
people.push({
first_name: $('input:nth-child(1)', this).val(),
last_name: $('input:nth-child(2)', this).val()
});
});
console.log(people);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="myForm">
<input type="text" name="dummy">
<div class="name">
<input type="text" value="John">
<input type="text" value="Doe">
</div>
<div class="name">
<input type="text" value="Jane">
<input type="text" value="Smith">
</div>
</form>
Use CSS attribute prefix selector, such as
form.querySelectorAll('[name^="people[]"]')
You can use a for-loop to get all peoples, as such
const MAX_PEOPLES = 2;
const list = [];
for (i = 0; i <= MAX_PEOPLES; i++) {
const eles = form.querySelectorAll(`[name^="people[${i}]`);
if (eles.length !== 2)
break;
list.push({
first_name: eles[0].value,
last_name: eles[1].value
});
}
that yields
[
{
"first_name":"John",
"last_name":"Doe"
},
{
"first_name":"Jane",
"last_name":"Smith"
}
]
I am having some trouble creating and getting a cookie with multiple values inside.
Okay, what I would like to do, is to create a cookie with a forms input values in it when a submit button is clicked. Then when the same user revisits the site, the form will be autofilled with what the user typed in last time.
My html:
<form id="formen">
<fieldset>
<legend>Login</legend>
<label for="firstname" class="label">Firstname</label>
<input type="text" name="firstname" id="firstname" class="text" maxlength="30" />
</br></br>
<label for="lastname" class="label">Lastname</label>
<input type="text" name="lastname" id="lastname" class="text" maxlength="30" />
</br></br>
<label for="lastname" class="label">Address</label>
<input type="text" name="third" id="address" class="text" maxlength="30" />
</br></br>
<label for="lastname" class="label">City</label>
<input type="text" name="city" id="city" class="text" maxlength="30" data-sayt-exclude/>
</br></br>
<label for="lastname" class="label">Zipcode</label>
<input type="number" name="zipcode" id="zipcode" class="text" maxlength="30" />
</br></br>
<label for="lastname" class="label">E-mail</label>
<input type="email" name="email" id="email" class="text" maxlength="30" />
</br></br>
<label for="lastname" class="label">Phone</label>
<input type="number" name="phone" id="phone" class="text" maxlength="30" />
</br></br>
<input type="submit" name="submit" value="Remember Me" id="remember"/>
</fieldset>
</form>
My javascript/jQuery:
$(document).ready(function () {
var date = new Date();
date.setTime(date.getTime() + (60 * 1000));
if ($("#remember").click(function () {
$.cookie('firstnameCookie', $firstnameVariable.val(), { expires: date });
$.cookie('lastnameCookie', $lastnameVariable.val(), { expires: date });
$.cookie('addressCookie', $addressVariable.val(), { expires: date });
$.cookie('cityCookie', $cityVariable.val(), { expires: date });
$.cookie('zipcodeCookie', $zipcodeVariable.val(), { expires: date });
$.cookie('emailCookie', $emailVariable.val(), { expires: date });
$.cookie('phoneCookie', $phoneVariable.val(), { expires: date });
}));
//set the value of the cookie to the element
var $firstnameVariable = $("#firstname").val($.cookie("firstnameCookie"));
var $lastnameVariable = $("#lastname").val($.cookie("lastnameCookie"));
var $addressVariable = $("#address").val($.cookie("addressCookie"));
var $cityVariable = $("#city").val($.cookie("cityCookie"));
var $zipcodeVariable = $("#zipcode").val($.cookie("zipcodeCookie"));
var $emailVariable = $("#email").val($.cookie("emailCookie"));
var $phoneVariable = $("#phone").val($.cookie("phoneCookie"));
});
This code actually does the trick. It saves the different input values, and autofills when user revisits the site.
The only problem is that I don't want to create a new cookie for each input value.
Is it possible to create just one cookie with each of the inputs values in it, and get it to autofill the different input fields?
Hope someone can help me! Can't figure it out..
Thx
Concatenate the form values into a string before saving the cookie and split when you have to assign it.
Those are functions I use to concatenate and split:
var splitQueryString = function (q) {
var pars = q.split("&");
var qq = {};
var i = 0;
for (i = 0; i < pars.length; i++) {
var ret = pars[i].toString().split("=");
qq[ret[0]] = decodeURIComponent(ret[1]);
}
return qq;
};
var getQueryString = function (pars) {
var q = '';
var value;
var key;
for (key in pars) {
if (pars.hasOwnProperty(key)) {
value = pars[key];
if (!(value === null)) {
q += "&" + key + "=" + encodeURIComponent(value);
}
}
}
if (q.length > 0) {
//remove first
q = q.substr(1);
}
return q;
};
Your code could become something like:
if ($("#remember").click(function () {
var pars = {};
pars.firstnameVariable = $firstnameVariable.val();
pars.lastnameVariable = $lastnameVariable.val();
var cookie = getQueryString(pars);
$.cookie('formCookie', cookie, { expires: date });
}));
//set the value of the cookie to the element
var pars = splitQueryString($.cookie("formCookie"));
var $firstnameVariable = $("#firstname").val(pars.firstnameVariable);
var $lastnameVariable = $("#lastname").val(pars.lastnameVariable);
Store the data by converting the object to a string
var obj = {
"firstname" : $("#firstname").val(),
"lastname" : $("#firstname").val()
};
$.cookie('data', JSON.stringify(obj), { expires: date });
And when you read it out:
var data = $.cookie("data"),
obj = data ? JSON.parse(data) : "";
Object.keys(obj).forEach(function(key){
$("#" + key).val(obj[key]);
});
Personally I would use localstorage and not a cookie.
I know how do that with Jquery http://jsfiddle.net/69UAT/ But can you help me with native JS.
jQuery:
$('.inputs').on('keyup',function(){
$(this).parent().not(this).find('.inputs').val($(this).val());
}
);
HTML:
<div>
<input type="text" class="inputs" value="hello">
<input type="text" class="inputs" value="John">
</div>
const inputs = document.querySelectorAll(".inputs");
inputs.forEach(input => {
input.addEventListener("keyup", e => {
let value = e.target.value;
inputs.forEach(input => input.value = value);
});
});