How to use a JavaScript variable as a XHTML attributes value? - javascript

I have tried:
<!--...-->
<script type="text/javascript">
var myVar = "some string";
</script>
<!--...-->
<input name="&{myVar};" ... />
<!--...-->
But using FireFox, the name is set to the literal string: "&{myVar};" instead of the value of myVar...
UDPATE: I see this called JavaScript Entities and hasn't been supported for a long time - but there must be way if one can include JavaScript directly in events (I realize attributes are not events, so JavaScript probably isn't evaluated).. ?! It would be a lot nicer than hardcoding the value as it used elsewehere a lot..

var myInput = document.createElement('input');
myInput.setAttribute('name', myVar);
someContainElement.appendChild(myInput);

I'm afraid you have to use Javascript to manipulate the html element.
You can use jQuery to make this easier:
<script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
<input id="myInput" .../>
<script>
var myVar = "value";
$("#myInput").attr("name", myVar);
</script>

Here's what you need to do.
Start by never reading javascript tutorials from a Java site again. Different monsters entirely, plus the tutorials on the site you're referencing are horrible.
Second, get a copy of Javascript the Good Parts, http://www.amazon.com/dp/0596517742/
This book is perhaps the most useful book ever written (in my opinion) about the language itself. It doesn't say anything about dealing with DOM API's.
I encourage you to learn the language itself before getting too deep into javascript libraries like jQuery. It'll do you a load of good sooner rather than later.
Once you're at least somewhat familiar with the proper ways to use javascript as a language, start investing your time into one library or another. jQuery is probably the most used, well loved, and kindest library out there. It will make dealing with cross-browser crap SO much easier for you.

Both Phil's and Xenoflex's ways, are the better way to go. They are actually doing the same thing just different ways, one using jQuery the other pure Javascript.
Alex's will work as well but then everything is hardcoded and somewhat less flexiable to future changes. The way Alex left his answer open you could print the string or assign it to a variable to be appended to a javascript object.
I think the nearest match to what you're looking for is:
<script type="text/javascript">
var myVar = "some string";
</script>
...
<script type="text/javascript">
document.write('<input name="' + myVar + '" ... />')
</script>
But as I said you should really take one of the first two approaches.

Related

Javascript alternative to document.write not innerHTML

I modified a little js script which compares a date to today and calculates the difference. (I'm a novice)
However, it uses document.write, which I've been told is bad.
I don't know why it's bad, people just say it's bad and never explain why.
Anyway, I'm looking for an alternative. innerHTML doesn't seem to work, and other questions answered on this site just point to DOM manipulation references without really answering the question.
Here's my script:
//Set the two dates
var iquit =new Date(2013, 1, 15);
today=new Date();
//Get 1 day in milliseconds
var one_day=1000*60*60*24;
var day_numeric=Math.ceil((today.getTime()-iquit.getTime())/(one_day));
//Calculate difference btw the two dates, and convert to days
document.write("<p>"+day_numeric+
" days have gone by since you quit smoking!</p>"+
"<p>You have saved "+ day_numeric*7+" pounds</p>");
If anyone can tell me a better way to write this, it'd be amazing.
The problem with document.write() is that if you call it after the DOM is ready, it will overwrite the existing DOM. This SO answer has a more extensive explanation to why document.write() rarely is the best choice.
Using .innerHTML should work fine, but you need to select the element you want to add the content do. So something like this:
document.getElementById("idOfSomeElement").innerHTML = "your content";
Live example
What method to use to get the proper element depends on what you have to select on, but if possible, the easiest way is probably to attach an ID to the element you want to add content to, and use the above method.
If you're using pure JavaScript, one of best ways to get this may be:
var paragraph1 = document.createElement("p");
paragraph1.appendChild(document.createTextNode(day_numeric+" days have gone by since you quit smoking!"));
var paragraph2 = document.createElement("p");
paragraph1.appendChild(document.createTextNode("You have saved "+ day_numeric*7+" pounds"));
document.body.appendChild(paragraph1);
document.body.appendChild(paragraph2);
100% standard DOM.
About document.write: good or evil...
I guess some consider document.write as a bad practice because it's the lower-level way of output raw content to the (X)HTML document.
Since (X)HTML is basically a dialect of XML (or at least, based on XML and SGML), the right and expected way of writing a document is creating nodes and appending them to the whole document.
document.write writes the content after the last written element and you lose a lot of control when you want to decide where to place the newly-created element in the document.
For example, would you output a paragraph from a JavaScript function loaded in the from the <head> element? It would be hard as it'll not be rendered in the body necessarily. That's too bad.
It's better to create DOM elements/nodes and append them to the document using appendChild(...).
Check this link for reasons why it is considered bad practice: Why is document.write considered a "bad practice"?
And how are you using innerHTML?
Have you tryed something like
<script>
...
document.getElementById('container-id').innerHTML = "<p>"+day_numeric+" days have gone by since you quit smoking!</p>"+"<p>You have saved "+ day_numeric*7+" pounds</p>";
</script>
This requires an element with the container-id id somewhere in the page, like:
<div id='container-id'></div>

Javascript creating an HTML object vs creating an HTML string

Pretty simple question that I couldn't find an answer to, maybe because it's a non-issue, but I'm wondering if there is a difference between creating an HTML object using Javascript or using a string to build an element. Like, is it a better practice to declare any HTML elements in JS as JS objects or as strings and let the browser/library/etc parse them? For example:
jQuery('<div />', {'class': 'example'});
vs
jQuery('<div class="example></div>');
(Just using jQuery as an example, but same question applies for vanilla JS as well.)
It seems like a non-issue to me but I'm no JS expert, and I want to make sure I'm doing it right. Thanks in advance!
They're both "correct". And both are useful at different times for different purposes.
For instance, in terms of page-speed, these days it's faster to just do something like:
document.body.innerHTML = "<header>....big string o' html text</footer>";
The browser will spit it out in an instant.
As a matter of safety, when dealing with user-input, it's safer to build elements, attach them to a documentFragment and then append them to the DOM (or replace a DOM node with your new version, or whatever).
Consider:
var userPost = "My name is Bob.<script src=\"//bad-place.com/awful-things.js\"></script>",
paragraph = "<p>" + userPost + "</p>";
commentList.innerHTML += paragraph;
Versus:
var userPost = "My name is Bob.<script src=\"//bad-place.com/awful-things.js\"></script>",
paragraph = document.createElement("p");
paragraph.appendChild( document.createTextNode(userPost) );
commentList.appendChild(paragraph);
One does bad things and one doesn't.
Of course, you don't have to create textNodes, you could use innerText or textContent or whatever (the browser will create the text node on its own).
But it's always important to consider what you're sharing and how.
If it's coming from anywhere other than a place you trust (which should be approximately nowhere, unless you're serving static pages, in which case, why are you building html?), then you should keep injection in mind -- only the things you WANT to be injected should be.
Either can be preferable depending on your particular scenario—ie, if everything is hard-coded, option 2 is probably better, as #camus said.
One limitation with the first option though, is that this
$("<div data-foo='X' />", { 'class': 'example' });
will not work. That overload expects a naked tag as the first parameter with no attributes at all.
This was reported here
1/ is better if your attribubes depends on variables set before calling the $ function , dont have to concatenate strings and variables. Aside from that fact ,since you can do both , and it's just some js code somebody else wrote , not a C++ DOM API hardcoded in the browser...

How safe is it use document.body.innerHTML.replace?

Is running something like:
document.body.innerHTML = document.body.innerHTML.replace('old value', 'new value')
dangerous?
I'm worried that maybe some browsers might screw up the whole page, and since this is JS code that will be placed on sites out of my control, who might get visited by who knows what browsers I'm a little worried.
My goal is only to look for an occurrence of a string in the whole body and replace it.
Definitely potentially dangerous - particularly if your HTML code is complex, or if it's someone else's HTML code (i.e. its a CMS or your creating reusable javascript). Also, it will destroy any eventlisteners you have set on elements on the page.
Find the text-node with XPath, and then do a replace on it directly.
Something like this (not tested at all):
var i=0, ii, matches=xpath('//*[contains(text(),"old value")]/text()');
ii=matches.snapshotLength||matches.length;
for(;i<ii;++i){
var el=matches.snapshotItem(i)||matches[i];
el.wholeText.replace('old value','new value');
}
Where xpath() is a custom cross-browser xpath function along the lines of:
function xpath(str){
if(document.evaluate){
return document.evaluate(str,document,null,6,null);
}else{
return document.selectNodes(str);
}
}
I agree with lucideer, you should find the node containing the text you're looking for, and then do a replace. JS frameworks make this very easy. jQuery for example has the powerful :contains('your text') selector
http://api.jquery.com/contains-selector/
If you want rock solid solution, you should iterate over DOM and find value to replace that way.
However, if 'old value' is a long string that never could be mixed up with tag, attribute or attbibute value you are relatively safe by just doing replace.

What's the best practice to transfer a variable value to javascript from server?

I'm developing a pet project with jQuery. Now the application requires some variable value is transferred to client javascript when the page is loaded. I'm wondering what's the best practice to do it.
I can image to do it in two ways. First, render it to be a javascript variable in the page.
<script> <?php echo "var maxid = $maxid;"?> </script>
Which means the client will see
<script> var maxid = <somevar>; </script>
Second, assign it to be an attribute of one element.
<div maxid="<php echo $maxid >" />
Which approach is better? Is there any other way to do it?
For the sake of valid html I'd go with the first method, though it really doesn't matter as long as it gets the job done.
<script>
$(function() {
var max_id = <?php echo $max_id;?>;
});
</script>
I use JSON string to pass values to client
Take a look at this example http://blog.reindel.com/2007/10/02/parse-json-with-jquery-and-javascript/
I rarely have to pass just one variable ... I tend to have a whole set of information, in which case I use:
var myAwesomeStuff = <?php echo json_encode($myArrayOfAwesomeInformation); ?>
No round trip to the server, as mentioned earlier with JSON.
-- Edit:
Just so it's clear, your "question" is asking something totally different than your "code". You'll need to clarify, my post below talks about the "question".
-- Old:
I generally return the complete HTML to be rendered, in the pages that the ajax calls to.
The reason for this is that I don't have to duplicate layout logic in JavaScript, and it ends up being generally useful for just keeping the JavaScript trivial, and of the form of setting HTML/text content of relevant placeholders.
It comes at the cost of transferring more data, but for me, I'm happy to make this trade-off.
I would render it to be a javascript variable (your first alternative). This seems to be a common approach.
First method is better because you will consume less memory and CPU with a simple variable. Going the DIV way, you will consume a DOM element and a DOM node search to read the value.

Escaping dilemma in Javascript

I have the following
var id='123';
newDiv.innerHTML = "";
Which renders 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...
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 = "";
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!
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.
Try using " instead of \"
newDiv.innerHTML = "<a href="#"...
You should be using " not " or \" inside an HTML string quoted with double-quotes.
NewDiv.innerHTML = "";
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:
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
as the next " after the start of the onclick attribute, closes it. Use " as others have suggested. And don't use eval.
You need to alternate your " and '.
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 or use ".
In your code:
newDiv.innerHTML = "";
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">.
...
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 = '';
eval('(function(div, html){div.innerHTML = html;})')(newDiv, html);
So, what's going on here?
eval creates a function that contains two parameters, div and html and returns it.
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))();
}

Categories