Javascript Form: Only Changed Fields - javascript

I have a php-site with a form on which i output preselected values via php. On form submit I want to check which values have changed and just submit these via javascript.
These are the preselected values I passed over from php. It's important that I keep the associative array structure.
var pbData = jQuery.parseJSON("{
"GameMode":"DEATHMATCH",
"Current Map":"VEGAS JUNKYARD",
"Current Missions":["VEGAS JUNKYARD","VILLA","PRESIDIO","KILL HOUSE","MURDERTOWN","CQB TRAINING","STREETS","THREE KINGDOMS CASINO","IMPORT\/EXPORT;"],
"RoundDuration":"3 minutes"}");
I marked the error in the code.
<script>
function displayVars(){
var form = document.getElementById('settings');
var elems = form.elements;
var txt = "";
for (var index = 0; index < elems.length; index++){
var selIndex = elems[index].selectedIndex;
if (typeof selIndex !== "undefined"){
//the Index Name in the json-object and the name of the form-field are the same
var idxName = elems[index].name;
//HERE is the problem. I want to access the subobject via a variablename, so i can iterate through it, but that doesnt work.
console.log ("pbData default = "+pbData.idxName); //always undefined
if (elems[index].value !== pbData.idx_name){
//building a POST-Url
txt = txt + elems[index].name + "=" + elems[index].options[selIndex].value+"&";
}
}
}
console.log (txt);
return false;
}
</script>
I know that I could do this differently, also with jQuery. In my case as I have the preselected values as a php-variable in any case, i think it's easier like this.
I would really like to know how I can iterate through the subobjects via a variable that contains the object names.

This is due to how you'e trying to access the property of the (JSON) object. Consider
var o1 = {idxName: true},
o2 = {foo : 'bar'},
idxName = 'foo';
o1.idxName; // true
o2.idxName; // undefined
o2[idxName]; // 'bar'
You need to access the property via pbData[idxName].
Additionally, you're not escaping quotes in your JSON string, and line breaks need to be escaped as follows
var pbData = jQuery.parseJSON("{\
\"GameMode\":\"DEATHMATCH\",\
\"Current Map\":\"VEGAS JUNKYARD\",\
\"Current Missions\":[\"VEGAS JUNKYARD\",\"VILLA\",\"PRESIDIO\",\"KILL HOUSE\",\"MURDERTOWN\",\"CQB TRAINING\",\"STREETS\",\"THREE KINGDOMS CASINO\",\"IMPORT\/EXPORT;\"],\
\"RoundDuration\":\"3 minutes\"}");

In Javascript you could keep an object or array with initial values and only post those values that are changed.
But in fact, I would do something similar, but in PHP. You can keep the original values in the session and compare the posted values to those initial values to see what has changed. That way, you won't depend on Javascript. Not only may Javascript be disabled, but also, a fast user may theoretically post the form before the Javascript has run. To move this check to PHP eliminates that risk.

Related

Determine if value exists in JavaScript "hash table"

I have built a JavaScript object that functions as a hash table.
var hashTable = {};
The table consists of key value pairs that are manually built. The table will be used to generate a new value based on an old value, or key, in the table.
//hashTable['old_value'] = new_value;
hashTable['115004568543'] = 115004567503;
hashTable['115004545983'] = 360000857366;
hashTable['115004723526'] = 360000865566;
hashTable['115004723646'] = 360000865566;
I have another variable that is compared to the keys in the hash table. If it matches a key in the hash table, then it can be used to capture the new value mapped to it.
For example, let's say some_value is declared.
some_value = '115004568543';
Since it matches a key value (or old_value) in the hash table, I can get the new value by calling
var new_value = hashTable[some_value];
// new_value is going to be equal to 115004567503 due to the mapping above
My problem is that I have two different hash tables that "some_value" is being compared against. I want to see if the first value in the hash is present either in the first hash table OR in the second hash table. So I have been working with:
var hashTable = {};
hashTable['115004568543'] = 115004567503;
hashTable['115004545983'] = 360000857366;
var hashTable2 = {};
hashTable2['115004702483'] = 360000857366;
hashTable2['115004560766'] = 360000857366;
var some_value = '115004545983';
if (hashTable.includes(some_value)) {
var new_value = hashTable[some_value];
//Do some other stuff with new_value
}
else if (hashTableTwo.includes(some_value)) {
var new_value = hashTableTwo[some_value];
//Do some other stuff with new_value
}
Additionally, some_value will exist in the first hash table, the second hash table, or not at all. It will not exist multiple times.
MY QUESTION: I am trying to use hashTable.includes() to see if some_value is present in either of the two hash tables. It isn't working. What is the best way to determine if some_value is a value in one of the hash tables?
When I try to call hashTable.includes(some_value) I get
Uncaught TypeError: hashTable.includes is not a function
Array.includes() is an array method. Since your hashtable is based on an object, it doesn't support this method.
If your values aren't falsy (false, undefined, null, 0, NaN) you can use logical short-circuit evaluation to assign the value:
var new_value = hashTable[some_value] || hashTableTwo[some_value] || some_value;
If they might be falsy, you can use the in operator to check if they exist in the object:
if (some_value in hashTable) {
var new_value = hashTable[some_value];
} else if (some_value in hashTableTwo) {
var new_value = hashTableTwo[some_value];
//Do some other stuff
}

Trouble with getting access to an object's property

I'm having a trouble with getting access to an object's property.
Isn't it possible to get access to an object's property like this?
key["heading"]
key in the code above is a variable.
This code below is the code I'm working on right now.
alertHeading.on('blur', function(){
var inputtedVal = $(this).val();
var key = alertMode.val();
chrome.runtime.getBackgroundPage(function(backgroundPage) {
var background = backgroundPage.background;
//(1)This works fine.
background.setStorage(key, {heading:inputtedVal});
console.log(background.getStorage(key));// Object {heading: "aaa"}
//(2)This doesn't work.
var alertObject = background.getStorage(key["heading"]);
console.log(alertObject);// null. I'm expecting to get "aaa".
});
})
I think I'm making a very simple mistake which comes from my lack of javascript knowledge.
Please help me out to solve this problem.
Your key isn't an object, it's a string. It is the return from background.getStorage(key) that is an object, so you can do this:
var alertObject = background.getStorage(key)["heading"]; // note () and [] placement
// OR, in two steps:
var alertObject = background.getStorage(key);
var heading = alertObject["heading"];
EDIT:
"I haven't understood why it's not an object but a string yet"
Your key variable is set to the return from jQuery's .val() method:
var key = alertMode.val();
...which returns a string that is the value of the form element that it is called on. Add in a console.log(key) and you'll see.

Issue with JSON stringify?

/* Helper function to clean up any current data we have stored */
function insertSerializedData(ids, type) {
// Get anything in the current field
current_data = $('#changes').val();
if (!current_data) {
var data = new Array();
data[type] = ids;
$('#changes').val(JSON.stringify(data));
} else {
var data = JSON.parse($('#changes').val());
data[type] = ids;
$('#changes').val(JSON.stringify(data));
}
console.log($('#changes').val());
}
I am using the following function to either add data to a current JSON object or create a new JSON object all together to be used in PHP later. Is the stringify() method only for FF? I am using google chrome and I am being given an empty object when using the conosole.log() function...
Also what happens if you try to store two values with the same key? I assume it will overwrite...so I should add a random math number at the end array in order to keep duplicates from showing up?
Thanks :)
These lines may cause problems:
var data = new Array();
data[type] = ids;
... because arrays in JavaScript are not quite like arrays in PHP. I suppose what you meant is better expressed by...
var data = {};
data[type] = ids;
Besides, current_data seems to be local to this function, therefore it also should be declared as local with var. Don't see any other problems... except that similar functionality is already implemented in jQuery .data() method.
UPDATE: here's jsFiddle to play with. ) From what I've tried looks like the array-object mismatch is what actually caused that Chrome behavior.
I reformatted it a bit, but and this seems to work. It will set the "value" attribute of the #changes element to a JSON string. I assume that the type argument is supposed to be the index of the array which you're trying to assign?
function insertSerializedData(ids, type) {
var changes = jQuery('#changes'), arr, val = changes.val();
if (!val) {
arr = [];
arr[type] = ids;
changes.val(JSON.stringify(arr));
} else {
arr = JSON.parse(val);
arr[type] = ids;
changes.val(JSON.stringify(arr));
}
console.log(changes);
}

Set cookies for form elements

I'm trying to take values from a from and then and when it is submitted turn the values into a cookies. This is what I have, but I wanted to know if there was a way to make it so I didn't have to keep writing out the same thing for all of the variables.
function submitValues(){
var firstName = document.forms["frm1"]["first_name"].value;
var lastName = document.forms["frm1"]["last_name"].value;
var number = document.forms["frm1"]["phNum"].value;
setCookie("firstName",firstName,365);
setCookie("lastName",lastName,365);
setCookie("number",number,365);
}
If you want to set cookies for all form elements, use the DOM2 form.elements collection:
var els = document.forms.frm1.elements;
for (var i=els.length;i--;){
setCookie(els[i].name, els[i].value, 365);
}
If you want only specific, then write your code like so:
var els = document.forms.frm1.elements;
var cookiesToSet = ['first_name','last_name','phNum'];
for (var i=cookiesToSet.length;i--;){
var name = cookiesToSet[i];
setCookie(name, els[name].value, 365);
}
In the above, els[name] is equivalent to document.forms.frm1.elements[name].
In general, every property of every object in JavaScript is accessible via either "dot notation" (foo.bar) or "bracket notation" (foo["bar"]). You must use the latter when the property name is not a valid identifier(foo["names[]"] or foo["12 freakin' whales!"]) or when constructing the property name from a variable (foo[name] or foo["item"+i]).
You could shorten it somewhat by saving a reference to the form in a variable, like so:
var form = document.forms["frm1"];
var firstName = form["first_name"].value;
//...and so on
Or to shorten it even more by looping through all the <input> elements in the form:
var formInputs = document.forms["frm1"].getElementsByTagName("input");
for (var i=0;i<formInputs.length;i++) {
setCookie(formInputs[i].name, formInputs[i].value, 365);
}

How to store a div ID value globally

I am creating an application that uses the same number pad to fill out two separate text style form values using javascript.
I found out how to gather a div ID for use inside of a function (for say toggling the hide value), but I need to save this value somehow so that I can know which field to put the numbers into when they come in.
I tried using a global variable for this, but it does not seem to work as the ID does not seem to be recorded as a String value.
The code that I am using does toggle the show/hide attribute, but if I use an alert box to pop what the variable I am using as storage is it reads [object HTMLDivElement]
My script looks like this (bear in mind that I am a noob to javascript).
<script type="text/javascript">
<!--
keypad.display="none";
//Classes for the numberpad on the text fields.
var padName = ""; //Storage for the name of the current pad.
function numPad(field) {
var pad = document.getElementById("keypad"); //manipulating pad.
var ref = document.getElementById(field);//gather the field info.
if (pad.style.display == "block") { //Open or close?
pad.style.display = "none"; //Blank out.
padName = "";
}
else {
pad.style.display = "block";//Set to refer to correct field.
padname = ref;
alert (ref);
}
}
function click(id) {
var key = document.getElementById(id);
var total = padName.value();
if (key == "Backspace") total.slice(0, -1);
else if (key == "Enter") numPad("blanck");
else total += key;
padName.value = total;
}
-->
</script>
// to get the ID by direct property access of the DOM element
var ref = document.getElementById(field).id;
and then ref stores the ID value.
I would suggest:
// create an object to store app-wide settings
// access properties like this: appSettings.propertyName
var appSettings = { padName: "" };
...
var ref = document.getElementById(field).id;
appSettings.padName = ref;
to avoid polluting the global namespace.
To get/set the value of the pad, you'll need to do this:
// to get
var total = document.getElementById(appSettings.padName).value;
// to set
document.getElementById(appSettings.padName).value = "something";
You should read up on DOM objects and properties.
For starters, ref is assigned a reference to a DOM element. You are then assigning this reference to padName, hence the [object HTMLDivElement] alert.
If you just want the ID stored in padName, use
padName = field;
Also, you're mixing cases of padName. You have both padName and padname.
Further, as mentioned in the comments, use the console for debugging. It's much more comprehensive than an alert.
I can't tell what's happening in your click function. You seem to be expecting padName to be an object of some kind however where the value() method and value property comes from is anyone's guess (FYI only form elements have value properties).

Categories

Resources