compare two arrays based on length: skip empty values - javascript

I have a form with 4 input (can be even many more) where the user can put a number or nothing. The only rule is that if you put a number in a input you cannot submit if the same number is in another input (no duplicates). You can submit with as many empty input as you want.
To validate the input I compare the length of the array of all the inputs with the same array with only unique values. If they have the same length it's ok.
I need to improve my code because now it works only if the user enters all the input fields. If some inputs are empty they are considered in the array with unique value as they all have "" as a value. So, if the user enters just one number I will get that array length is 4 and array unique is 2 but it should be 1 and 1 (skipping the blank items).
I was thinking about using splice() on arr, but is this the best way to do this validation?
**EDIT: I applied splice BUT if the array is ('1','','') my code gives me ('1','') instead of just (1) as I'd expect... ** This is because splice remove the item and change array length so that the for loop point to the wrong index.
Any idea?
HTML:
<div class="sez-form">
<fieldset>
<legend>Messaggi inclusi</legend>
<div class="percheckbox">
<input class="checkseq" type="checkbox" value="1" name="messaggio[0]">
Prova di messaggio che scorre<br>
<label>Ordine: </label>
<input class="seq" type="text" name="ordine[0]" maxlength="2" size="2">
</div>
<div class="percheckbox">
<input class="checkseq" type="checkbox" value="3" name="messaggio[1]">
Titoli di film<br>
<label>Ordine: </label>
<input class="seq" type="text" name="ordine[1]" maxlength="2" size="2">
</div>
<div class="percheckbox">
<input class="checkseq" type="checkbox" value="6" name="messaggio[2]">
Prova a testo fisso<br>
<label>Ordine: </label>
<input class="seq" type="text" name="ordine[2]" maxlength="2" size="2">
</div>
<br style="clear: both;">
</fieldset>
</div>
JAVASCRIPT:
function uniqueArray(arr) {
return $.grep(arr,function(v,k) {
return $.inArray(v,arr) === k;
});
}
$(document).ready(function() {
$('#invia').click(function(e) {
e.preventDefault();
var arr = $(".seq").map(function(){ return $(this).val(); }).toArray();
var empty = $(".seq").filter(function() {
return this.value == "";
})
for (index = 0; index < arr.length; ++index) {
if (arr[index]=='') {
new_arr = arr.splice([index],1);
}
console.log(arr);
}
if(empty.length == $('.seq').length) {
alert('Non hai scelto alcun messaggio per il workflow. Correggi per procedere.');
}
else if(uniqueArray(arr).length != $('.seq').length) {
console.log(uniqueArray(arr));
alert('Ci sono voci duplicate nella sequenza. Correggi per procedere.');
}
else if($('#dt_from').val()=='__/__/____ __:__') {
alert('Scegli data e ora di inizio validit\u00E0 per il workflow');
}
else if($('#dt_to').val()=='__/__/____ __:__') {
alert('Scegli data e ora di fine validit\u00E0 per il workflow');
}
else {
ajaxSubmit();
}
});
});

Here is another possible way to handle it. Here is the working JSFiddle. And here is the code:
$(function() {
$("#submit").click(function() {
//build a profile of the inputs
var inputs = [];
var values = [];
var dups = false; //track duplicates on pass 1
$(".seq").each(function(i, el) {
var empty = (el.value == ""); //check if empty
var exists = (!empty && $.grep(inputs, function(item, index) {
return (item.Value === el.value);
}).length > 0); //check if exists
dups = (dups || exists); //track dups
//add the new input item
var obj = {
Element: el,
Value: el.value,
Empty: empty,
Exists: exists
};
inputs.push(obj);
//conditionally add the sorting value
if (!empty && !exists)
values.push(el.value);
});
//Validate the inputs. If there are duplicates, don't submit
$(".seq").css("background-color", "white"); //clear errors
if (dups) {
$(inputs).each(function(i, el) {
if (el.Exists)
el.Element.style.backgroundColor = "red";
});
} else {
values = values.sort();
alert(values);
}
});
});
With this method, at the end you have an array - inputs - of all of the elements with their statuses so that you can provide error handling on specific fields. In my example, the error fields turn red.
At the alert, you have a sorted array of the valid values.

Maybe I don't understand what you are trying to do, but why can't you do it very simply with something like:
$('#invia').click(function(e) {
e.preventDefault();
var unique = [], nonunique = [];
$(".seq").each(function(index){
var val = $(this).val();
if (val !== "") {
if ($.inArray(val, unique) !== -1) {
nonunique.push(val);
} else {
unique.push(val);
}
}
});
// If unique and nonunique are empty, all inputs were blank
// else if nonunique is empty, inputs are valid and in unique
});

Use a hash to track values as you iterate. This example simply returns true or false, but you could also scan the entire array and return the repeated values.
function uniquifyArray(ary) {
var seen = {};
var isUnique = true;
/* iterate backwards since the array length will change as elements are removed */
for (var i=ary.length; i--;) {
/* remove blank/undefined */
if (typeof ary[i] === 'undefined' || ary[i] === '') {
ary.splice(i,1);
} else {
/* check if this value has already been seen */
if (ary[i] in seen) {
isUnique = false;
ary.splice(i,1);
} else {
seen[ary[i]]=true;
}
}
}
ary = ary.sort();
return isUnique;
}
var test = [ '1','2','','','3','4','1' ];
uniquifyArray(test); // returns false, test = [ '1','2','3','4' ]
test = [ '1','2','','' ]
uniquifyArray(test); //true, test = ['1','2']

Related

Remove specific array from multiple array set using jquery

I have two checkboxes. When I check one, the code will get status and id of that checkbox and push into array, if that value is not present already
The array set become like this
[8,0] [10,0]
Requirements:
It is inserting [8,0] [8,0] twice if I check and then uncheck and again check it so this should not insert multiple times same values
Remove specific array from set of array so if I uncheck chkecbox then remove only [8,0] but keep [10,0]
var positions = [];
$("body").on('click', '.check_box', function() {
var id = $(this).attr('data-id');
var status = $(this).attr('data-status');
if ($(this).prop("checked") == true) { // if click on check
if (!$.inArray(id, positions)) positions.push(id); // if id and status not in array then only push
positions.push([id, status]); // it will insert like [8,10] but geting duplicate [8,10] [8,10]
console.log(positions);
} else {
// if uncheck checkbox
// remove specific value like [8,0] or if value present [10,0] then remove this
console.log(positions);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" class="check_box" data-id="8" data-status="0">
<input type="checkbox" class="check_box" data-id="10" data-status="0">
You can use indexOf to check if object is present in array & add only if it doesn't exist
For removing, you can use filter & select only those objects in array which are not exactly as you specify
var positions = [];
$("body").on('click', '.check_box', function() {
var id = $(this).attr('data-id');
var status = $(this).attr('data-status');
if ($(this).prop("checked") == true) {
var exists = false;
positions.forEach((p) => {
if (id == p[0] && status == p[1]);
exists = true;
});
if (!exists) {
positions.push([id, status]);
}
} else {
positions = positions.filter(function(a) {
return !(a[0] == id && a[1] == status);
});
}
console.log(positions);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" class="check_box" data-id="8" data-status="0">
<input type="checkbox" class="check_box" data-id="10" data-status="0">
Explanation
In The first loop .each we iterate through each existing values in array & set exist to true when we find an element which has id & status same as the one we selected
If after loop we have exist as true, we know it already exists & we won't push it to array, otherwise we will push it to the array
In else condition we have used filter function of array, this fuction filters the array & only keep the elements for which we returned true, for elements we return false, it gets removed from resulting array
So we did check every element of array for exact match of id & status & if its matched we return false, so it gets removed from the resulting array
I will use findIndex and splice to handle it, hope this can help you :)
$(function() {
let positions = [];
$("body").on('click', 'input:checkbox', function() {
let id = $(this).attr('data-id');
let status = $(this).attr('data-status');
let data = [id, status];
if ($(this).is(':checked')) {
positions.push(data);
} else {
let index = positions.findIndex(c => c[0] === id);
if (index != -1)
positions.splice(index, 1);
}
$('#result').html(positions.toString());
});
});
#result{
width: 20rem;
height: 1rem;
margin-top: 2rem;
border-width:3px;
border-style:dashed;
border-color:#FFAC55;
padding: 15px 20px;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<input type="checkbox" data-id="A" data-status="0">A</button>
<input type="checkbox" data-id="B" data-status="0">B</button>
<div id="result"></div>
</body>
</html>
If the array is small, just recreate it each time
let positions;
$("body").on('click', '.check_box', function() {
positions = [];
$(".check_box:checked").each(function() {
positions.push([
$(this).data('id'), $(this).data('status')
]);
});
console.log(positions);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" class="check_box" data-id="8" data-status="0">
<input type="checkbox" class="check_box" data-id="10" data-status="0">

JavaScript validate at least one radio is checked

I'm building a tabbed for using a mixture of JavaScript and CSS. So far I have validation on my text inputs that ensure a user can't progress unless data has been input.
I have got it working so that my script detected unchecked radios, but the problem is that I want the user to only select one. At the moment even when one gets selected the script won't let you progress because it's seeing the other three as unchecked. How could I add a rule to look at the radios and set valid = true if one is selected - if more or less than 1 then fail?
my function:
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, valid = true;
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
// A loop that checks every input field in the current tab:
for (i = 0; i < y.length; i++) {
// If a field is empty...
if (y[i].type === "text") {
if (y[i].value == "") {
// add an "invalid" class to the field:
y[i].classList.add('invalid');
// and set the current valid status to false:
valid = false;
} else if (!y[i].value == "") {
y[i].classList.remove('invalid');
valid = true;
}
}
if (y[i].type === 'radio') {
//y[i].classList.remove('invalid');
//valid = true;
if (!y[i].checked) {
y[i].classList.add('invalid');
valid = false;
} else {
y[i].classList.remove('invalid');
valid = true;
}
}
}
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("step")[currentTab].className += " finish";
}
return valid; // return the valid status
}
Do I need to split the validation down into further functions to separate validating different field types?
I think that radio buttons are the way to go. Especially from a UI point of view. Why would you let the user pick more than one item only to tell them later they can't?
Having said that, you can do what you're trying to do with something like this:
function validateForm() {
var checkBoxHolders = document.querySelectorAll(".checkboxholder");
var valid = true;
for (var i = 0; i < checkBoxHolders.length; i++) {
var numChecked = checkBoxHolders[i].querySelectorAll("input[type='checkbox']:checked").length;
if (numChecked === 1) {
checkBoxHolders[i].classList.remove('invalid');
} else {
checkBoxHolders[i].classList.add('invalid');
}
valid = valid && numChecked === 1;
}
document.getElementById('valid').innerHTML = 'I am valid: ' + valid;
}
.invalid {
background-color: orange;
}
<input type="text" id='foo'>
<input type="text" id='bar'>
<div class='checkboxholder'>
First group
<input type="checkbox" id='check1'>
<input type="checkbox" id='check2'>
</div>
<div class='checkboxholder'>
Second group
<input type="checkbox" id='check3'>
<input type="checkbox" id='check4'>
</div>
<button type='button' onclick='validateForm()'>Validate me</button>
<div id='valid'>
</div>
With jQuery, it'd be something like:
if (jQuery('input[name=RadiosGroupName]:checked').length === 0) {
valid = false;
}

check two input element's names are different or not using javascript

I have an array in which the values of check boxes gets stored on user click. Now I need to use an if loop for a particular logic in my code to give a condition whether the elements inside the array have same name (group check box name) or different names. How can I do it in javascript or jquery?
var Array = ['bob','bob','smith','smith','john','john'];
var UniqueArray = new Array();
var obj = {};
$.each(Array , function(i,value) {
if(!obj[value]) {
obj[value] = true;
UniqueArray.push(value)
}
})
Are you expecting something like this.
$(function() {
// create an array.
var elements = [];
// click event for all input of type checkbox.
$('[type="checkbox"]').on("click", function() {
// restrict no. of items to be inserted into the array to 2
if (elements.length <= 2) {
// push each element to array.
elements.push($(this));
}
// compare name attribute of 1st and 2nd element in array.
if (elements.length == 2) {
if (elements[0].attr('name') == elements[1].attr('name')) {
alert('elements with same name');
} else {
alert('elements with differnt name');
}
//clear all elements from array.
elements = [];
//clear all checkbox.
$('input:checkbox').removeAttr('checked');
}
// if you want to iterate through array use $.each
/*$.each(elements,function(index,data){
alert(data.attr('name'));
});
*/
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
first checkbox - :"myCheckBox":
<input type="checkbox" name=myCheckBox id="cbxCustom1" />
<br>second checkbox - :"myCheckBox":
<input type="checkbox" name=myCheckBox id="cbxCustom2" />
<br>third checkbox - :"myCheckBoxNew":
<input type="checkbox" name=myCheckBoxNew id="cbxCustom3" />

Javascript Count number of time same value repeated in the textbox(s)

The below code add as yes if the master class text box value matches with the user but i want to compare the master with the user class and print the number count result in a div of how many input user class have the same repeated value of as master has.
Html:
<input class="master" value="1">
<input class="user" value="1">
<input class="user" value="1">
<input class="user" value="0">
<input class="user" value="0">
<div id="result_count"></div>
Javascript:
$(function() {
var master = $('input.master').get(0).value; // get the master value
var fn = function() {
return this.value === master ? "yes" : "no";//if current text-box matches master,then yes else no
};
$('input.user').val(fn); // loop and replace text for each user input
});
You should use the attribute selector based on the master input's value:
$(function() {
var master = $('input.master').val(); // get the master value
var userInputs = $('input.user');
var fn = function() {
return this.value === master ? "yes" : "no";//if current text-box matches master,then yes else no
};
userInputs.val(fn); // loop and replace text for each user input
// get inputs who has the same value as "master"
var inputs = userInputs.filter( 'input[value="'+ master +'"]' )
// Print the number of matches
console.log( inputs.length )
});
An example: http://jsfiddle.net/gjangztm/
This should do the job: http://codepen.io/zvona/pen/qOqKJe?editors=101
var masterValue = $('.master').val();
var $userInputs = $('.user');
var resultCount = $userInputs.filter(function(i, input) {
return $(input).val() === masterValue;
});
$('#result_count').text(resultCount.length);
$(function() {
var count=0;
var master = $('input.master').get(0).value; // get the master value
var fn = function() {
return this.value === master ? "yes" : "no";//if current text-box matches master,then yes else no
};
$('input.user').val(fn);
$(".user").each(function() {
if($(this).val()==master ){
++count;
}
});
$('#result_count').val(count);
});
var same = $('input.user').filter(function( index ) {
return ($(this).val() == $('.master').val());
})
console.log(same.length);
$('#result_count').text(same.length);
demo
Documentation for more information

Generic way to detect if html form is edited

I have a tabbed html form. Upon navigating from one tab to the other, the current tab's data is persisted (on the DB) even if there is no change to the data.
I would like to make the persistence call only if the form is edited. The form can contain any kind of control. Dirtying the form need not be by typing some text but choosing a date in a calendar control would also qualify.
One way to achieve this would be to display the form in read-only mode by default and have an 'Edit' button and if the user clicks the edit button then the call to DB is made (once again, irrespective of whether data is modified. This is a better improvement to what is currently existing).
I would like to know how to write a generic javascript function that would check if any of the controls value has been modified ?
In pure javascript, this would not be an easy task, but jQuery makes it very easy to do:
$("#myform :input").change(function() {
$("#myform").data("changed",true);
});
Then before saving, you can check if it was changed:
if ($("#myform").data("changed")) {
// submit the form
}
In the example above, the form has an id equal to "myform".
If you need this in many forms, you can easily turn it into a plugin:
$.fn.extend({
trackChanges: function() {
$(":input",this).change(function() {
$(this.form).data("changed", true);
});
}
,
isChanged: function() {
return this.data("changed");
}
});
Then you can simply say:
$("#myform").trackChanges();
and check if a form has changed:
if ($("#myform").isChanged()) {
// ...
}
I am not sure if I get your question right, but what about addEventListener? If you don't care too much about IE8 support this should be fine. The following code is working for me:
var form = document.getElementById("myForm");
form.addEventListener("input", function () {
console.log("Form has changed!");
});
In case JQuery is out of the question. A quick search on Google found Javascript implementations of MD5 and SHA1 hash algorithms. If you wanted, you could concatenate all form inputs and hash them, then store that value in memory. When the user is done. Concatenate all the values and hash again. Compare the 2 hashes. If they are the same, the user did not change any form fields. If they are different, something has been edited, and you need to call your persistence code.
Another way to achieve this is serialize the form:
$(function() {
var $form = $('form');
var initialState = $form.serialize();
$form.submit(function (e) {
if (initialState === $form.serialize()) {
console.log('Form is unchanged!');
} else {
console.log('Form has changed!');
}
e.preventDefault();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
Field 1: <input type="text" name="field_1" value="My value 1"> <br>
Field 2: <input type="text" name="field_2" value="My value 2"> <br>
Check: <input type="checkbox" name="field_3" value="1"><br>
<input type="submit">
</form>
Form changes can easily be detected in native JavaScript without jQuery:
function initChangeDetection(form) {
Array.from(form).forEach(el => el.dataset.origValue = el.value);
}
function formHasChanges(form) {
return Array.from(form).some(el => 'origValue' in el.dataset && el.dataset.origValue !== el.value);
}
initChangeDetection() can safely be called multiple times throughout your page's lifecycle: See Test on JSBin
For older browsers that don't support newer arrow/array functions:
function initChangeDetection(form) {
for (var i=0; i<form.length; i++) {
var el = form[i];
el.dataset.origValue = el.value;
}
}
function formHasChanges(form) {
for (var i=0; i<form.length; i++) {
var el = form[i];
if ('origValue' in el.dataset && el.dataset.origValue !== el.value) {
return true;
}
}
return false;
}
Here's how I did it (without using jQuery).
In my case, I wanted one particular form element not to be counted, because it was the element that triggered the check and so will always have changed. The exceptional element is named 'reporting_period' and is hard-coded in the function 'hasFormChanged()'.
To test, make an element call the function "changeReportingPeriod()", which you'll probably want to name something else.
IMPORTANT: You must call setInitialValues() when the values have been set to their original values (typically at page load, but not in my case).
NOTE: I do not claim that this is an elegant solution, in fact I don't believe in elegant JavaScript solutions. My personal emphasis in JavaScript is on readability, not structural elegance (as if that were possible in JavaScript). I do not concern myself with file size at all when writing JavaScript because that's what gzip is for, and trying to write more compact JavaScript code invariably leads to intolerable problems with maintenance. I offer no apologies, express no remorse and refuse to debate it. It's JavaScript. Sorry, I had to make this clear in order to convince myself that I should bother posting. Be happy! :)
var initial_values = new Array();
// Gets all form elements from the entire document.
function getAllFormElements() {
// Return variable.
var all_form_elements = Array();
// The form.
var form_activity_report = document.getElementById('form_activity_report');
// Different types of form elements.
var inputs = form_activity_report.getElementsByTagName('input');
var textareas = form_activity_report.getElementsByTagName('textarea');
var selects = form_activity_report.getElementsByTagName('select');
// We do it this way because we want to return an Array, not a NodeList.
var i;
for (i = 0; i < inputs.length; i++) {
all_form_elements.push(inputs[i]);
}
for (i = 0; i < textareas.length; i++) {
all_form_elements.push(textareas[i]);
}
for (i = 0; i < selects.length; i++) {
all_form_elements.push(selects[i]);
}
return all_form_elements;
}
// Sets the initial values of every form element.
function setInitialFormValues() {
var inputs = getAllFormElements();
for (var i = 0; i < inputs.length; i++) {
initial_values.push(inputs[i].value);
}
}
function hasFormChanged() {
var has_changed = false;
var elements = getAllFormElements();
for (var i = 0; i < elements.length; i++) {
if (elements[i].id != 'reporting_period' && elements[i].value != initial_values[i]) {
has_changed = true;
break;
}
}
return has_changed;
}
function changeReportingPeriod() {
alert(hasFormChanged());
}
Here's a polyfill method demo in native JavaScript that uses the FormData() API to detect created, updated, and deleted form entries. You can check if anything was changed using HTMLFormElement#isChanged and get an object containing the differences from a reset form using HTMLFormElement#changes (assuming they're not masked by an input name):
Object.defineProperties(HTMLFormElement.prototype, {
isChanged: {
configurable: true,
get: function isChanged () {
'use strict'
var thisData = new FormData(this)
var that = this.cloneNode(true)
// avoid masking: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
HTMLFormElement.prototype.reset.call(that)
var thatData = new FormData(that)
const theseKeys = Array.from(thisData.keys())
const thoseKeys = Array.from(thatData.keys())
if (theseKeys.length !== thoseKeys.length) {
return true
}
const allKeys = new Set(theseKeys.concat(thoseKeys))
function unequal (value, index) {
return value !== this[index]
}
for (const key of theseKeys) {
const theseValues = thisData.getAll(key)
const thoseValues = thatData.getAll(key)
if (theseValues.length !== thoseValues.length) {
return true
}
if (theseValues.some(unequal, thoseValues)) {
return true
}
}
return false
}
},
changes: {
configurable: true,
get: function changes () {
'use strict'
var thisData = new FormData(this)
var that = this.cloneNode(true)
// avoid masking: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
HTMLFormElement.prototype.reset.call(that)
var thatData = new FormData(that)
const theseKeys = Array.from(thisData.keys())
const thoseKeys = Array.from(thatData.keys())
const created = new FormData()
const deleted = new FormData()
const updated = new FormData()
const allKeys = new Set(theseKeys.concat(thoseKeys))
function unequal (value, index) {
return value !== this[index]
}
for (const key of allKeys) {
const theseValues = thisData.getAll(key)
const thoseValues = thatData.getAll(key)
const createdValues = theseValues.slice(thoseValues.length)
const deletedValues = thoseValues.slice(theseValues.length)
const minLength = Math.min(theseValues.length, thoseValues.length)
const updatedValues = theseValues.slice(0, minLength).filter(unequal, thoseValues)
function append (value) {
this.append(key, value)
}
createdValues.forEach(append, created)
deletedValues.forEach(append, deleted)
updatedValues.forEach(append, updated)
}
return {
created: Array.from(created),
deleted: Array.from(deleted),
updated: Array.from(updated)
}
}
}
})
document.querySelector('[value="Check"]').addEventListener('click', function () {
if (this.form.isChanged) {
console.log(this.form.changes)
} else {
console.log('unchanged')
}
})
<form>
<div>
<label for="name">Text Input:</label>
<input type="text" name="name" id="name" value="" tabindex="1" />
</div>
<div>
<h4>Radio Button Choice</h4>
<label for="radio-choice-1">Choice 1</label>
<input type="radio" name="radio-choice-1" id="radio-choice-1" tabindex="2" value="choice-1" />
<label for="radio-choice-2">Choice 2</label>
<input type="radio" name="radio-choice-2" id="radio-choice-2" tabindex="3" value="choice-2" />
</div>
<div>
<label for="select-choice">Select Dropdown Choice:</label>
<select name="select-choice" id="select-choice">
<option value="Choice 1">Choice 1</option>
<option value="Choice 2">Choice 2</option>
<option value="Choice 3">Choice 3</option>
</select>
</div>
<div>
<label for="textarea">Textarea:</label>
<textarea cols="40" rows="8" name="textarea" id="textarea"></textarea>
</div>
<div>
<label for="checkbox">Checkbox:</label>
<input type="checkbox" name="checkbox" id="checkbox" />
</div>
<div>
<input type="button" value="Check" />
</div>
</form>
I really like the contribution from Teekin above, and have implemented it.
However, I have expanded it to allow for checkboxes too using code like this:
// Gets all form elements from the entire document.
function getAllFormElements() {
// Return variable.
var all_form_elements = Array();
// The form.
var Form = document.getElementById('frmCompDetls');
// Different types of form elements.
var inputs = Form.getElementsByTagName('input');
var textareas = Form.getElementsByTagName('textarea');
var selects = Form.getElementsByTagName('select');
var checkboxes = Form.getElementsByTagName('CheckBox');
// We do it this way because we want to return an Array, not a NodeList.
var i;
for (i = 0; i < inputs.length; i++) {
all_form_elements.push(inputs[i]);
}
for (i = 0; i < textareas.length; i++) {
all_form_elements.push(textareas[i]);
}
for (i = 0; i < selects.length; i++) {
all_form_elements.push(selects[i]);
}
for (i = 0; i < checkboxes.length; i++) {
all_form_elements.push(checkboxes[i]);
}
return all_form_elements;
}
// Sets the initial values of every form element.
function setInitialFormValues() {
var inputs = getAllFormElements();
for (var i = 0; i < inputs.length; i++) {
if(inputs[i].type != "checkbox"){
initial_values.push(inputs[i].value);
}
else
{
initial_values.push(inputs[i].checked);
}
}
}
function hasFormChanged() {
var has_changed = false;
var elements = getAllFormElements();
var diffstring = ""
for (var i = 0; i < elements.length; i++) {
if (elements[i].type != "checkbox"){
if (elements[i].value != initial_values[i]) {
has_changed = true;
//diffstring = diffstring + elements[i].value+" Was "+initial_values[i]+"\n";
break;
}
}
else
{
if (elements[i].checked != initial_values[i]) {
has_changed = true;
//diffstring = diffstring + elements[i].value+" Was "+initial_values[i]+"\n";
break;
}
}
}
//alert(diffstring);
return has_changed;
}
The diffstring is just a debugging tool

Categories