Call Javascript Function with argument and use argument as a variable name - javascript

I've the following snip of a code:
var about = "about.html";
function loadPage(target){
$("#dashboard").load(target);
}
$(".nav li").click(function(){
loadPage($(this).attr("class"));
});
So when I click on a button like <li class="about">, target is = about.
But in that way, $("#dashboard").load(target); doesn't load the variable about which is the html-file which I want to load.
So how is it possible to call the variable in this way?

You seem to miss the .html part. Try with
$("#dashboard").load(target+'.html');
But, supposing you have only one class on your li element, you'd better use this.className rather than $(this).attr("class").
EDIT :
if you want to use your about variable, you may do this :
$("#dashboard").load(window[target]);
But it would thus be cleaner to have a map :
var pages = {
'about': 'about.html',
'home': 'welcome.jsp'
}
function loadPage(target){
$("#dashboard").load(pages[target]);
}
$(".nav li").click(function(){
loadPage(this.className);
});

A stupid answer : create a <a> tag, and set its href attribute to the correct value.
Otherwise :
A standard way to store key: values pairs in javascript is to use a plain object :
var urls = {};
urls['about'] = 'mysuperduperurlforabout.html';
function loadPage(target) {
var url = urls[target];
//maybe check if url is defined ?
$('#dashboard').load(url);
}

$(".nav li").click(function(){
loadPage($(this).attr("class") + ".html");
});
or
$("#dashboard").load(target+".html");

You can call the variables like this (if that's what you asked):
var test = 'we are here';
var x = 'test';
console.log(window[x]);
It's similar to the $$ in PHP. The output will be:
we are here in the console window.

You could put the "about" as an object or array reference similar to:
var pageReferences = [];
pageReferences["about"] = "about.html";
var otherReference = {
"about": "about.html"
};
function loadPage(target) {
alert(pageReferences[target]);
alert(otherReference[target]);
$("#dashboard").load(target);
}
$(".nav li").click(function () {
loadPage($(this).attr("class"));
});
Both of these alerts will alert "about.html" referencing the appropriate objects.
EDIT: IF you wished to populate the object based on markup you could do:
var otherReference = {};
$(document).ready(function () {
$('.nav').find('li').each(function () {
var me = $(this).attr('class');
otherReference[me] = me + ".html";
});
});
You could even store the extension in an additional attribute:
var otherReference = {};
$(document).ready(function () {
$('.nav').find('li').each(function () {
var me = $(this).attr('class');
otherReference[me] = me + "." + $(this).attr("extension");
});
});
Better would be to simply put the page reference in a data element:
<li class="myli" data-pagetoload="about.html">Howdy</li>
$(".nav li").click(function () {
loadPage($(this).data("pagetoload"));
});

Related

Optimizing JQuery

I have Jquery code that looks like this. Is there a way to optimize this code? What happens if the image doesn't have a title attribute? Should I insert a case for using the value of the alt attribute as a backup and If I'm chaining the .attr() function multiple times, then it'd be cleaner code I you just ran the .attr() function a single time passing a value pair object of all my properties to the function. How can I do this ?
$(function() {
$('.component-individual-detail-profile').each(function() {
var $self = $(this), $images = $self.find('.photos');
$images.find('li').click(function(e) {
e.preventDefault();
var thumb = $(this);
$images.find('.selected')
.attr('src', thumb.find('img').attr('src'))
.attr('alt', thumb.find('img').attr('alt'))
.attr('title', thumb.find('img').attr('title'));
});
});
});
You can store the attributes in a array, and cache the $thumb.find('img') selector:
$('.component-individual-detail-profile').each(function() {
var $self = $(this);
var $images = $self.find('.photos');
$images.find('li').click(function(e) {
e.preventDefault();
var $thumb = $(this).find('img');
var $selected = $images.find('.selected');
$.each(['src', 'alt', 'title'], function(index, attrName){
$selected.attr(attrName, $thumb.attr(attrName));
});
});
});
Have you considered var thumb = $(this).find("img") for starters? Anywhere your code repeats function calls, you're probably doing something wrong.
Regarding "what if there is no attribute", you can do thumb.attr('title') || thumb.attr('alt'), using the logical or (||) to provide a value if the first one doesn't exist.
According to the documentation, you can do...
$images.find('.selected').attr({
src: thumb.attr('src'),
alt: thumb.attr('alt'),
title: thumb.attr('title') || thumb.attr('alt')
});

Javascript/jQuery set global variable of an unknown element

EDIT
TO BE DELETED. Issue was not code based but the global variable help was greatly appreciated and I did learn a lot.
How would you set a Global variable of an unknown element.
I need to pass a variable when an element is clicked to the rest of the functions in my code. I know I am somewhat close. I just need a bit of help.
My code is below. I am trying to pass my 'sampleName' and 'samplePath' to the 'loadPage' function only when an element is clicked.
(function ($) {
//Original Variables
//var sampleName = 'Book1'
// samplePath = '/Book1/'
//Want dynamic variables
var sampleName;
var samplePath;
$(document).on("click", ".sampleDiv", function (event) {
sampleName = $(this).attr("sample") || '';
samplePath = 'Books/' + sampleName;
//alert(sampleName);
// alert(samplePath);
});//End click
function loadPage(page) {
var img = $('<img />');
img.load(function () {
var container = $('.Book .p' + page);
img.css({ width: '100%', height: '100%' });
img.appendTo($('.Book .p' + page));
container.find('.loader').remove();
});
img.attr('src', samplePath + 'pages/' + page + '.jpg');
}
})(jQuery);
Thanks in advance.
/EDIT/
Hmmm. I must be asking this the wrong way.
More explanation.
Originally my code had 2 variable set statically.
Example:
var sampleName = 'Book1',
samplePath = '/Book1/'
What I am trying to do is make those variables more dynamic and set them when the
<div sample='Book1'></div>
is clicked on the variables (mainly the 'Book1' part) changes. Each 'Book' will have a different number (Book1, Book2, Book3, etc). I want to make the variables get set depending on which one gets clicked on. The attr("sample") on my DIV will determine the Book number. So when the DIV is clicked on the attr("sample") will be the variable's value.
Hope this helps with my issue in explaining more.
Just put all your global variables outside of your function.
var sampleName;
var samplePath;
(function ($) {
$(document).on("click", ".sample", function (event) {
sampleName = $(this).attr("sample") || '';
samplePath = 'Books/' + sampleName;
//alert(sampleName);
// alert(samplePath);
});//End click
If the variable is GLOBAL, it must be declared OUTSIDE the (function ($) {
.. ex:
var sampleName;
var samplePath;
(function ($) {
...
})(jQuery);

get and append first four images from url

that's pretty much it, how do I get the first four images from whatever url and then append them to a specified element
something like this:
$('document').ready(function(){
var thing = $.get('thing.html');
thing.slice(0,2).appendTo(".appending");
});
Try this
$('document').ready(function () {
var thing = $.get('HTMLPage.htm',
function (markup, b) {
var $page = $(markup);
$page.each(function (index, item) {
if (item.tagName == "IMG") {
$(item).appendTo(".appending");
}
});
});
});
Try this:
$('document').ready(function(){
var thing = $.get('thing.html');
thing.find('img').slice(0,4).appendTo(".appending");
});
$.get('thing.html', function(html){
//depending on what 'html' is made of, you may need to wrap it in a node
var $imgs = $(html).find('img').slice(0,4);
$(imgs).appendTo(".appending");
});
If you're expecting thing to contain HTML, try
$('document').ready(function(){
var thing = $.get('thing.html');
$(thing).filter('img').slice(0,4).appendTo(".appending");
});
.find('img') search only in descendants so if your thing contains img direcly It wouldn't work, try filter() instead http://jsfiddle.net/ouadie/UnNd9/
filter() – search through all the elements.
find() – search through all the child elements only.
http://www.mkyong.com/jquery/difference-between-filter-and-find-in-jquery/

How to get outer element value in JavaScript

I have the following jQuery code:
$('.active #search').on('mouseout', function () {
$('#search_box #search').not('.active').each(function(){
this.value = $('.active #search')[0].value;
})
});
It works, but I have to call $('.active #search') twice. How can I refer to the $('.active #search') array from within my inner function?
P/S: I know I'll be complained about giving multiple elements same ID, but this seem to be generated by Rails automatically (text_field_tag).
I think this is what you're looking for:
$('.active #search').on('mouseout', function () {
var val = $(this)[0].value; //cache value of $('.active #search').
$('#search_box #search').not('.active').each(function () {
this.value = val;
})
});
You can do something like below. I added self = $(this)
$('.active #search').on('mouseout', function () {
var self = $(this);
$('#search_box #search').not('.active').each(function(){
this.value = self[0].value;
});
});
Here is a link to very good explanation of 'this' keyword, explained by Jeffrey Way
tutsplus.com/lesson/the-this-keyword
Therese several ways of achieving this:
var activeSearch = $('.active #search');
activeSearch.on('mouseout', function () {
$('#search_box #search').not('.active').each(function(){
this.value = activeSearch.val();
})
});
notice that since this is an id you are querying for you should have only one element so you can replace activeSearch[0].value with activeSearch.val();
second way:
$('.active #search').on('mouseout', function () {
var activeSearch = $(this);
$('#search_box #search').not('.active').each(function(){
this.value = activeSearch.val();
})
});
when in an event handler $(this) will give you a jquery object of the event sender. you can further simplify it by ignoring jquery and just using plain elements by doing the following:
$('.active #search').on('mouseout', function () {
var activeSearch = this;
$('#search_box #search').not('.active').each(function(){
this.value = activeSearch.value;
})
});
this is the same as above but you arent dealing with jquery objects.
What you end up using depends on you but the final code snippet would be my preferred way.
You can use $(this) instead of using the $('.active #search')

Reference JS object to DOM element

How can I reference specific DOM element to specific JS object?
For example, i have an array of customers. Using jQuery, for each customer I create LI with checkbox and span for customers name. When checkbox is clicked, I need to do some processing on that customer JS object. The question, how i can get this JS object an easy way.
Currently I have following:
$(customers).each(function(){
$("<li>").append($("<input type=\"checkbox\"").attr("id","chk_" + this.ID)).append($("<span>").text(this.Name)).appendTo("#ulCustomers");
});
$("#ulCustomers input[type=checkbox]").bind("click",function(){
var customerId = $(this).attr("id").replace("chk_","");
var CustomerObj = $(customers).filter(function () { return this.ID == customerId }).get(0);
myProcess(CustomerObj); //Two above two lines are just for select correct customer from array.
});
I believe in world of JS and jQuery exists more elegant way to do it.
Thanks
You can use jquery data function
$(customers).each(function() {
var elem = $("<li><input type='checkbox'><span>" + this.Name + "</span></li>").appendTo("#ulCustomers");
elem.find("input").data("customer", this);
});
$("#ulCustomers input[type=checkbox]").click(function() {
var CustomerObj = $(this).data("customer");
myProcess(CustomerObj);
});
Could you not bind the click event to a closure with a reference to the relevant Customer object?
like this
$(customers)
.each(function(){
var custObj = this;
$("<li>")
.append(
$("<input type=\"checkbox\"")
.append($("<span>")
.text(this.Name))
.appendTo("#ulCustomers")
.bind("click", function(){
myProcess(custObj);
})
});
I would use jQuery data, just like this:
$("checkbox").data('customer', this.ID);
To retrieve the data:
$("#ulCustomers input[type=checkbox]").bind("onchange",function(){
var customerId = $(this).data("customer");
var CustomerObj = $(customers).filter(function () { return this.ID == customerId }).get(0);
myProcess(CustomerObj); //Two above two lines are just for select correct customer from array.
});
Additionally, don't use click event on check-boxes, use onchange event ;)

Categories