jQuery detect input change - javascript

I'm working on a feature where the user needs to be informed that there are unsaved changes in a form in case if they decide to navigate away from the page.
I am almost done but there's a tiny problem-
I am setting a boolean dirty on input change event.
The .change() event will detect any kind of change, as in it doesn't keep track of changes. For example, if an input field has the original value hello, which is modified to bye and back to hello, it will still set the dirty boolean.
Is there any way where I can take a backup of the form with initial values and then compare it with itself at every change event?

You need a way to serialize the form data into a JSON object, and then you could either compare the JSON object by iterating the properties or by comparing the JSON.stringify values.
I have slightly modified the method of objectifying the form data from here in order to do this.
var form = document.getElementById("myForm");
var originalFormData = objectifyForm(form);
var originalFormDataString = JSON.stringify(originalFormData);
setInterval(function() {
var formData = objectifyForm(form);
var formDataString = JSON.stringify(formData);
console.log("Form is dirty: " + (formDataString != originalFormDataString));
},1000);
function objectifyForm(formArray) {//serialize data function
var returnArray = {};
for (var i = 0; i < formArray.length; i++){
returnArray[formArray[i]['id']] = formArray[i]['value'];
}
return returnArray;
}
<form id="myForm">
<input id="myInput" value="test" type="text" />
</form>

You can do something like this. Remember this solution is just a sample. You have multiple input element, than use array/object to save there defaultValue.
var defaultValue = document.getElementById("myText").defaultValue;//Get the default value
var handleChange = function (){
let value = document.getElementById("myText").value;//get the current value
if(defaultValue===value){
console.log("dirty false")
}else {
console.log("Dirty True")
}
}
<input type="text" id="myText" value="abc" onkeyup="handleChange()">

I think you can create a javascript empty initial_values = {} object. initialised it with the default values in the form of key:value pairs. and if dirty boolean is set, it can be used to compare later on.

Related

Remove comma from an array element when element is empty

This is my HTML
<input type="text" class="date_of_birth" name="date[]" value="" onkeyup="dateOfBirth('stepbirth')">
<input type="text" class="date_of_birth" name="date[]" value="" onkeyup="dateOfBirth('stepbirth')">
Here is my javascript to collect the value for each element.
var DoB = [];
$(".date_of_birth").each(function(){
DoB.push($(this).val());
});
var newDob = DoB.slice(0,-1);
var stepVar = newDob;
It is working fine. When there are more values it sends values like this
20/02/2002,03/03/2003
which is fine.But the issue i have event on keyup on each input field. When the user fill in both fields and after if remove the data from one field then it sends values like this..
20/02/2002,
So my script stops validation here because of comma it expect the values like
20/02/2002,03/03/2003
or
20/02/2002
How can i remove comma here until input is empty.
Thanks
Instead of removing the commas, fix the problem at the source. The cause is due to the fact that you always push the value to the array even if the value is empty. To fix this, check the value before calling push().
var DoB = [];
$(".date_of_birth").each(function() {
var value = $(this).val().trim();
if (value.length)
DoB.push($(this).val());
});
Alternatively you can make this more succinct by using map(). If you return null, then the element will not be added to the array.
var DoB = $(".date_of_birth").map(function() {
return $(this).val().trim() || null;
});
You can use "toArray" and filter all elements with values:
var DoB = $(".date_of_birth").toArray().filter(function(el) {return $(el).val().trim();});
or using arrow function
var DoB = $(".date_of_birth").toArray().filter(el => $(el).val().trim());

Get value of all dynamically created hidden fields with class?

I would like to get the values of dynamically created hidden fields with a class reference.
Example of created hidden field
<input class="SelectedClaimants" id="CodesList_2__Claimant" name="CodesList[2].Claimant" type="hidden" value="Jason Statham">
This is something along the lines of what i have tried.
$('.listSelected').on('DOMSubtreeModified', function (event) {
$(".SelectedClaimants").find('input[type=hidden]').each(function () {
var testC += $(this).val();
});
});
I was aiming to have them create into an array object, but at the moment i am happy just to get the values out into a concatenated string.
Try this (the result is logged to the console). It's based onn Tushar's answer, but the selector was wrong.
$('input[type="hidden"].SelectedClaimants').map(function () {
return $(this).val();
}).get().join(',')
You can use .querySelectorAll(), spread element, for..of loop. Note, id, e.g., CodesList_2__Claimant should be unique in document.
var testC = [];
for (let el of [...document.querySelectorAll("input[type='hidden'].SelectedClaimants")]) {
testC.push(el.value)
}

Using form values javascript

I'm trying to access form data through a Javascript function when an input is 'changed'.
Currently I use something like this:
<form>
<input type="radio" name="type" name="myValue" onchange="myFunction(this.form)>
</form>
<script>
function myFunction(form) {
var value = form.type.value;
}
</script>
And it works, however instead of writing
var value = form.type.value;
I need to write something like this
var myArray = ["type"];
var value = form.myArray[0].value;
Which is not working. Is this due to how values in arrays are handled?
I have it here on JSFiddle if that is useful.
Thanks
Try
var value = form[myArray[0]].value;
form.myArray[0] is first getting the member myArray from form, and then trying to get the first item in that. Equal to (form.myArray)[0]
form[myArray[0]] explicitly says get the member from form which is of the name of the value inside myArray[0]
You can access properties of object using [] like this:
var value = form["type"].value;
// equivalent to:
var value = form.type.value
In your case this should work:
var myArray = ["type"];
var value = form[myArray[0]].value;
'myArray' is declared as a local variable but it is NOT form's property.
So form.myArray will fail.

Converting checkboxes to JSON array

I'm trying to serialize checkboxes on a form where several checkboxes will have the same name.
<input name="mycheckbox" type="checkbox" value="A"/>A</br>
<input name="mycheckbox" type="checkbox" value="B"/>B</br>
Using the serializeArray such as below everything works great. If both A & B are checked the JSON.stringify correctly represents the JSON as an array:
{"mycheckbox":["A","B"]}
However if I only have A checked the JSON is no longer represented as an array:
{"mycheckbox":"A"}
In my RESTful backend that's processing I need to consistently pass as an array. Is there any way of forcing stringify to represent it as an array?
var jsonData = JSON.stringify($('form').serializeObject());
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
You'll have to find each element within the form by name and check whether it's a checkbox.
But note that it's perfectly valid to have multiple text boxes, passwords, file uploads, etc. as well. Nothing defines a form input as being "multiple" in any way except the presence of two successful controls with the same name when you happen to look at the form.
It might be easier to just deal with this on the backend when you know you need an array. Or submit the form with plain old form encoding rather than JSON, and let your backend's HTTP library deal with it. (Most of them let you do something like request.GET.getall('mycheckbox') to always get a list back.)
If you do not want to modify the plugin's code directly, you can simply modify the object afterward.
var formData = $('form').serializeObject(),
mycheckboxVal = formData.mycheckbox;
if (!$.isArray(mycheckboxval)) {
formData.mycheckbox = [mycheckboxval];
}
//then you serialize
var jsonData = JSON.stringify(formData);
You could also perform the same logic server-side if you prefer.

jQuery form input into an array not working

I'm working on a game and there is a form input where the user enters the number of characters. Once this happens more inputs appear for each character's name. My problem right now is reading those names into an array.
When the new inputs are created also a new button called nameButton is created and that is my issue, when I attempt to click that nothing happens when the values should be stored in an array. I put a prompt at the end of the function just to check and that does not even get called.
If you all have any suggestions please let me know here is the jsFiddle
function nameRecording(names,$this){
var addRows='<tr id=newRows>';
for(var i =1; i<=names; i++)
{ var nearTr=$this.closest('tr');
addRows=addRows+'<td>Name one:</td><td><form><input type="text" name="charcItem" class = "newR"/></form></td>';
}
addRows=addRows+'<td><div class="button" id="nameButton"> Add! </div></td></tr>';
nearTr.after(addRows);
};
$('#nameButton').click(function(){
names=$(".newR").map(function(){
return $(this).val();
});
prompt(names);
});
And there are some of my functions.
Try this way:
$(".form").on('click', '#nameButton', function () {
names = $(".newR").map(function () {
return this.value;
}).get();
prompt(names);
});
You can use event delegation using on for dynamic elements
You need to do a .get() on .map() result to convert the collection object into array.
Demo

Categories

Resources