Problems to get functions argument outside the scope - javascript

I want to get functions argument outside the scope, but have some kinds of problems to do that.
I have tried to get the value by this code: var text = $.commentString.text();
Live Demo
JQuery:
function addComment(commentString) {
var container = $('#divComments');
var inputs = container.find('label');
var id = inputs.length + 1;
var div = $('<div />', {
class: 'CommentStyle'
});
$('<label />', {
id: 'comment' + id,
text: commentString
}).appendTo(div);
var $edit = $('<p />', {
class: 'edit',
text: 'Edit'
}).addClass('edit').appendTo(div);
div.appendTo(container);
}
$('#divComments').on('click','.edit',function () {
var text = $.commentString.text();
});

In JavaScript it's not possible to get access to a variable outside of the scope which it was declared in. You could declare the variable outside of your function, but it will be overwritten every time the function runs - it doesn't look like this is the behaviour you're after.
What you can do in this example is use jQuery to traverse the DOM and find the text which you require.
$('#divComments').on('click','.edit',function () {
var text = $(this).parents(".CommentStyle").find("label").text();
});

then just declare a variable outside the function:
var someCommentString;
function addComment(commentString) {
someCommentString = commentString;
...

or u can try other way to get value but not sure its correct or not
$('#divComments').on('click','.edit',function () {
$(this).prev().text()
});

Related

Rewrite the code in a loop

I'm just learning JS and jQuery, so I can not reduce the normal code is shown below:
var menuBtn = '#menu',
classMenuOpen = 'side_menu_open',
aboutBtn = '#about',
classAboutOpen = 'side_about_open',
dateBtn = '#date',
classDateOpen = 'side_date_open',
closeBtn = '.header__menu a, .close';
// Menu Side
$(menuBtn).on('click', function() {
$('html').toggleClass(classMenuOpen);
});
$(closeBtn).not(menuBtn).on('click', function() {
$('html').removeClass(classMenuOpen);
});
// About Side
$(aboutBtn).on('click', function() {
$('html').toggleClass(classAboutOpen);
});
$(closeBtn).not(aboutBtn).on('click', function() {
$('html').removeClass(classAboutOpen);
});
// Date Side
$(dateBtn).on('click', function() {
$('html').toggleClass(classDateOpen);
});
$(closeBtn).not(dateBtn).on('click', function() {
$('html').removeClass(classDateOpen);
});
I would like to write a loop (example below) , but knowledge is not enough. I hope someone can help, thanks in advance ;)
['menu', 'about', 'date'].forEach((selector) => {
$('.' + selector + ' .scrollbar-inner').scrollbar({
onScroll: function(y, x){
$('.' + selector + ' .scrollbar-inner').toggleClass('scroll-shadow', y.scroll >= 5);
}
});
});
maybe something like this:
// wrap in IIFE for scope containment
(function($) {
// Setup button keys
const buttons = ['menu', 'about', 'date'];
// click handler
const createClickHandler = value => {
// set loop variables
let selector = `#${value}`
, className = `side_${value}_open`;
// create event triggers
$(selector).on('click', e => $('html').toggleClass(className));
$('.header__menu a, .close').not(selector).on('click', e => $('html').removeClass(className))
};
// iterate keys and apply handler method
buttons.forEach(createClickHandler);
})(jQuery);
Here is the loop you are looking for!
In the forEach() loop you are looping through the array of strings, component holds the string element (so here 'menu', 'about', etc...). Then inside the loop's body set two variables:
selector is the selector string
classOpen is the class name of an element you have associated with the component
Then you basically write the same code using only those two variables instead of writing the code three times with set strings.
let closeBtn = '.header__menu a, .close'
['menu', 'about', 'date'].forEach(function(component) {
let selector = '#' + component;
let classOpen = '.side_' + component + '_open';
$(selector).on('click', function() {
$('html').toggleClass(classOpen);
});
$(closeBtn).not(selector).on('click', function() {
$('html').removeClass(selector);
});
});

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);

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

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"));
});

.append link will not fire onclick function

I've searched around I cannot find the answer to this. In my code, a link is created inside of a div and given an onclick value to pass an argument to a function. I cannot figure out why it will not fire.
var imgCount = 0;
var curImg;
function resetImg(target) {
alert(target);
}
$(".add").click(function () {
imgCount = imgCount + 1;
curImg = "theImg" + imgCount;
//Here we add the remove link
$('#links')
.append('Call Function');
$('.dynamic').css('display', 'block');
});
Here's the fiddle:
http://jsfiddle.net/stewarjs/4UV7A/
I've tried using .click() when creating the link, but the argument being passed needs to be unique to each link. I've tried grabbing $(this).attr("id") but the value comes back undefined.
Thanks for any and all help.
Jeff
Rather than try to mangle HTML into JavaScript, I suggest you use the jQuery methods already available to you.
$('#links')
.append($("<a>").attr('href', '#').on('click', function () { resetImg(curImg);
}).addClass('dynamic').text('Call Function'));
http://jsfiddle.net/ExplosionPIlls/4UV7A/1/
remove javascript: from onclick, it should like like this: onclick="resetImg(\'' + curImg + '\');"
There's always a way to get rid of onclick handlers. Here's how I'd do it:
var image_count = 0;
$('#links').on('click', '.dynamic', function(e) {
e.preventDefault()
alert($(this).data('image'));
});
$('.add').click(function () {
$('<a />', {
'href': '#',
'data-image': 'theImg' + (++image_count),
'class': 'dynamic',
'text': 'Call function'
}).appendTo('#links');
});
Demo: http://jsfiddle.net/4UV7A/4/

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')

Categories