referring the array with a dynamic string name - javascript

I have an array.
var ABCD=[{Key:"Milk",Value:"1" },{Key:"Bread",Value:"2" }];
now need to find using the key in this array (ABCD) using a dynamic string value (returned from a function myFunction("guest_user")). I am using something like this which is working in all the browsers apart from IE because of the eval() and would be great if someone can advise on this.
var entry = eval(myFunction("guest_user")).find(function(e) { return e.Key === "Milk"; });
the return value myFunction("guest_user") is ABCD which is the array name defined above.
myFunction is returning a request parameter .. .
function myFunction(key) {
var result = new RegExp(key + "=([^&]*)", "i").exec(window.location.search);
return result && unescape(result[1]) || "";
}

The issue in IE11 is not the eval() function. It's the find() method.
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find, and you'll see that find() is not supported in Internet Explorer.
You can, however, add the functionality to IE by using the Polyfill from the same link.
That said, it's best to avoid using eval() altogether. You can do so by placing your arrays in an object, such as:
var obj = {ABCD: [{Key ...}];
You can then reference the appropriate array by calling:
obj[myFunction("guest_user")].find(...

adding polyfill method (Adding a function to Array.prototype in IE results in it being pushed in to every array as an element ) and as Rick advised obj[myFunction("guest_user")].find( is working on IE.

Related

Slicing an object off of a jQuery collection [duplicate]

In Javascript, arrays should have methods pop and shift.
However, JQuery objects seem to be missing these methods:
$('div').shift(); // Error, shift is undefined
$('div').pop(); // Error, pop is undefined
$('div').splice(); // Splice is OK actually
I wonder why these functions are missing - after all, the jquery object is just an array.
What's the easiest way of performing pop and shift functions on jquery objects?
They're missing because a jQuery object isn't an Array.
(function( $ ) {
$.fn.pop = function() {
var top = this.get(-1);
this.splice(this.length-1,1);
return top;
};
$.fn.shift = function() {
var bottom = this.get(0);
this.splice(0,1);
return bottom;
};
})( jQuery );
EDIT: .slice() doesn't modify the original object. Fixed to use .splice() instead.
Your safest bet would be to just use:
[].pop.call($('div'))
[].shift.call($('div'))
If you want to use the exact syntax in your example you can augment jQuery.fn:
jQuery.fn.pop = [].pop;
jQuery.fn.shift = [].shift;
The latter works well for the mutator methods. It'll work for the accessor and iteration methods too, but be advised that many of those returns a pure array that you'd have to rewrap. Be aware that jQuery has is own version of some of these (e.g. .map, .slice, .filter, etc.) that you probably don't want to overwrite.
This seemed to work for me:
var divArray = $('div').toArray();
var elem = $( divArray.shift() );
.toArray() return the DOM elements as a JavaScript Array, which can be used as intended. Then all you need to do is convert it back into a jQuery object.
I realize this answer has already been selected, but here's another alternative that isn't too hard to remember, in case you don't want to worry about having to install plugins all the time.
$('div > :first').detach(); // shift
$('div > :last').detach(); // pop
By the way, I realize there are performance issues with using :last selector as part of your primary selector so you may want to consider doing something like this for pop:
$('div').children(':last').detach();
var $firstDiv = $( $('div').splice(0, 1) );
Another way using jQuery 1.9.1+:
$('div').first().remove();
$('div').last().remove();

JavaScript - Unable to get property from an Array of Object over function(parameters)

I have an Array of Objects:
var keywordset = [
{word:["PO","Pending Order"],message:["Do you need to post registry?"]},
{word:["delete"],message:["Do you want to delete in system?"]},
{word:["contact"],message:["Inter-related feature: Contact Management"]}
]
Also, I created a function to convert the strings in an array of objects to UpperCase:
function ObjectArrayUpperCase(arrayname,array1){
console.log(arrayname[0])
console.log(array1)
for(b=0;b<arrayname.length;b++){
for(c=0;c<arrayname[b].array1.length;c++){
arrayname[b].array1[c] = arrayname[b].array1[c].toUpperCase()
}
}
}
Then, i run the ObjectArrayUpperCase() function by passing parameter into it
ObjectArrayUpperCase(keywordset,'word')
Unfortunately, the ObjectArrayUpperCase() function unable to process "array1" part, seems like unable to recognize it. But the "arrayname" working as expected, because if i replace "array1" to "word", the function work.
I tried to change the parameter but still no luck:
ObjectArrayUpperCase(keywordset,'word')
ObjectArrayUpperCase(keywordset,word)
ObjectArrayUpperCase(keywordset,keywordset.word)
etc...
Please advise how to pass the correct parameter to the function
You need square brackets to evaluate an expression like array1 to be used as the property name.
for(var b=0;b<arrayname.length;b++) {
// -----------------------v------v--- and likewise below
for(var c=0;c<arrayname[b][array1].length;c++){
arrayname[b][array1][c] = arrayname[b][array1][c].toUpperCase()
}
}
}
Otherwise, how could it know if you meant to use the variable or an actual property with that name?
Also, be sure to declare your variables explicitly. I used var above.
Lastly, the loops can be written a little more cleanly using modern syntax and methods like this:
arrayname.forEach(obj => obj[array1] = obj[array1].map(s => s.toUpperCase()))

javascript/jQuery anonymous functions to populate an array

Hi I was just wondering if building an array in javascript was possible using a function like so. I have a variable that is getting the margins of a series of elements using $(ele).css('margin');. This returns a string of 0px 0px 0px 0px where I only want the left property to check whether it's been animated -= left.
I can do a similar function but I know there must be a better way. Here's my example:
var marginsLeft = new array();
$(ele).each(function(i){
var r = $(i).css('margin').split(" ");
marginsLeft[i]=r[3];
});
I'm not entirely sure how to simplify this, but I'm sure it's possible :) thanks in advance.
You can use $.map:
var marginsLeft = $(ele).map(function() {
return parseInt($(this).css('margin-left'), 10);
}).get();
Update: as pointed out by #undefined, if you want a regular array you should also call .get on the result. Otherwise, you'll have a jQuery wrapped array. It is array-like, so it can be used as an array in many contexts, but not in others (in particular, it may not have the native Array methods).
Also, to convert the result to a number you can use parseInt (which will ignore the letters and use only the digits), remembering to explicitate the base (10).
Have a look at the docs for .each(): The first parameter of the callback function is the index, the array element (DOM node) can be accessed either as the second parameter or the this value. So, use
var marginsLeft = []; // literal shortcut for "new Array()"
$(ele).each(function(i, el){
marginsLeft[i] = $(el).css('margin-left');
});
You also might have a look at the .map() method, but that returns a jQuery wrapper object instead of an array.
you could use css('margin-left') instead

HTML DOM element name as a string

Suppose I have the following HTML snippet:
<input type="text" id="myinput" />
Now I want to get that DOM element using JavaScript:
var element = document.getElementById("myinput");
Works fine, no problem so far.
But when I print it inside an alert box using alert(element);, it displays object HTMLInputElement.
Is there a way to get that element name (HTMLInputElement) as a string?
(Notice that when saying "element name" I do not mean the name attribute of an element, but the name how it is displayed when using alert() for example, as described above.
In some browsers, such as Firefox (and Chrome, potentially others) you can do:
element.constructor.name; // => "HTMLInputElement"
But in general it's a bit more complicated, perhaps not even totally reliable. The easiest way might be as such:
function getClassName(o) {
// TODO: a better regex for all browsers...
var m = (o).toString().match(/\[object (.*?)\]/);
return (m) ? m[1] : typeof o;
}
getClassName(element); // => "HTMLInputElement"
getClassName(123); // => "number"
[Edit]
Or, using the "nodeName" attribute, you could write a utility function which should be generally much more reliable:
function getHtmlElementClassName(htmlElement) {
var n = htmlElement.nodeName;
if (n.matches(/^H(\d)$/)) {
return "HTMLHeadingElement";
} else if (/* other exceptional cases? */) {
// ...
} else {
return "HTML" + n.charAt(0) + n.substr(1).toLowerCase() + "Element";
}
}
(Thanks #Esailija for the smarter implementation, #Alohci for pointing out exceptional cases.)
alert(element.nodeName);
https://developer.mozilla.org/En/DOM/Node.nodeName
When passing an object to the alert() function, it implicitly calls .toString() on that object in order to get the text for the alert. You could do something like:
var element = document.getElementById("myInput");
var string = element.toString(); // this will return 'object HTMLInputElement'
then work with the string variable to get only the HTMLInputElement part.
if I've got the question correctly you should try document.getElementById("myinput").toString().
document.getElementById returns the HTML element as an object. Simply get the attribute of the object you want to display in the alert instead (e.g., alert(element.getAttribute('ID'));). Alternatively, if you want '[object HTMLInputElement]' displayed in the alert, simply call the toString() method on the object in the alert (e.g., alert(element.toString());).
Hope this helps,
Pete

JSON how find another value at the same index from a value in Javascript Object

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.

Categories

Resources