Question

I have the following

var id='123';

newDiv.innerHTML = "<a href=\"#\" onclick=\" TestFunction('"+id+"', false);\"></a>";

Which renders <a href="#" onclick="return Testfunction('123',false);"></a> in my HTML.

The problem I have is that I wish to take the call to the method TestFunction, and use as a string parameter in my function StepTwo(string, boolean), which would ideally end up in live HTML as shown...

<a href="#" onclick="StepTwo("TestFunction('123',false)",true)"></a>

notice how the TestFunction is a string here (it is executed within StepTwo using eval).

I have tried to format my JS as by :

newDiv.innerHTML = "<a href=\"#\" onclick=\"StepTwo(\"TestFunction('"+id+"', false);\",true)\"></a>";

but while this appears to me correct in my IDE, in the rendered HTML, it as garbelled beyond belief.

Would appreciate if anyone could point me in the right direction. Thanks!

Was it helpful?

Solution

Try using &quot; instead of \"

newDiv.innerHTML = "<a href=&quot;#&quot;...

OTHER TIPS

One of the biggest capital failures on the internet is creating html in javascript by gluing strings together.

var mya = document.createElement("a");
mya.href="#"; 
mya.onclick = function(){ 
    StepTwo(function(){ 
        TestFunction('123', false ); 
    }, true );   
};
newDiv.innerHTML = ""; 
newDiv.appendChild(mya);

This Eliminates the need for any fancy escaping stuff.

( I probably should do 'onclick' differently, but this should work, I'm trying hard not to just use jQuery code to do everything )

Heres how I would do it in jQuery:

jQuery(function($){ 

  var container = $("#container"); 
  var link = document.createElement("a"); /* faster than  $("<a></a>"); */
  $(link).attr("href", "Something ( or # )" ); 
  $(link).click( function(){ 
       var doStepTwo = function()
       { 
            TestFunction('123', true ); 
       };
       StepTwo( doStepTwo, false );  /* StepTwo -> doStepTwo -> TestFunction() */
  });
  container.append(link); 
}); 

There is no good excuse for gluing strings together in Javascript

All it does is ADD overhead of html parsing back into dom structures, and ADD potential for XSS based broken HTML. Even beloved google get this wrong in some of their advertising scripts and have caused epic failures in many cases I have seen ( and they don't want to know about it )

I don't understand Javascript is the only excuse, and it's NOT a good one.

You should be using &quot; not " or \" inside an HTML string quoted with double-quotes.

NewDiv.innerHTML = "<a href=\"#\" onclick=\"StepTwo(&quot;TestFunction('"+id+"', false);&quot;,true)\"></a>";

There's probably a better way to do this - any time you find yourself using eval() you should stand back and look for a different solution.

You claim that eval is the right thing to do here. I'm not so sure.

Have you considered this approach:

<a href="#" onclick="StepTwo(TestFunction,['123',false],true)"></a>

and in your StepTwo function

function StepTwo(func,args,flag){
    //do what ever you do with the flag
    //instead of eval use the function.apply to call the function.
    func.apply(args);
}

You could create the a element and attach to the click event using DOM Methods.

A Javascript Framework (like the ubiquitous jQuery) would make this a lot easier.

Your biggest problem is using eval, it leads to so many potential problems that it's nearly always better to find an alternative solution.

Your immediate problem is that what you really have is

<a href="#" onclick="StepTwo("></a>

as the next " after the start of the onclick attribute, closes it. Use &quot; as others have suggested. And don't use eval.

  1. You need to alternate your " and '.

  2. Maybe you don't need quotes around the 123, because of Javascripts flexible typing. Pass it without quotes but treat it as a string within TestFunction.

Hey guys, thanks for all the answers. I find that the quot; seems to work best.

I'll give you guys some votes up once I get more reputation!

In regards to eval(), what you see in the question is a very small snapshot of the application being developed. I understand the woes of eval, however, this is one of those one in a million situations where it's the correct choice for the situation at hand.

It would be understood better if you could see what these functions do (have given them very generic names for stackoverflow).

Thanks again!

The best way is to create the element with document.createElement, but if you're not willing to, I guess you could do <a href="#" onclick="StepTwo('TestFunction(\'123\',false)',true)"></a> or use &quot;.

In your code:

newDiv.innerHTML = "<a href=\"#\" onclick=\"StepTwo('TestFunction(\'"+id+"\', false);\',true)\"></a>";

If it doesn't work, try changing "\'" to "\\'".

Remember that the " character is used to open and close the attribute on HTML tags. If you use it in the attribute's value, the browser will understand it as the close char.

Example: <input type="text" value="foo"bar"> will end up being <input type="text" value="foo">.

<a href="#" onclick="StepTwo('TestFunction(\'123\', false)', true)">...</a>

I know this is hella' old now, but if anyone has issues with escaped strings when using eval (and you absolutely have to use eval), I've got a way to avoid problems.

var html = '<a href="#\" onclick=" TestFunction(\''+id+'\', false);"></a>';
eval('(function(div, html){div.innerHTML = html;})')(newDiv, html);

So, what's going on here?

  1. eval creates a function that contains two parameters, div and html and returns it.
  2. The function is immediately run with the parameters to the right of the eval function. This is basically like an IIFE.

In this case

var myNewMethod = eval('(function(div, html){div.innerHTML = html;})');

is basically the same as:

var myNewMethod = function(div, html){div.innerHTML = html;}

and then we're just doing this:

myNewMethod(newDiv, html); //where html had the string containing markup

I would suggest not using eval. If it can't be avoided, or if you control all the inputs and there's no risk of injection then this will help in cases where string escapes are an issue.

I also tend to use Function, but it isn't any more secure. Here's the snippet I use:

    var feval = function(code) {
    return (new Function(code))();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top