anArray = ['thing1','thing2','thing3'];
$.each(anArray, function (i,el) {
var object = 'name.space.' + el;
var selector = 'node-' + el;
var object = $('#' + selector);//need object here to be interpreted as it's value
//as if: var name.space.thing1 = $('#' + selector);
});
such that these are usable jQuery objects:
console.log(name.space.thing1);
console.log(name.space.thing2);
console.log(name.space.thing3);
I feel like eval() is involved. I'm hydrating navigation selectors so as pages are added/removed, we just update the array. We could build the array from the nav nodes, but either way, we still need to be able to make these namespaced selectors...
You will have to use bracket notation:
var array = ['thing1', 'thing2'];
var object = {};
object.space = {};
$.each(array, function () {
object.space[this] = $('#node-' + this);
});
console.log(object.space.thing1); // [<div id="node-1">];
I am not sure what are you trying to accomplish, but
name.space[el] = $('#' + selector);
might work.
Object properties are always accessible with the bracket notation as well. This means that obj.xy is just the same as obj['xy'], but the latter is more flexible and can be used in situations like yours.
var anArray = ['thing1','thing2','thing3'];
var name = {space:new Array()};
$.each(anArray, function (i,el) {
var selector = 'node-' + el;
name.space[el] = $('#' + selector);
});
Related
Could you please help me, how to simplify this code? I think, it is too long and confused.
var launchPad = $(".launchPad").clone();
var launchPad_plankovy = $(".launchPad-plankovy").clone();
var launchPad_plankovy_tvarovany = $(".launchPad-plankovy-tvarovany").clone();
var launchPad_tyckovy = $(".launchPad-tyckovy").clone();
var launchPad_kombinovany = $(".launchPad-kombinovany").clone();
var launchPad_barvy_plankovy = $(".launchPad-barvy-plankovy").clone();
var launchPad_barvy_tyckovy = $(".launchPad-barvy-tyckovy").clone();
var launchPad_zakonceni_plotovek = $(".launchPad-zakonceni-plotovek").clone();
var launchPad_zakonceni_tycek = $(".launchPad-zakonceni-tycek").clone();
$("[name='reset']").click(function(){
$(".launchPad").html(launchPad.html());
$(".launchPad-plankovy").html(launchPad_plankovy.html());
$(".launchPad-plankovy-tvarovany").html(launchPad_plankovy_tvarovany.html());
$(".launchPad-tyckovy").html(launchPad_tyckovy.html());
$(".launchPad-kombinovany").html(launchPad_kombinovany.html());
$(".launchPad-barvy-plankovy").html(launchPad_barvy_plankovy.html());
$(".launchPad-barvy-tyckovy").html(launchPad_barvy_tyckovy.html());
$(".launchPad-zakonceni-plotovek").html(launchPad_zakonceni_plotovek.html());
$(".launchPad-zakonceni-tycek").html(launchPad_zakonceni_tycek.html());
});
You could make one big selector and collect all elements at once. You can apply clone on all of them in one call. For restoring, you would reuse that same selector, loop over the results and replace the HTML from the collected clones.
var $restorable = $(".launchPad, .launchPad-plankovy, " +
" .launchPad-plankovy-tvarovany, .launchPad-tyckovy, .launchPad-kombinovany, " +
" .launchPad-barvy-plankovy, .launchPad-barvy-tyckovy, " +
" .launchPad-zakonceni-plotovek, .launchPad-zakonceni-tycek");
var $launchPad = $restorable.clone();
$("[name='reset']").click(function (){
$restorable.each(function (i) {
$(this).html($launchPad.eq(i).html());
});
});
I do seem to notice you give unique classes to each of your elements. It is better to use id properties for that purpose, and use classes for marking the same kind of elements with the same class. If you would use one class for all these elements, like 'restorable', the list would not have to be that long.
Also, as you only use the HTML of the clones, you will get better performance and memory usage, if you don't actually clone, but just save the HTML. Together with the idea to give the class restorable to all these elements, the code becomes:
var $restorable = $(".restorable");
var launchPadHtml = $restorable.map(function() { return $(this).html(); }).get();
$("[name='reset']").click(function (){
$restorable.each(function (i) {
$(this).html(launchPadHtml[i]);
});
});
var keys = ['launchPad-plankovy-tvarovany', 'launchPad-plankovy' ...];
var clones = {};
keys.forEach(function(key){
clones[key] = $('.' + key).clone();
}
$("[name='reset']").click(function(){
keys.forEach(function(key){
$('.' + key).html(clones[key];
}
});
In lodash, it's move elegant:
var keys = ['launchPad-plankovy-tvarovany', 'launchPad-plankovy' ...];
var clones = _.zipObject(keys, _.map(keys, function(key){
return $('.' + key).clone();
});
I'm getting those 2 vars from the DOM:
var get_category = $('#category').find('.current').attr('rel');
var get_subcategory = $('#subcategory').find('.current').attr('rel');
and I want here to find the classes in my DOM and show it
$('.filter-result').find('.'+get_category, '.'+get_subcategory ).show();
But I need to write it inside the .find() only if the variables are exist
I hope it answers your question:
var get_category = $('#category').find('.current').attr('rel');
var get_subcategory = $('#subcategory').find('.current').attr('rel');
var classes = [];
if (get_category) {
classes.push('.' + get_category);
}
if (get_subcategory) {
classes.push('.' + get_subcategory);
}
//if get_category or get_subcategory were found
if (classes.length) {
$('.filter-result').find(classes.join('')).show();
}
I do like Gabriels answer because it is very simple another option that works well and is extensible all you would have to do add another selector is add it to the selectors array. It is a little bit more advanced using javascripts filter and map array methods though.
var get_category = $('#category').find('.current').attr('rel');
var get_subcategory = $('#subcategory').find('.current').attr('rel');
var selectors = [get_category, get_subcategory];
var query = selectors.filter(function(elem) {
if (elem) { return elem };
}).map(function(elem){
return '.' + elem;
}).join(', ')
$('.filter-result').find(query).show();
I have an object with a bunch of properties. Some properties are to be displayed in input elements, some in labels.
So, my code looks like this:
var data = getMyData();
var propNames = Object.keys(data);
var i, propName, elem;
for (i = 0; i < propNames.length; ++i) {
propName = propNames[i];
elem = $("#" + propName);
if (elem.is('input')) {
elem.val(data[propName]);
} else {
elem.html(data[propName]);
}
}
Is it the right way to do it in jquery? Cause it looks kinda ugly...
Thanks.
I find it easier to store the method name in a variable (text/val), so that we don't have so much code repetition (the conditional in your code makes for unnecessary repetition).
Also, since you're anyhow using jQuery, you might as well use each. It simplifies all of it into this:
$.each(getMyData(), function (key, val)
{
var el = $("#" + key),
method = el.is('input') ? 'val' : 'text';
el[method](val);
});
Here's the fiddle: http://jsfiddle.net/pFbSf/
If you don't like storing the method name in a variable, use this instead:
$.each(getMyData(), function (key, val)
{
var el = $("#" + key);
el.is('input') ? el.val(val) : el.text(val);
});
Here's the fiddle: http://jsfiddle.net/GQTZv/
If you worry about jQuery not using hasOwnProperty, you can run the check yourself:
var data = getMyData();
$.each(data, function (key, val)
{
if ( ! data.hasOwnProperty(key) ) return;
var el = $("#" + key);
el.is('input') ? el.val(val) : el.text(val);
});
Here's the fiddle: http://jsfiddle.net/GQTZv/1/
I think you can rewrite that for-loop with the jQuery .each() function, which can iterate over any array or object. It takes a callback function, which is given the index (or key) and the value of each item.
In your example it would be something like:
jQuery.each(data, function(key, value) {
elem = jQuery("#" + value);
if (elem.is('input')) {...
Check out the docs for jQuery.each()
Assuming you're trying to fill either an input or a textarea, you should be able to replace this with:
var data = getMyData();
var propNames = Object.keys(data);
for (i = 0; i < propNames.length; ++i) {
$("input#"+propNames[i]).val(data[propNames[i]);
$("textarea#"+propNames[i]).html(data[propNames[i]);
}
You might even get away with replacing the two jQuery selectors with:
$("input#"+propNames[i]).val(data[propNames[i]).html(data[propNames[i]);
Since input elements don't have innerHTML and textarea elements don't have val, this should work as-is. Hackish, but it's succinct.
I don't see how that looks ugly but I don't understand why you need Object.keys... You can simplify it a bit with a regular for...in:
var data = getMyData(),
d, $el;
for (d in data) {
$el = $('#'+ d);
if ($el.is('input')) {
$el.val(data[d]);
} else {
$el.html(data[d]);
}
}
Everything looks fine to me Mark. The one thing I would highly advise against is using a new Object prototype method like Object.keys, which is only available in IE9+ and other newer browsers. Instead either create the prototype for it before all of your JS (something I actually don't like doing) or instead have a replica work-around global function / namespace method that takes care of it like function getkeys() at the bottom.
http://jsfiddle.net/WJ24q/1/
for (i = 0; i < propNames.length; ++i) {
var el = $("#" + propNames[i]),
_d = data[propNames[i]];
// you could also use a simple ternary instead of the if/else
el.is('input') ? el.val(_d) : el.html(_d);
}
Function instead of Object.keys:
function getKeys (obj){
var keys = [];
for(var key in obj){
keys.push(key);
}
return keys;
}
I have a list of variables or variable names stored in an array. I want to use them in a loop, but I don't want to have to use eval(). How do I do this? If I store the values in an array with quotes, I have to use eval() on the right side of any equation to render the value. If I store just the variable name, I thought I'd be storing the actual variable, but it's not working right.
$(data.xml).find('Question').each(function(){
var answer_1 = $(this).find("Answers_1").text();
var answer_2 = $(this).find("Answers_2").text();
var answer_3 = $(this).find("Answers_3").text();
var answer_4 = $(this).find("Answers_4").text();
var theID = $(this).find("ID").text();
var theBody = $(this).find("Body").text();
var answerArray = new Array();
answerArray = [answer_1,answer_2,answer_3,answer_4,theID,theBody]
for(x=0;x<=5;x++) {
testme = answerArray[x];
alert("looking for = " + answerArray[x] + ", which is " + testme)
}
});
You can put the values themselves in an array:
var answers = [
$(this).find("Answers_1").text(),
$(this).find("Answers_2").text(),
$(this).find("Answers_3").text(),
$(this).find("Answers_4").text()
];
for(x=0;x<=5;x++) {
alert("looking for = " + x + ", which is " + answers[x])
}
EDIT: Or even
var answers = $(this)
.find("Answers_1, Answers_2, Answers_3, Answers_4")
.map(function() { return $(this).text(); })
.get();
If your answers share a common class, you can change the selector to $(this).find('.AnswerClass').
If you need variable names, you can use an associate array:
var thing = {
a: "Hello",
b: "World"
};
var name = 'a';
alert(thing[name]);
This would make it easier to get the array populated.
var answers = new Array();
$("Answers_1, Answers_2, Answers_3, Answers_4", this).text(function(index, currentText) {
answers[index] = currentText;
});
As others have mentioned, if you can put the variables in an array or an object, you will be able to access them more cleanly.
You can, however, access the variables through the window object:
var one = 1;
var two = 2;
var three = 3;
var varName = "one";
alert(window[varName]); // -> equivalent to: alert(one);
Of course, you can assign the varName variable any way like, including while looping through an array.
I have two arrays, one is full of strings, the other is an array of objects. The indexes on each correspond, and I want to replace the text of each of the objects in my object array with the corresponding text in my string array.
For example, I have an array like this:
var textarr = ["value1", "value2", "value3"]
and a Jquery object array that contains a bunch of span elements:
var spans = $("span.myClass");
var spanarr = $.makeArray(spans);
I'm trying to use $.each() to iterate over each of the spans and use the corresponding index of my text array to assign a text value to the current span.
I've tried a couple different ways, and nothing seems to work. I'm missing some logic here, but why wouldn't this work?:
i = 0;
jQuery.each(spanarr, function() {
$(this).text(textarr[i]);
i++;
});
EDIT:
I think maybe the rest of my function might be causing this not to work. Here's the entire script:
$("span input:radio").click(function() {
if (($(this).is(":checked")) == true) {
var parent = $(this).parent();
var aunts = parent.parent().children();
var parentIndex = aunts.index(parent);
var indexToNthChild = parentIndex + 1;
var otherSpans = $(".DropDownMenu span:nth-child(" + indexToNthChild + ")");
var position = parent.position();
var topValue = position.top;
var smallPrice = otherSpans.children("span.dropDownPrice");
var pricearr = jQuery.makeArray(smallPrice);
var textarr = [];
jQuery.each(pricearr, function() {
textarr[i] = $(this).text();
});
alert(textarr); // Returns all the text values expected in array
var changers = $(".bigPriceChanger");
var changerarr = $.makeArray(changers);
$(".DropDownMenu").css({ "top": "-" + topValue + "px" });
$(".DropDownMenu span").css("background-image", "none");
parent.css({ "background": "#f3f1e7 url(assets/images/branding/DropDownArrow.gif) no-repeat right" });
otherSpans.css({ "background": "#f3f1e7 url(assets/images/branding/DropDownArrow.gif) no-repeat right" });
alert(changearr); // Returns all span objects in array
i = 0;
jQuery.each(changearr, function() {
$(this).text(textarr[i]);
i++;
});
}
});
Try
$("span.myClass").each(function (i) {
$(this).text(textarr[i]);
});
I think you don't need the call to makeArray. Just write:
i = 0;
jQuery.each($("span.myClass"), function() {
$(this).text(textarr[i++]);
});
I hate to end the question with a 'it was all a dream afterall' copout, but it turns out my browser was funked.
I've since checked my script (and the million variations of it that everyone suggested) in IE8 and someone else's firefox, and low and behold, it works.
You might want to try something like this:
var spans = $("span.myClass");
for(i=0;i<spans.length;i++){
spans[i].innerHTML = textarr[i];
}
You can think of a jQuery object like an extended version of an array. You can use length and [i] in reference to the number of DOM elements selected and the DOM element at a certain index respectively.
Your code is fine, although the makeArray call is redundant
There must be an error somewhere else,
here is your code running fine in firefox
http://jsbin.com/oxiwu
to edit go to http://jsbin.com/oxiwu/edit
I think your code is not working because the variable i was defined outside its scope.
Probably there is a better solution, but you could try the following:
function createF() {
var i = 0;
function f() {
$(this).text(textarr[i]);
i++;
}
return f;
}
f = createF();
jQuery.each(spanarr, f);
What's the reason for calling $.makeArray? You can iterate through your spans like this...
$("span.myClass").each(function(i) {
alert(textarr[i]);
$(this).text(textarr[i]);
});