I have a form that I want to only submit post data for value which have changed.
So the way I have been doing this is like this:
function submit_form(){
var hd = [];
// hd is a big array that is defined here
// hd ['some id_number'] = 'some value'
// main function
for (var id_number in hd ){
var x=document.getElementById(id_number).selectedIndex;
var y=document.getElementById(id_number).options;
selector_text = y[x].text;
if (hd[id_number] == selector_text){
$(id_number).remove();
}
}
document.forms["my_form"].submit()
}
So the goal is that if the selector equals what is in the array, then don't POST the data.
To do this I have been doing the remove function. Everything up to the remove function works as expected. However when I look at the post data I still get the selected value for the id_numbers that mach the value in hd.
Is there a better way to remove to prevent it from going to the POST data? The id.parent.removeChild(id) method didn't work either.
The jQuery id selector should begin with a #, but yours appears not to:
$('#' + id_number).remove();
Your for-in loop should be a regular incremental for loop, which is the proper way to iterate an array in JavaScript. for-in loops are typically used for iterating object properties rather than array elements.
for (var i=0; i<hd.length; i++) {
// Access hd[i] in the loop
var x=document.getElementById(hd[i]).selectedIndex;
var y=document.getElementById(hd[i]).options;
selector_text = y[x].text;
if (hd[i] == selector_text){
$('#' + hd[i]).remove();
}
}
Since you aren't really using jQuery here except for that line, instead the plain JS version is:
var removeMe = document.getElementById(hd[i]);
removeMe.parentNode.removeChild(removeMe);
Related
Being fairly new to jquery and javascript I can't seem to understand how the .text() method really works. I read through the jQuery documentation but still can't figure it out.
for (var i=0; i < arrayLength; i++){
var currentElement = $(".artist")[i];
var currentArtist = currentElement.text;
console.log(currentElement);
console.log(currentArtist);
}
currentArtist returns "undefined" in the console. It works fine on the $(".artist") alone, but not when I use the [i] or anything additional for that matter. What am I missing here? How else could I grab a text value inside a selector?
By using the [] operator on jQuery object you're accessing the raw element node that was found by jQuery. This raw element doesn't have the jQuery methods anymore, nor a text property.
If you want to get single element from jQuery object and keep the jQuery wrapper, use eq method.
var artistElement = $(".artist").eq(i);
artistElement.text(); // gets the text content of the element
The code you've posted is also not very optimized. For instance, with every loop iteration you're searching the document over and over again for elements with class artist. Better to cache that search result in a variable before performing the loop. And if the loop iterates over all .artist elements, you can use jQuery's each method.
$(".artist").each(function () {
var artist = $(this); // this poits to the raw element thus wrapping into jQuery object
console.log(artist.text());
});
var currentArtist = currentElement.text;
Should be:
var currentArtist = currentElement.text();
You should use a each():
$(".artist").each(function(i,val){
var currentArtist = $(val).text();
console.log(val);
console.log(currentArtist);
});
$(".artist") produce a jQuery object that could be like this:
[div, div, div, div, prevObject: jQuery.fn.jQuery.init, context: document, selector: ".artist"...]
So the result of $(".artist")[i] is a HTMLElement and do not have a text method, that's why you're getting undefined
Also text() is a function and may be followed with ()
But if you want to keep the for loop you can do
for (var i=0; i < arrayLength; i++){
var currentElement = $(".artist")[i];
var currentArtist = $(currentElement).text();
console.log(currentElement);
console.log(currentArtist);
}
.text() shows the text of an html element or set of html elements that would be visible to the user.
I'm struggling to dynamically convert a set of inputs into a multi-dimensional object for passing in an ajax call.
Assume I have a Person, with multiple Addresses.
My fields currently look like this:
<input name='Person[name]' value='Bradley'/>
<input name='Person[addresses][home]' value='123 Anywhere Drive.'/>
<input name='Person[addresses][work]' value='456 anywhere Road.'/>
How would one convert my fields into ab object that looks like this:
Person :
{
name: 'Bradley',
addresses:
{
home: '123 Anywhere Drive.',
work: '456 anywhere Road.'
}
}
I need to do this dynamically (function needs to work regardless of the inputs provided) and work at N-depth.
(Note: jQuery available).
http://jsfiddle.net/w4Wqh/1/
Honestly I think there's a way to do this in a regex.. but I couldn't figure it out. So, it's a bit of ugly string manipulation. Either way, this should get you on the right track I think:
function serialize () {
var serialized = {};
$("[name]").each(function () {
var name = $(this).attr('name');
var value = $(this).val();
var nameBits = name.split('[');
var previousRef = serialized;
for(var i = 0, l = nameBits.length; i < l; i++) {
var nameBit = nameBits[i].replace(']', '');
if(!previousRef[nameBit]) {
previousRef[nameBit] = {};
}
if(i != nameBits.length - 1) {
previousRef = previousRef[nameBit];
} else if(i == nameBits.length - 1) {
previousRef[nameBit] = value;
}
}
});
return serialized;
}
console.log(serialize());
Quick explanation. This just grabs anything with a 'name' attribute, and then iterates over them. For each iteration, it grabs the name and splits it on '['. This gets you basically how far into the object you need to put things. So, for Person[addresses][work], you would get Person, addresses], work].
Then, there's the tricky part. Since objects are always passed around by reference, we can see if the serialized variable has 'Person' in it. If not, it adds it, and sets the value to an empty object.. which is generic enough to be used for storing more things, or replaced if necessary. If there are no more levels that we need to go through, it just takes the value of the element and assigns it to the reference it has. Otherwise, the code grabs a reference to whatever it just made, and loops again, performing the same operation. So, for Person[addresses][work]..
Does serialized.Person exist? No. Setting serialized.Person to {}. This is not the end of the loop, store reference to serialized.Person as previousRef.
Does previousRef.addresses exist? (serialized.Person.addresses) No. Setting previousRef.addresses to {}. This is not the end of the loop, store reference to previousRef.addresses as previousRef.
Does previousRef.work exist? (serialized.Person.addresses.work) No. Setting previousRef.work to {}. Wait. This is the end of the loop. Setting previousRef.work to the value in the element.
In javascript, I'm loading an json object, and trying to update values within it. Elements in html have ids that match their path, such that the "values.one" element in this:
{"values":{"one":"val1","two":"val2"},"OtherStuff":"whatever"}
would be related to this element:
<input id="values_one" type="text">val1</div>
When this element loses focus, I want to grab the value of "#values_one" (using jQuery) and set use whatever value is there into my json object. I've figured out how to get the value from the existing json object (see my horrid code below), but I end up with nothing but the value, so setting it doesn't affect the json object. Any suggestions on how I can do this (assuming that I don't know whether the element that lost focus was "values_one", "values_two", or any other element that might map to the json object)?
Here's the code that I have at this point (that isn't working), but happy to scrap it for something that actually works:
var saveEdit = function() {
var data = getJson();
pathElements = $(this).attr('id').split('_');
length = pathElements.length;
var path = data[pathElements[0]];
index = 1;
while (index < length) {
path = path[pathElements[index]];
length -= 1;
}
path = $(this).text(); //resets "path", but not data.values.one
$(this).unbind();
}
Loop one shorter than the length, so that you get the element that contains the property that matches the last identifier:
var path = data;
for (index = 0; index < length - 1; index++) {
path = path[pathElements[index]];
}
path[pathElements[length - 1]] = $(this).text();
Firstly, there's no such thing as a "JSON Object". Yes, I'm being pedantic, but you should either have a "JSON String", or a "Javascript Object".
It looks like you're trying to modify a JSON string via events, instead of just having the object itself available to reference and modify. Why bother keeping it in a string? When you're ready to export the data (perhaps saving to a db), then just stringify(); the object and be on your way.
Take a look at the following jsFiddle for a working implementation that you can build off of: http://jsfiddle.net/julianlam/WRZPF/
In JS, I'm having trouble working out how to split a string coming from an AJAX call.
This is what I have so far:
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
feedUpdateResponse = xmlhttp.responseText;
/////...split script.../////
}
}
xmlhttp.open("GET","https://myDomain.com/myScript.aspx",true);
xmlhttp.send();
Where you have /////...split script...///// in my script above, I need to add a little function that splits the string returned from my AJAX call.
The string simply contains names of DIVs, like this:
feedUpdateResponse = "div1/div2/div3/div4"
I would like to first split the string by its slashes (/) and run a loop through the different values and do stuff to those elements on my page.
To give an idea of what I need to achieve, I have given this example which is a mix of ASP & JS - it's the only way I can possibly describe it (and show that I've had an attempt) :)
MyArray = Split(feedUpdateResponse,"/")
For Each X In MyArray
documentGetElementById('updateAvailable_'+x).style.visibility="visible";
Next
On my page I have an ASP script that produces jquery carousels, all contained by separate DIVs. The DIVs are named DIV1, DIV2 etc. Inside DIV1, for example, is a text element called updateAvailable_div1 which will alert the user "There are new photos available for this feed, please click the refresh button".
Could somebody please explain to me how I can change my example above to work in JS? Just need to split the string into an array and loop through the split values...
You can use .split() to split a string on a specified character with the results returned as an array. So then it's just a matter of looping through the array:
// given your existing variable
// feedUpdateResponse = "div1/div2/div3/div4" as set in the
// code in the question, add this:
var a = feedUpdateResponse.split("/"),
i;
for (i = 0; i < a.length; i++) {
document.getElementById("updateAvailable_" + a[i]).style.visibility
= "visible";
}
Get your array via string.split("/"). Iterate your array using your method of choice. I prefer Array.forEach():
feedUpdateResponse.split("/").forEach(function (item) {
document.getElementById(item).style.visibility = "visible";
});
See the compatibility notes for using .forEach() in older browsers.
As an alternative:
for(element of feedUpdateResponse.split("/")){
do_your_thing();
}
Using for..in will end up giving you the indices on the array (keys), while for..on will give you the elements of the array (values).
You can also do:
for ([index, element] of Object.entries(feedUpdateResponse.split("/"))) {
do_your_thing();
}
In the event that you need the index.
The disadvantage is it not being compatible with IE, but for personal projects or a quick automation script it usually does me plenty fine.
Try this code:
var a = feedUpdateResponse.split("/");
for (i in a) {
document.getElementById("updateAvailable_" + a[i]).style.visibility
= "visible";
}
var feedUpdateResponse = "div1/div2/div3/div4";
var feedUpdateSplit = feedUpdateResponse.split("/");
for (var x = 0; x < feedUpdateSplit.length; x++) {
document.getElementById("updateAvailable_" + feedUpdateSplit[x]).style.visibility = "visible";
}
A simple question I'm sure, but I can't figure it out.
I have some JSON returned from the server
while ($Row = mysql_fetch_array($params))
{
$jsondata[]= array('adc'=>$Row["adc"],
'adSNU'=>$Row["adSNU"],
'adname'=>$Row["adname"],
'adcl'=>$Row["adcl"],
'adt'=>$Row["adt"]);
};
echo json_encode(array("Ships" => $jsondata));
...which I use on the client side in an ajax call. It should be noted that the JSON is parsed into a globally declared object so to be available later, and that I've assumed that you know that I formated the ajax call properly...
if (ajaxRequest.readyState==4 && ajaxRequest.status==200 || ajaxRequest.status==0)
{
WShipsObject = JSON.parse(ajaxRequest.responseText);
var eeWShips = document.getElementById("eeWShipsContainer");
for (i=0;i<WShipsObject.Ships.length;i++)
{
newElement = WShipsObject.Ships;
newWShip = document.createElement("div");
newWShip.id = newElement[i].adSNU;
newWShip.class = newElement[i].adc;
eeWShips.appendChild(newWShip);
} // end for
}// If
You can see for example here that I've created HTML DIV elements inside a parent div with each new div having an id and a class. You will note also that I haven't used all the data returned in the object...
I use JQuery to handle the click on the object, and here is my problem, what I want to use is the id from the element to return another value, say for example adt value from the JSON at the same index. The trouble is that at the click event I no longer know the index because it is way after the element was created. ie I'm no longer in the forloop.
So how do I do this?
Here's what I tried, but I think I'm up the wrong tree... the .inArray() returns minus 1 in both test cases. Remember the object is globally available...
$(".wShip").click(function(){
var test1 = $.inArray(this.id, newElement.test);
var test2 = $.inArray(this.id, WShipsObject);
//alert(test1+"\n"+test2+"\n"+this.id);
});
For one you can simply use the ID attribute of the DIV to store a unique string, in your case it could be the index.
We do similar things in Google Closure / Javascript and if you wire up the event in the loop that you are creating the DIV in you can pass in a reference to the "current" object.
The later is the better / cleaner solution.
$(".wShip").click(function(){
var id = $(this).id;
var result;
WShipsObject.Ships.each(function(data) {
if(data.adSNU == id) {
result = data;
}
});
console.log(result);
}
I could not find a way of finding the index as asked, but I created a variation on the answer by Devraj.
In the solution I created a custom attribute called key into which I stored the index.
newWShip.key = i;
Later when I need the index back again I can use this.key inside the JQuery .click()method:
var key = this.key;
var adt = WShipsObject.Ships[key].adt;
You could argue that in fact I could store all the data into custom attributes, but I would argue that that would be unnecessary duplication of memory.