views:

298

answers:

10

Hi everyone, 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!

+2  A: 

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.

Greg
again, right at the same time the other answer. wish i could mark both as being the chosen correct answer. Will throw some votes up your way once I have 15+ reputation. Thanks for taking the time to help.
+1  A: 

Try using &quot; instead of \"

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

knabar
worked great! thank you!
A: 

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.

David Kemp
A: 
  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.

Corey Trager
A: 

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.

Gareth
thanks for your time. Eval isn't always evil though. There are some niche situations where it is the correct pattern to use, this is one of them. Again, thanks.
+4  A: 

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.

Kent Fredric
That is indeed an elegant way (referring to the first block of code). However, this would not work in any way whatsoever with the application being developed.100% agree that in 99% of cases this is far better than gluing strings together and then using eval. However, I assure you that this is a 1%
FYI - String concatenation is a heck of a lot faster. Useful for say a grid with 1000 rows.
Chase Seibert
A: 

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">.

Mauricio
A: 

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!

Chances are if you think you have found a legitamate excuse for eval, then you just don't know enough about javascript/dom.
Kent Fredric
( Effective use of closures trumps Eval 99/100 times )
Kent Fredric
Understood, and this is that 1/100 times. Cheers. Wish I could talk about it more but it's not my place to talk about the specific code I'm working on.
+1  A: 

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);
}
Gene
again, thanks. elegant. But eval is correct here in the context of our app. (lol, wish i put a disclaimer in my original post about eval!).Thanks very much anyway. :-).If StepTwo were doing ANYTHING different than what it's currently doing, I would avoid eval.
My answer is not only for you. It's also for all of those who search answers to similar issues. For those eval is likely not the right solution. However you got me curious. What is the key reason why eval is right here?
Gene
Hey, I'm sorry but I'm not allowed to say. I'd be pasting code from work which technically belongs to the company I'm writing it for. I'm sure not much of a fuss would be kicked up but I'd rather keep on the safe side. Hope you understand.
Oh yes. I can never use any real examples of my work either.
Gene
A: 
<a href="#" onclick="StepTwo('TestFunction(\'123\', false)', true)">...</a>
ngn