JavaScript Vanilla Two Way Binding - javascript

I have found this very short yet handy two way binding code written in pure JavaScript. The data binding works fine, but what I want is to take the value from the first input and multiply it by a desired number and bind the outcome to the next input. I will appreciate any kind of help.
This is my HTML Code:
<input class="age" type="number">
<input class="age" type="number">
and the JavaScript Code:
var $scope = {};
(function () {
var bindClasses = ["age"];
var attachEvent = function (classNames) {
classNames.forEach(function (className) {
var elements = document.getElementsByClassName(className);
for (var index in elements) {
elements[index].onkeyup = function () {
for (var index in elements) {
elements[index].value = this.value;
}
}
}
Object.defineProperty($scope, className, {
set: function (newValue) {
for (var index in elements) {
elements[index].value = newValue;
}
}
});
});
};
attachEvent(bindClasses);
})();

If the desired results is take first input value, do something with it, put it to second input then why so serious?
(function () {
var bindClasses = ["age"];
var attachEvent = function (classNames) {
classNames.forEach( function( className ) {
var els = document.getElementsByClassName( className ),
from, to;
if ( 2 > els.length ) {
return;
}
from = els[0];
to = els[els.length - 1];
from.addEventListener( 'keyup', function() {
var v = this.value;
// Do whatever you want with that value
// Then assign it to last el
if ( isNaN( v ) ) {
return;
}
v = v / 2;
to.value = v;
});
});
};
attachEvent(bindClasses);
})();

Another simple approach to two-way binding in JS could be something like this:
<!-- index.html -->
<form action="#" onsubmit="vm.onSubmit(event, this)">
<input onchange="vm.username=this.value" type="text" id="Username">
<input type="submit" id="Submit">
</form>
<script src="vm.js"></script>
// vm.js - vanialla JS
let vm = {
_username: "",
get username() {
return this._username;
},
set username(value) {
this._username = value;
},
onSubmit: function (event, element) {
console.log(this.username);
}
}
JS Getters and Setters are quite nice for this - especially when you look at the browser support for this.

Related

How can i add or update products and prices in my list?

Pretty new to javascript, i want to add and update my list but it doesn't work.
I tried adding following code but it didn't work
Product.prototype.addProduct = function() {
var elol = document.getElementById("lijst");
var nieuwNaam = document.createElement("li");
nieuwNaam.textContent= this.naam;
elol.appendChild(nieuwNaam);
var nieuwPrijs = document.createElement("li");
nieuwPrijs.textContent= this.prijs;
elol.appendChild(nieuwPrijs);
}
Product.prototype.getProducten = function() {
return this.naam + "(€ " + this.prijs +")";
}
This is the document i want wish would work propperly
<!DOCTYPE html>
<html>
<head>
<script src="oefwinkel.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
winkel.addProduct("Potlood", 10);
VulLijst();
var elBtn = document.getElementById("btn");
elBtn.onclick = VoegProductToe;
});
function VulLijst() {
var elol = document.getElementById("lijst");
var producten = winkel.getProducten("</li><li>");
if (producten.length > 0) {
elol.innerHTML = "<li>" + producten + "</li>";
} else {
elol.innerHTML = "";
}
}
function VoegProductToe() {
var naam = document.getElementById("txtNaam").value;
var prijs = document.getElementById("txtPrijs").value;
winkel.addProduct(naam, prijs);
VulLijst();
}
function Product(naam, prijs) {
this.naam = naam;
this.prijs = prijs;
}
</script>
</head>
<body>
<div><label for="txtNaam">Naam:</label>
<input type="text" id="txtNaam" /></div>
<div><label for="txtPrijs">Prijs:</label>
<input type="number" id="txtPrijs" /></div>
<input type="button" id="btn" value="Toevoegen/Updaten" />
<ol id="lijst">
</ol>
</body>
</html>
There is no list output how do i correct this?..
I really can't find the solution, what did i miss.. huh?
You had a few things missing,
The HTML code.
The winkel object was undefined.
The VulLijst function was doing nothing... because addProduct was taking care of this already.
You are relying on the instance fields (this.naam and this.prijs), but what you want to do is pass in method parameters (external variables).
As for updating, you will need to store a list of Products, clear the child elements of lijst, and re-add the items that represent the list.
Note: One thing I am confused about is why you named your class—that represents a list—Product, when it should really be an Inventory that allows you to ADD Product objects.
Code
// Uncaught ReferenceError: winkel is not defined
var winkel = new Product();
function Product(naam, prijs) {
this.naam = naam;
this.prijs = prijs;
}
Product.prototype.addProduct = function(naam, prijs) {
naam = naam || this.naam; // Default or instance field
prijs = prijs || this.prijs; // Default or instance field
console.log(naam, prijs);
var elol = document.getElementById("lijst");
var nieuwNaam = document.createElement("li");
nieuwNaam.textContent = naam;
elol.appendChild(nieuwNaam);
var nieuwPrijs = document.createElement("li");
nieuwPrijs.textContent = prijs;
elol.appendChild(nieuwPrijs);
}
Product.prototype.getProducten = function(naam, prijs) {
naam = naam || this.naam; // Default or instance field
prijs = prijs || this.prijs; // Default or instance field
return naam + " (€ " + prijs + ")";
}
document.addEventListener("DOMContentLoaded", function() {
winkel.addProduct("Potlood", 10); // Why are you adding a product to a product?
var elBtn = document.getElementById("btn");
elBtn.onclick = VoegProductToe;
});
function VoegProductToe() {
var naam = document.getElementById("txtNaam").value;
var prijs = document.getElementById("txtPrijs").value;
winkel.addProduct(naam, prijs);
}
label { font-weight: bold; }
<label>Product</label>
<input id="txtNaam" value="Something" />
<input id="txtPrijs"value="1.99" />
<button id="btn">Add</button>
<br/>
<ul id="lijst"></ul>
Explained
I will openly admit, I'm not 100% sure what you're trying to do, I assume that's due to a language barrier my side though, I'm not sure of the natural language that you use on a daily basis, i.e. some of the variable names seem unclear to me, but that's my problem, not yours! :)
Anyway, I used some guess work to figure out what you're trying to achieve, and I assumed that you're simply trying to have some sort of product list where each product has a name and a price attached to it?
You want to be able to add a product to the list, based on two input fields, then some button to add to/update that product list.
I've broken up the code into a couple of simple functions, with this solution you can add/remove as many functions, classes or whatever you want. In this answer you can clearly see that there's some render function, and some onUpdate function, I just went with these generic names for the sake of simplicity.
If you have any issues with this solution, please provide as much feedback as possible! I hope that it's been of some help one way or another.
// A simple product list.
const ProductList = () => {
const products = [];
let el = null;
// What you wish to return, aka an object...
return {
addProduct: (name, price) => {
products.push({
name: name,
price: price
});
onUpdate();
render(el, products);
},
setRoot: root => {
el = root;
},
// removeFromList, etc...
};
};
// A simple on update function.
const onUpdate = () => {
console.clear();
console.log('Update!');
};
// A 'simple' render function.
const render = (el, products) => {
if (el == null) return;
const template = obj => `<li>${obj.name} €${obj.price}</li>`;
let html = '';
products.forEach(product => html += template(product));
el.innerHTML = html;
};
// A function to dispatch some event(s).
const dispatchEvents = products => {
const btn = document.getElementById("btn");
const price = document.getElementById("price");
const name = document.getElementById("name");
// Just an example.
const isValid = () => {
if (price.value != '' && name.value != '') return true;
return false;
};
// Handle the on click event.
btn.onclick = () => {
if (isValid()) {
products.addProduct(name.value, price.value);
name.value = '';
price.value = '';
}
};
};
// A simple dom ready function.
const ready = () => {
const products = ProductList();
products.setRoot(document.getElementById("productList"));
products.addProduct('Demo', 10);
products.addProduct('Other', 19.99);
dispatchEvents(products);
};
document.addEventListener("DOMContentLoaded", ready);
<div>
<label for="name">name:</label>
<input type="text" id="name" />
</div>
<div>
<label for="price">Prijs:</label>
<input type="number" id="price" />
</div>
<input type="button" id="btn" value="Update" />
<ol id="productList">
</ol>

Display number of Input fields based on the value in database column

I have a database table with column name qty that holds an int.Now i want to display as many input fields as the value in qty.
So far i haved tried this using iavascript code . Here is my javascript code .
$(function() {
var input = $(<input 'type'="text" />);
var newFields = $('');
$('#qty').bind('blur keyup change', function() {
var n = this.value || 0;
if (n+1) {
if (n > newFields.length) {
addFields(n);
} else {
removeFields(n);
}
}
});
function addFields(n) {
for (i = newFields.length; i < n; i++) {
var newInput = input.clone();
newFields = newFields.add(newInput);
newInput.appendTo('#newFields');
}
}
function removeFields(n) {
var removeField = newFields.slice(n).remove();
newFields = newFields.not(removeField);
}
});
Just store the value in the textfield(hidden)
HTML:
<input type="hidden" id="quantitycount" value="4" />
<div class="textboxarea"></div>
Jquery:
Get the textbox value
var quantitycount=jQuery('#quantitycount').val();
var txthtml='';
for(var txtcount=0;txtcount<quantitycount;txtcount++){
txthtml+='<input type="text" id="txtbox[]" value="" />';
}
jQuery('.textboxarea').html(txthtml);
You can use entry control loops to loop for number of times
Now we can see number of textbox as per need, Just the value from db and store that in the textbox
You can try this
foreach($qty as $qt){
echo '<input type="text">';
}
To append the text fields you need a wrapper on your html form
use some wrapper as mentioned by #Rajesh: and append your text-fields to that wrapper as shown below
$('#qty').bind('blur keyup change', function() {
var n = this.value || 0;
if (n >0) {
for(var x=0;x<n;x++){
$('#textboxarea').append('<input type="text" name="mytext[]"/>');
}
});
similarly you can write your own logic to remove the text-fields also using jquery

ng-dirty is not working as expected

I am having tough time in understanding why my element shows ng-dirty after updating the model.
I have a collection of bridges which need to be rendered on UI. On each tab click, I am changing the index and rendering the data.
If my first tab data has changed and moved to second tab why are input elements still dirty on second tab. (Function - $scope.changeIndex)
After executing calculate, the model gets updated but still the input elements are still dirty
UI
<td style="padding:10px;text-align:center">
<label>Length:</label>
<input type="text" class="currencyLabel-editable" ng-model="bridgeModel.bridges[currentIndex].length" />
</td>
<td style="padding:10px;text-align:center">
<label>Width:</label>
<input type="text" class="currencyLabel-editable" ng-model="bridgeModel.bridges[currentIndex].width" />
</td>
<td style="padding:10px;text-align:center">
<label> Skew:</label>
<input type="text" class="currencyLabel-editable" ng-model="bridgeModel.bridges[currentIndex].skew" />
</td>
Controller
(function () {
var bridgeCtrl = function ($scope, $bootstrapBridgeData, $crudService,$log) {
$scope.bridgeModel = $bootstrapBridgeData.bridgeModel;
var onCalculateComplete = function (data) {
$scope.bridgeModel.bridges[$scope.currentIndex] = angular.copy(angular.fromJson(data));
}
var onCalculateError = function (reason){
$scope.error = "Unable to perform calculation";
$log.error(reason);
}
var onError = function (reason) {
$scope.error = "Unable to fetch data";
}
//function to null the values which needs to be re-computed
var removeCalculatedValues = function () {
$scope.bridgeModel.bridges[$scope.currentIndex].foundation_PreBoringCalculated = null;
$scope.bridgeModel.bridges[$scope.currentIndex].foundation_DrilledShaftsCalculated = null;
}
//function to compute the bridge values
$scope.calculate = function (url) {
if (!preValidation()) {
return false;
}
removeCalculatedValues();
$crudService.postAndGetData(url, $scope.bridgeModel.bridges[$scope.currentIndex])
.then(onCalculateComplete, onCalculateError)
}
//function to select the bridge and change the index of the bridge
$scope.changeIndex = function (bridgeName,index) {
$scope.selectedBridge = bridgeName;
$scope.currentIndex = index;
}
$scope.save = function (index, url) {
$scope.currentIndex = index;
crudService.postAndGetData(url, $scope.bridges[index])
.then(onUserComplete, onError);
}
//$scope.enableSave = function isFormDirty() {
// if ($(".ng-dirty").length) {
// return false;
// }
// else { return true; }
//}
//Behaviour Changes
//function which changes the css
$scope.isBridgeSelected = function (bridge) {
return $scope.selectedBridge === bridge;
}
var preValidation = function () {
if ($(".ng-invalid").length) {
alert("Please correct the errors.")
return false;
}
else { return true;}
}
}
//Get the module and add a controller to it
var module = angular.module("bridgeModule");
module.controller("bridgeCtrl", bridgeCtrl);
}());
From the documentation
ng-dirty is set if the form is dirty.
This is a check for whether the form itself has been interacted with in any way. It doesn't care what the underlying object binding is. So this is the expected behavior, since you are using the same form but changing the ng-model behind the scenes.
Dunno if this is the problem or not, but the line $scope.$setPristine; is not doing anything. It should be: $scope.$setPristine();

Attribute default value: attribute.defaultValue

Can you get an attribute default value so you don't have to repeat it in the following example:
<p title="foo" id="p">Hello, world!</p>
<input type="text" id="i">
<script>
var p = document.getElementById('p'),
i = document.getElementById('i');
i.oninput = function () {
p.title = this.value;
if (this.value == 'bar') {
p.title = 'foo';
}
};
</script>
DEMO
For text field elemets there's a property known as defaultValue: element.defaultValue.
Is there something like attribute.defaultValue? In other words, is there something like p.title = p.title.defaultValue for the above example?
Fiddle demo
If you build a nice reusable function like:
function el(id){
var e = document.getElementById(id), a = e.attributes; e.default = {};
for(var k in a)if(typeof a[k]==='object') e.default[a[k].nodeName] = a[k].nodeValue
return e;
}
not only it'll allow you to easily reference a desired element by ID like:
var p = el('p'),
i = el('i');
but also to retrieve at any point any default element attribute like:
p.default.title // "foo"
or in your example:
i.oninput = function () {
p.title = this.value;
if (this.value == 'bar') {
p.title = p.default.title ;
}
};
or shortened like http://jsfiddle.net/jU5Tv/6/ :
i.oninput = function () {
p.title = this.value==="bar" ? p.default.title : this.value;
};
so double pleasure in any way :)
What the function does is: returns a DOM HTMLElement, but at the same time loops any Element's assigned attribute and stores it inside a self-assigned Object called default.
There is not a default value property for input title attributes.
However, so that you're not repeating yourself you can store this in a variable before updating it:
var p = document.getElementById('p'),
i = document.getElementById('i');
var defaultTitle = p.title;
i.oninput = function () {
p.title = (this.value == 'bar') ? defaultTitle : this.value;
};
You could create a data attribute to hold your default title.
<p title="foo" data-default-title="foo" id="p">Hello, world!</p>
<input type="text" id="i">
In the JS:
if (this.value == 'bar') {
p.title = p.dataset.defaultTitle;
}

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