Why localStorage.clear() is not working inside function? - javascript

I created form where are filled data storaged to localstorage and I want to delete them if form is submitted. But it is not working inside this function.
If I use it outside of this function, it is working well.
What can be problem?
// Send formData to upload.php
form.on('submit', function() {
event.preventDefault();
if (checkFieldsIfNotEmpty() == true) {
var formDataFields = form.serializeArray(), // Get all data from form except of photos
count = Object.keys(data).length; // count fields of object
// Fill formData object by data from form
$.each(formDataFields, function(index, value) {
if (value.name === 'category' || value.name === 'subcategory' || value.name.indexOf('filter') >= 0) {
// do nothing
} else {
formData.append(value.name, value.value); // add name and value to POST data
}
});
// foreach - fill formData with category, subcategory and filters names/values from form
$('.add-item__input-select').each(function(index, value) {
formData.append($(this).attr('name'), $(this).attr('id'));
});
// foreach - fill formData with photos from form
$.each(data, function(index, value) {
formData.append('files[]', value);
});
uploadData(formData); // send data via ajax to upload.php
// Clear loaclstorage
window.localStorage.clear();
}
});
If I click on submit the it redirects me from form page to item page. and if I go back I can see data from localstorage again on fomr page. I added code which have some connection with localstorage. Maybe there is some problem. On form page is nothing important
/* SAVE FORM DATA TO LOCAL STORAGE - presistent - saved until submit is not clicked */
// The unload event is sent to the window element when the user navigates away from the page for ex. page refresh
$(window).on('unload', function() {
// Save values of form fields to local storage
$(':file, :checkbox, select, textarea, input').each(function() {
// Due to JS added input instead of select, need to get value from input + add to storage just checked items
if ( !$(this).hasClass('add-item__select') && !$(this).is(':checkbox') ) {
// Save value of field to local storage
localStorage.setItem($(this).attr('name'), $(this).val());
} else if ( $(this).is(':checked') ) {
// Save just name of checkbox which is checked
localStorage.setItem($(this).attr('name'), $(this).val());
}
})
});
// Get values form local storage if page is refreshed
$(window).on('load', function() {
// Save values of form fields to local storage
$(':file, :checkbox, select, textarea, input').each(function() {
// Set values for input elements
if ( !$(this).hasClass('add-item__select') && ( !$(this).is(':checkbox' ) && !$(this).is(':file') ) ) {
// Get value of field
fieldValue = localStorage.getItem($(this).attr('name'));
// Show value of field if fieldValue is not empty
if (fieldValue.length !== 0) {
// Fill value of element by value from from localstorage - all filled fileds must have class counted to be not conted again
$(this).val(fieldValue).addClass('black-text counted');
// Add label, bcz it is checked just on focusout event
$('<label class="add-item__form-label-JS">' + $(this).attr('placeholder') + '</label>').insertBefore($(this));
$('.add-item__form-label-JS').css({color: '#888'});
}
// Done action just for checkbox
} else if ( $(this).is(':checkbox') ) {
// Get value of field
fieldValue = localStorage.getItem($(this).attr('name'));
// All filled fileds must have class counted to be not conted again
// If chekcbox name is same as saved in local storage then set as checked
if ( fieldValue === $(this).val() ) {
$(this).prop('checked', true);
$(this).parent().parent().addClass('counted');
}
// Remove checkbox value in localstorage each time - bcz of change checked checkboxes
localStorage.removeItem(fieldValue);
}
})
});

You are saving when unloading the page.
To solve:
let submitting = false;
$(window).on('unload', function() {
if (!submitting) {
// Save values of form fields to local storage
form.on("submit", function(e) {
uploadData(formData); // send data via ajax to upload.php
// in PRINCIPLE you should move the clear AND setting submitting to the success of the ajax
// Clear localstorage
window.localStorage.clear();
submitting = true;
BUT
WHY are you redirecting in uploadData? WHY not just SUBMIT the form to the server and redirect in the response from the server using a header directive???

Related

Keep value after submit form

I have this category checkbox where if I select certain values it will display div size but also in the same time when I select the checkbox it will submit the form. The problem is if I add this.form.submit() , the code below won't work and the form won't submit the value, but if I don't add it, the code will work.
How do I display div size and submit the form at the same time?
function getIds(checkboxName) {
let checkBoxes = document.getElementsByName(checkboxName);
let ids = Array.prototype.slice.call(checkBoxes)
.filter(ch => ch.checked==true)
.map(ch => ch.value);
return ids;
}
$(".category").on('change', function() {
this.form.submit();
let catIds = getIds("category[]");
$.each(catIds, function(index, value){
if (value == '1' || value == '2') {
$("#size").show();
} else if (value == '3') {
$("#size").hide();
}
});
});
This sounds like a racing problem. The form gets put into a different thread by the browser and gets handled first before the rest of the javascript is able to finish.
A quick (but dirty) hotfix for me is usually to use the setTimeout() method.
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
That way the javascript can work it's magic and afterwards the form gets submitted.

Angular 1 component save current input values when clicking outside the input or other inputs

i am using angular material and have a modal that pops up with places where you can edit data, this inline editing area is created using a components. When user click the values, these values become editable and when user hit enter key the value get saved, when user hit esc key , modal get cancelled.
sometimes when an user click a value to edit, then accidentally proceed to click out side the modal or another value field without hitting enter, the data is not saving and user have to retype everything again. So i want a feature , when user click outside the modal while they are editing , data should get save automatically anyway or they clicked another value to edit without hitting enter on the current value ,data should save automatically
i have my attempt commented out in below code. The problem with my attempt is , 1) it doesn't save when clicking outside the modal, 2) it doesn't save the current edited value when clicking another value, it save only when clicking inside the same input field where i am editing the value.so it essentially only replaces enter key with click but doesnt give me any of the feature i described above.
if its possible, once a user click the value and the value become editable, anywhere else the user click should trigger the save the current entered values .
here is the component and controller code
component defined
let inlineEditComponent = {
restrict:'E',
bindings:{
identifier:"=",
value:"=",
onUpdate:"=",
display:"=",
valueName: "="
},
controller,
template
};
////controller
class InlineEditController{
constructor($scope, $element, $attrs,$timeout, $mdMedia){
"ngInject";
this.$scope = $scope;
this.$element = $element;
this.$attrs = $attrs;
this.$timeout = $timeout;
this.$mdMedia = $mdMedia;
}
$onInit = () => {
this.isEditing = false;
this._input = angular.element(document.querySelector('#inline-input-box'));
//handle when user hits enter
this.$element.bind("keydown keypress", (event) => {
if (event.which === 13) {
this.$scope.$apply(() => {
this.save();
});
event.preventDefault();
}
});
//handle when user hits esc
this.$element.bind("keydown keypress", (event) => {
if (event.which === 27) {
this.$scope.$apply(() =>{
this.cancel();
});
event.preventDefault();
}
//my attempt
// this.$element.bind("click", (event) => {
// this.$scope.$apply(() => {
// this.save();
// this.isEditing = true;
// });
// event.preventDefault();
// });
});
enableEditMode = (ev) => {
this.isEditing = true;
if(this.identifier == 'property'){
this.initDataTypeFields();
}
this.$timeout(() =>{
this._input[0].focus();
},100)
}
save = () => {
this._input.blur();
this.isEditing = false;
if (this.isTimestamp) {
this.value.value = moment(this.selectedDate).format("YYYY-MM-DDTHH:mm:ss");
}
if(this.isSelectValue){
this.value.value = this.selectedMultiValue.id;
this.valueNameMulti = this.selectedMultiValue.value;
}
this.onUpdate(this.value, this.display);
}

Getting default value of radio button upon page load using jQuery

I have two radio buttons whom I set to default (first selected value radio button is the default one upon load) like following:
var listing_type;
var shipping_location;
$(":radio[name='type'][value='1']").attr('checked', 'checked');
$(":radio[name='shipping'][value='1']").attr('checked', 'checked');
When the user clicks on some of the values from radio buttons, the values are caught like following:
$('input:radio[name=type]').click(function () {
listing_type = $(this).val();
});
$('input:radio[name=shipping]').click(function () {
shipping_location = $(this).val();
});
This 2nd part of the code works just fine, when the user clicks on some of the radio buttons, values are passed into my MVC Action just correctly.
However, I'm unable to catch the value if the user doesn't clicks anything on the radio buttons (i.e. leaves them as default as they are upon page load) and clicks "Search" Button...
The values in my MVC Action are always null for some reason, even though they aren't supposed to be. Here is how I'm passing the values and the here is the C# code from the Action:
$.post("/Search/Index", { keywords: $('.txtSearch').val(), type: /* listing_type */ <=> $('input[name=type]:checked').val(), location: $('input[name=shipping]:checked').val() <=> /*shipping_location*/ }, StartLoading())
.done(function (data) {
StopLoading();
var brands = $('<table />').append(data).find('#tableProducts').html();
$('#tableProducts').html(brands);
$('#tableProducts thead').show();
});
}
And this is the Action:
public ActionResult Index(string keywords, string type, string location)
{
// If the user doesn't interacts with the radio buttons and just enters the search term (ie. keywords) the type and location variables are null).
if ((keywords != null && keywords != "") && (type != null && type != "") && (location != null && location!=""))
{
// do something here....
}
return View();
}
So now my question is:
How can I pass the default values from the radio buttons if the user doesn't interacts with them (i.e. passing the default values I've set upon page load)???
Give this a try:
$('input:radio[name="type"]').filter('[value="1"]').attr('checked', true);
$('input:radio[name="shipping"]').filter('[value="1"]').attr('checked', true);

why the array reinitialized on every click?

I'm trying to push some numbers to an array, and then I want to assign the array to a hidden input to posted with a form.
On each click I am pushing a value to the array, but the array seems to be reinitialized on each click, so it stores the last pushed value only.
The full scenario:
open a popup modal contains a form (form loaded by ajax).
select a category, then the category items will be loaded by ajax too. (the shared code below is in this page).
click an item to get the full item details by ajax and load them in a div, and push the item ID to the array.
the array that stored the chosen items IDs will be assigned to a hidden input element.
So if the user choose another category, the items page will be reloaded, and this is the reason why the array is reinitialized each time.
$(document).ready(function(){
var added_items = [];
$('.items-list .one-item').click(function(e){
e.preventDefault();
if(added_items.indexOf($(this).attr('href')) < 0){
ajaxLoad('<?=Yii::$app->urlManager->createUrl('bookings/item'); ?>', $('.added-items'), {item:$(this).attr('href')}, true);
added_items.push($(this).attr('href'));
$('#added-items-list').val(JSON.stringify(added_items));
}
else{
alert("item already exist");
}
});
});
So how I can save the items IDs and post them with the form.
Three possible reasons
1.) form reloads page
2). if(added_items.indexOf($(this).attr("href")) < 0) returns false
3). Single .one-item element having $(this).attr("href"), see 2)
Utiltizing localStorage ; note, untested
$(document).ready(function() {
var added_items = localStorage.getItem("items") || [] ;
$('.items-list .one-item').click(function(e) {
e.preventDefault();
if (typeof added_items === "string") {
added_items = JSON.parse(added_items);
}
if (added_items.indexOf($(this).attr('href')) < 0) {
added_items.push($(this).attr('href'));
localStorage.setItem("items", JSON.stringify(added_items));
// note, not certain if page reloads here ?
// should $('#added-items-list').val(localStorage.getItem("items"));
// be called before `ajaxLoad` ?
ajaxLoad('<?=Yii::$app->urlManager->createUrl('
bookings / item '); ?>', $('.added-items'), {
item: $(this).attr('href')
}, true);
$('#added-items-list').val(localStorage.getItem("items"));
} else {
alert("item already exist");
}
});
});
Your code:
$(document).ready(function(){
var added_items = [];
...
}
seems located inside ajax loaded content so this code run every ajax call.
Your should move at least var added_items = []; outside of ajax reloaded content.
what I did (tested and worked successfully):
the form page :
$(document).ready(function(){
localStorage.clear();
...
$('form').on('submit', function(){
$('#added-items-list').val(JSON.stringify(localStorage["added_items"]));
});
});
the items page:
$(document).ready(function(){
var added_items = [];
if(localStorage.getItem("added_items")===null){
localStorage["added_items"] = JSON.stringify(added_items);
}
else {
// Parse the serialized data back into an array of objects
added_items = JSON.parse(localStorage.getItem('added_items'));
}
$('.items-list .one-item').click(function(e){
e.preventDefault();
if(added_items.indexOf($(this).attr('href')) < 0){
added_items.push($(this).attr('href'));
localStorage.setItem('added_items', JSON.stringify(added_items));
}
else{
alert("item already exist");
}
});

How to remember whether box is checked or unchecked (on click) with localstorage and also save a value?

Here is the jsfiddle: http://jsfiddle.net/nng6L/7/
So what I want to do is the following:
I want to set a value in localstorage, of 1 if box is checked, or 0 if box is unchecked
When page is reloaded, if box was checked then it stays checked, having fetched the value from localstorage
I want to be able to display either a 1 or a 0 in plain text, having fetched the aforementioned value from localstorage.
Here is my code, but it is not working (when page is reloaded, box is not checked; and null is returned instead of a 1 or a 0):
script.js
// here is to set item in localstorage when you click the check box.
vvvvvvv = document.getElementById('xxxx');
vvvvvvv.onclick = function() {
if(document.getElementById('xxxx').checked=true) {
localStorage.setItem('yyyyyyy', "1");
} else {
localStorage.setItem('yyyyyyy', "0");
}
}
// here is to fetch the item stored in local storage, and use that value
// to check or uncheck the box based on localstorage value.
zzzzzzz = localStorage.getItem('yyyyyyy');
if (zzzzzzz === null) {
localStorage.setItem('yyyyyyy', "0");
document.getElementById("xxxx").checked=false;
}
else {
if (zzzzzzz === "1") {
document.getElementById("xxxx").checked=true;
} else if (zzzzzzz === "0") {
document.getElementById("xxxx").checked=false;
}
}
output.js
// here is to output the value to the web page so we can know
// what value is stored in localstorage.
wwwwwwww = localStorage.getItem('yyyyyyy');
document.write(wwwwwwww);
page.html
<!-- here is the check box for which the scripts above are based from -->
<input type="checkbox" id="xxxx">Do you like summer?
<br><br>
<!-- here is where it will display the value from localstorage -->
<script src="output.js">
I removed some unnecessary bits of the script and tidied it a little and came up with this...
// here is to set item in localstorage when you click the check box.
vvvvvvv = document.getElementById('xxxx');
vvvvvvv.onclick = function() {
if(document.getElementById('xxxx').checked) {
localStorage.setItem('yyyyyyy', "1");
} else {
localStorage.setItem('yyyyyyy', "0");
}
}
// here is to fetch the item stored in local storage, and use that value
// to check or uncheck the box based on localstorage value.
zzzzzzz = localStorage.getItem('yyyyyyy');
console.log(zzzzzzz);
if (zzzzzzz === "1") {
document.getElementById("xxxx").checked=true;
} else {
document.getElementById("xxxx").checked=false;
}
Here's a working jsFiddle...
http://jsfiddle.net/nng6L/5/
Check the checkbox and refresh the page to see it work.
There are a couple of syntax errors in your code, which is why it is failing to store the value in localStorage. For example, here is one:
Equality operator in your onclick (== instead of =):
if(document.getElementById('xxxx').checked == true) {
or just:
if(document.getElementById('xxxx').checked) {
Another one:
Extra dangling { before the else as pointed out by dystroy.
Now it is working just fine:
See fiddle: http://jsfiddle.net/nng6L/6/
You did not fix the second! There was an extra { dangling before the else.

Categories