3 layers of embedded quotes, JS function not registering variable - javascript

The code looks something like this:
<?php
$page->startscript();
echo "
function f1(id){
$('#def').html('<button class=\'btn btn-danger\' onclick=\'f2(id);\'>act</button>');
}
function f2(id){
alert(id);
}
";
$page->endscript();
?>
The startscript(), endscript() thing works fine, it just allows me to add JS to the page. What doesn't work is id isn't carried over from f1 to f2, its just returning blank. I think it has something to do with the quotes and not being treated as a variable. If I pass an int as the parameter for the onclick attribute it works fine.

Variables aren't expanded inside strings in Javascript (ES6 adds "template strings", which support this), you need to use concatenation. And assuming id is a string, you need to put quotes around it in the function call.
echo"
function f1(id){
$('#def').html('<button class=\'btn btn-danger\' onclick=\'f2(\"' + id + '\");\'>act</button>');
}
function f2(id){
alert(id);
}
";

It's got to do with the context of your f2 function.
Since the function isn't present on the page, the scope in which the rendered JS is looking can't really find the function you've declared.
I've created a basic fiddle that shows you how you can achieve what you're looking to do here. JSFiddle
Basically, your js will call the f1 function like so:
function f1(id) {
$('#def').append('<button class="btn btn-danger" onclick="f2(' + id + ');">act</button>');
}
f1("10");
your HTML will need to look something like this:
<div id="def">
</div>
<script>
function f2(id){
alert(id);
}
</script>
Also, the JS that you're rendering is literally passing in the id to f2 as a string and not the value.
Hopefully you can see what you need to do.

Related

Call javascript function error

I have a problem, i have to call a function from a button onclick().
Javascript :
function deleteFolder(elemento){
var form=document.getElementById(elemento);
var conf=confirm("Sei sicuro di eliminare questa cartella?\nL'eliminazione sara' definitiva");
if (conf === true)
form.submit();
}
This function get a paramater made by php ,the pRoblem is that if this parameter has some space inside, the function is not called ..
deleteFolder(FolderName) --> It works
deleteFolder(Folder Name) --> of course it doesnt works
From php i just scan directories and put names of them in multiple form with foreach() function.
So the question is :
1) How from php i can put parameter that works with calling javascript's function with spaces inside?
2) If i have a directory called "Folder's name", it's enough put addslashes in $_POST to bypass XSS? because it cut all next the apostrophe and became :
HTML
<button onclick="deleteFolder(Folder)">
Thanxs for any suggestions, i can't find anything similar already in this forum.
I am assuming that you are passing a string to the deleteFolder() method. If that is the case, use the following code.
<button onclick="deleteFolder('FolderName')">
<button onclick="deleteFolder('Folder Name')">
You should use quotes to indicate that you are passing a string to the function. This should fix your problem.
You can put the actual folder name in a separate attribute say folder-name and in the id have incremental numbers, with this being in place following change would be needed in your JavaScript function.
HTML
<button folder-name="Folder" onclick="deleteFolder(id)">
JavaScript
function deleteFolder(elemento){
var form=document.getElementById(elemento);
var folderName = form.getAttribute('folder-name');
// then use the folderName however you want it.
}
Thanxs to all replies ! =)
I solve it adding " (--> " ) in php
first
"<button onclick='deleteFolder(".$elem."); return false;'>Elimina</button>"
next
"<button onclick='deleteFolder("".$elem.""); return false;'>Elimina</button>"
So the parameter became a string and can be passed to the function =)

How may I call a method of the same object inside .append()?

generarGrilla() creates an output that has some html buttons.
Each button calls a method that exist in the same object guardarReserva()
When I load the page guardarReserva() is called without clicking any button, because this line console.log("whatever "+this.i); gets printed into the console.
If I do click one of the buttons that have the listeners, nothing happens.
var reservasAPP = {
i:0,
nombre: function () {
return $('#h09').val();
},
guardarReserva:function(){
var reservaConfirmada = $('#horario'+this.i).html('--> '+this.nombre());
console.log("whatever "+this.i);
return false;
},
generarGrilla: function(){
//it loads from html using jQuery(document).ready();
for(this.i=1; this.i<13; this.i++){
var impresionGrilla = $('#grilla').append("<button class=\"btn btn-primary btn-xs\" onclick=\"return "+this.guardarReserva()+"\">Reservar</button>");
};
},
}
You're actually running guardarReserva() within your .append() function. That is why you see the immediate console.log("whatever "+this.i); when you first open the browser.
I think you want the onclick of that button to call that function. For that (assuming reservasAPP is in the window namespace) you can do something like this:
var reservasAPP = {
i:0,
nombre: function () {
return $('#h09').val();
},
guardarReserva:function(){
var reservaConfirmada = $('#horario'+this.i).html('--> '+this.nombre());
console.log("whatever "+this.i);
return false;
},
generarGrilla: function(){
//it loads from html using jQuery(document).ready();
for(this.i=1; this.i<13; this.i++){
// ---Change is here ------------------------------------------------------------------------|
// V
var impresionGrilla = $('#grilla').append("<button class=\"btn btn-primary btn-xs\" onclick=\"return reservasAPP.guardarReserva();\">Reservar</button>");
};
},
}
Why I couldn't use "this" and I need to use "reservasAPP"
So, let's look at some of your original code (I'll slightly modify it so it is a bit shorter) and see why it wasn't working.
The line where the good stuff happens is within generarGrilla, within the for loop where you call the .append() function.
var i_g = $('#grilla').append('<button onclick="return ' + this.guardarReserva() + '">Reservar</button>');
Now you are correct in the idea that when that line of code executes, the this keyword is pointing at the reservasAPP object. However, what you are doing is not setting the onclick event for the button to run this.guardarReserva(), you are immediately running the this.guardarReserva() function.
Let's look at a small, semi-related example:
var n = function() {
return 'John';
};
var str = 'Hello, ' + n();
Now, what is the value of our variable str? Well, we are doing two things:
First, we have a string literal Hello, .
We are then concatenating it using the + operator with what the function n() returns.
Notice how we are going to use what n() returns rather than the literal 'n()' (string or function). This is because we are actually calling the n() function.
So, at the end of the day:
// str = 'Hello, John';
So, let's go back and look at your original code. What is actually going on there? Well, you are selecting all elements with id set to grilla (I'm assuming there is only one of those) then calling the jQuery append() function. .append() can accept a string as its argument, and it'll take that string, and insert it into the DOM as HTML.
Your string is concatenating three different things.
'<button onclick="return '
The return value of this.guardarReserva()
'">Reservar</button>'
Your guardarReserva function at the end returns false, which when concatenated with a string, uses its .toString() method, which in this case returns the actual word 'false'.
So, if you'd look at your HTML from before, you'd see your HTML code looked like:
<div id="grilla">
<button onclick="return false">Reservar</button>
</div>
Which is not at all what you wanted.
Instead, to fix that issue, I had you pass in one long string (which includes the function name you do want to call). So, your HTML ended up looking like:
<div id="grilla">
<button onclick="return reservasAPP.guardarReserva()">Reservar</button>
</div>
OK, so that's why the function was running right away, and why your button wasn't working. So we need to pass in the function as a string for the HTML button to know to run that function when it is clicked.
So, why can't you pass in the string:
'<button onclick="return this.guardarReserva()">Reservar</button>'
It has to do with how the browser evaluates the this keyword within that button.
In fact, let's do an experiment
<button onclick="console.log(this);">CLICK ME</button>
What happens when I click the button? You can do this experiment yourself. You'll see that it actually logs the literal button. Because within the buttons inline onclick, this refers to the button itself!
You can doubly verify this with this code:
<button id="button-1" onclick="console.log(this.id);">CLICK ME</button>
And see that it logs the string "button-1" (aka, the button's id).
So, if this refers to the button, we can't leave that context to get at our reservasAPP object! By referencing the reservasAPP object directly (assuming it was declared in your main <script></script> tag, thus placing it in the accessible window object), we can access that object, and thus its inner properties.
SIDE NOTE:
I would use a different method altogether for attaching our onclick handler.
I'd use jQuery's .on() function. Here is an example of how you could define generarGrilla:
generarGrilla: function() {
for (this.i = 1; this.i < 13; this.i++) {
// Save our `this` object for later
var self = this;
var button = $('<button class="btn btn-primary btn-xs">Reservar</button>');
// Set the `onclick` handler for our button (that isn't in the DOM yet)
button.on('click', function(event) {
// Use our saved `self` variable, which points to `reservasAPP`
return self.guardarReserva();
});
// `onclick` is set, insert our button into the DOM
var impresionGrilla = $('#grilla').append(button);
};
}
Now, when you run reservasAPP.generarGrilla();, it'll insert your buttons, and they'll all have onclick event handlers.
You can read this post on why'd some people think it's better to use attached event handlers vs inline JS on HTML attributes.
Have you tried reservasAPP.guardarReserva() instead of this.guardarReserva() ?

Passing JS Object via HTML string

Having problems passing a JS object to a JS method via an HTML String. Here's a part of the HTML String:
onclick='addGrpMember("+c+"); return false;'
When I click to invoke this method I see this: Unexpected identifier
I can easily pass in properties of this c Object a la:
onclick='addGrpMember(\""+ c.contactName +"\",\""+ c.displayName +"\"); return false;'
And that works just fine.
What am I missing here? By the way, "c" is passed into the method as an arg. (where I'm executing this code).
Thanks for any helpful tips!
Updated with full code:
contact = "<tr><td style='width:60px; padding:12px 6px' title='"+ c.contactName +"'><span class='contactAvatar'><img src='<%= context %>/app/user/image?loginName="+ c.contactName +"' alt='' /></span></td><td style='padding-top:12px'><span class='contactTitle'>"+ c.displayName +"</span><br/><span class='contactTitleCompany'>"+c.title+ " at " +c.companyName+"</span><br/><a href='mailto:"+c.contactName+"'><i class='icon-envelope'></i> "+c.contactName+"</a></td><td style='padding-top:30px;padding-right:10px;text-align:right'><a href='#' data-toggle='tooltip' data-placement='right' title data-original-title='Add Member' onclick='addGrpMember("+c+"); return false;' class='addIcon'></a></td></tr>";
And the method:
function addGrpMember( c ){
selectedGroup.members.push( c );
populateSearchResults( selectedGroup.members, 'groups' );}
You will need to convert c into a JSON string. Assuming you are making this string in JavaScript.
onclick='addGrpMember("+JSON.stringify(c)+"); return false;'
JSON.stringify is IE 8+.
With that said... there is probably a better way to do what you are trying to do, but without seeing your entire method we can't really comment on that much. Generally inline JavaScript isn't the way to go.
I think , no need to concat the string or extract the object elements, all you need is to put this code on the button event onClick
onclick='addGrpMember(c); return false;'
if c is your javascript object
It should work just passing in the object variable name:
<button onClick="addGrpMember(c);">Add Group Member</button>
Then in your JavaScript, something like:
var c = {
contactName : "value1",
displayName : "value2"
};
var addGrpMember = function (groupMember) {
// Do something with the group member
return false;
};
Here is a working fiddle with some similar code: http://jsfiddle.net/vgF8C/

javascript change name of called function

Hi all im very new to javascript so please be gentle.
im mixing php with my calls and I have a slight issue.
I need to alter the function name that is called in an onclick event.
<div class=\"span4\" id=\"pass\">
<button class=\"btn btn-block btn-large btn-warning\" id=\"bypass\" disabled onclick=\"pass(); return false;\">
-
</button>
</div>
above is the div with the std call.
before this point some variables are set from another function call and I need to change the above call to "pinpass2() or pinpass3 etc.
function pincheck(id,type,lastid,pin){
document.getElementById('fade').style.display=\"block\";
document.getElementById('calc').style.display=\"block\";
var staffid = id;
document.getElementById('bypass').onclick = function (){\"pinpass\"+staffid();
return false;
};
}
the above is the function that should do it but i can't seem to get it working.
Any help appreciated.
p.s if i include the following into the pincheck function the desired staffid is diaplayed
alert(\"staff id\"+staffid);
document.getElementById('bypass').onclick = pinpass2;
That should work just fine. pinpass2 is already a function, you can assign it to onclick like any other object (yes, functions are objects in Javascript). So just change the onclick when you need it.
If you can't detect changes to the result of staffid(), then you should use a switch instead.
document.getElementById('bypass').onclick = function() {
switch(staffid()) {
case 1: pinpass(); break;
case 2: pinpass2(); break;
default: pinpass3(); break;
}
};
Though most of the time you don't have to do this. Also, I'm not sure if staffid is supposed to be a function or a variable, but it doesn't change anything.
By the way, this way of attaching handlers is quite old. There's a more powerful one:
document.getElementById('bypass').addEventListener('click', pinpass2, false);
With that you can attach more than one function. To remove one:
document.getElementById('bypass').removeEventListener('click', pinpass2, false);
You can change the onclick attribute the same way you'd change any attribute ?
var elem = document.getElementById('bypass');
elem.setAttribute('onclick', 'pinpass' + staffid + '(); return false;');
FIDDLE
In javascript functions are first class so you can literally just assign pincheck to another variable like this.
var pinpass2 = pincheck;
Now you can still call it like this
pinpass(1,2,3,4);
I'm not 100% from your question, but it looks like you are trying to call a different function based on the staffid variable. I.E. if it is 2 you want to call pinpass2().
If this is a global function you can call window[ 'pinpass' + staffid ]() and it will call the function you want (if it exists).
EXAMPLE: if staffid = 2 then window[ 'pinpass' + staffid ]() is eqivalent to window[ 'pinpass2' ]() which is the same as calling pinpass2().
This works because all global vars (including functions) are properties of the window object, and properties can be accessed using a dynamically generated name and square bracket notation.

call a javascript function using string name

It is a bit complicated for to explain properly what I mean, so please try to understand me :)
I want to be able in javascript to call a element method/function using text sent as parameter. For example:
function CallAFunction(function_name){
document.getElementById('some_id').function_name();
}
As you see in the above example, I want to send function_name as parameter, and it is type of string or a simple text. So how I can use this function name to call it like that ?
Or, please suggest me something which may help me get the same as I need.
Use bracket notation;
document.getElementById('some_id')[function_name]();
call function name using string :
var myFunc = window[myFuncName];
you can sent parameter like this :
<button onclick="myFunction('Harry Potter','Wizard')">Try it</button>
<script>
function myFunction(name,job)
{
alert("Welcome " + name + ", the " + job);
}
</script>

Categories

Resources