Trying to call a function in javascript - javascript

This is my code all I need to do is call a function which will write the contents to a dynamic div
<script language='javascript' type='text/javascript'>
function getComments(id)
{
alert(id);
}
var resultSet="";
function CreateDiv()
{
resultSet+="<br/><div id='"+rows.data[i].id+"'></div><script language='javascript' type='text/javascript'> getComments("+rows.data[i].id+"); <\/script>";
}
window.onload=CreateDiv;
</script>
The function getComments is not being called at all
What's that I am missing here

There are a few problems there.
You're referencing rows without defining it anywhere, which will cause an exception.
Assuming you define rows somewhere you haven't shown, the code's just creating a string containing a script tag and putting that string in resultSet. To cause the code inside the script tag to run, you'd have to assign resultSet to innerHTML on some element.
There's an extra ) in your call to getComments within the generated script.
Separately: Your id values would appear to be numbers (this is based on your passing them into getComments with no quotes around them). Note that using id values starting with a digit is allowed in HTML5, but not in earlier versions of HTML and not in CSS, so it's probably best avoided.
There's almost certainly a better way to do what you're actually trying to do, you may consider a separate question outlining the goal, how you've approached it so far, and asking for alternatives.

I would suggest that you break the code down into steps while you debug it. Specifically where you populate resultSet. Break it down at each plus sign. Then you can step through it and see how it is being populated.
resultSet+="<br/><div id='";
resultSet+=rows.data[i].id;
and so on.
Secondly, have a look in View Source to see what this looks like on the page when you run it. Does the HTML look properly formed?
Also, I am questioning whether that final <\/script> in resultSet is correct.

Try replacing the createDiv function with this:
function CreateDiv(){
resultSet += "<br/><div id='"+rows.data[i].id+"'></div>" + getComments(rows.data[i].id);
}
It should work flawlessly.

Related

Using variables with jQuery's replaceWith() method

Ok this one seems pretty simple (and it probably is). I am trying to use jQuery's replace with method but I don't feel like putting all of the html that will be replacing the html on the page into the method itself (its like 60 lines of HTML). So I want to put the html that will be the replacement in a variable named qOneSmall like so
var qOneSmall = qOneSmall.html('..........all the html');
but when I try this I get this error back
Uncaught SyntaxError: Unexpected token ILLEGAL
I don't see any reserved words in there..? Any help would be appreciated.
I think the solution is to only grab the element on the page you're interested in. You say you have like 60 lines. If you know exactly what you want to replace..place just that text in a div with an id='mySpecialText'. Then use jQuery to find and replace just that.
var replacementText = "....all the HTML";
$("#mySpecialText").text(replacementText);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mySpecialText">Foo</div>
If you're only looking to replace text then jaj.laney's .text() approach can be used. However, that will not render the string as HTML.
The reason the way you're using .html() is likely illegal is that qSmallOne is not a JQuery object. The method cannot be performed on arbitrary variables. You can set the HTML string to a variable and pass that string to the .html() function like this:
var htmlstring = '<em>emphasis</em> and <strong>strong</strong>';
$('#target').html(htmlstring);
To see the difference between using .html() and .text() you can check out this short fiddle.
Edit after seeing the HTML
So there is a lot going on here. I'm just going to group these things into a list of issues
The HTML Strings
So I actually learned something here. Using the carriage return and tab keys in the HTML string is breaking the string. The illegal-ness is coming from the fact the string is never properly terminated since it thinks it ends at the first line. Strip out the white space in your strings and they're perfectly valid.
Variable Names
Minor thing, you've got a typo in qSmallOne. Be sure to check your spelling especially when working with these giant variables. A little diligence up front will save a bunch of headache later.
Selecting the Right Target
Your targets for the change in content are IDs that are in the strings in your variables and not in the actual DOM. While it looks like you're handling this, I found it rather confusing. I would use one containing element with a static ID and target that instead (that way you don't have to remember why you're handling multiple IDs for one container in the future).
Using replaceWith() and html()
.replaceWith() is used to replace an element with something else. This includes the element that is being targeted, so you need to be very aware of what you're wanting to replace. .html() may be a better way to go since it replaces the content within the target, not including the target itself.
I've made these updates and forked your fiddle here.

Use one javascript script to dynamically modify another script

Yo!
I have an arbitrary javascript file, let's call it localScript, and just say it looks something like this:
<script id="myScript" type="text/javascript">
function () {
var blue = 'blue';
var person = {
firstName:"John",
lastName:"Doe",
age:50,
eyeColor:"brown"
};
var bluePerson = function () {
person[color] = blue;
};
}
</script>
I want to be able to use another externalScript to dynamically change the contents of this localScript. For this simple example, let's just say I want to update some of the values in localScript, like—maybe change age of the person object to 75. (Obviously, there's very simple ways to do this, but for my use case it's imperative that I use another externalScript to generate the contents of this localScript).
It would be easy if there was something like .innerHtml which I could use in the externalScript which would allow me to select an element and then replace the 'innerHtml' contents. The localScript, though, obviously isn't composed of elements.
As far as I know, when using a script to modify another script, there aren't any 'easy' ways to reference variables/objects/items in the script.
Things I've considered are indexOf(), search(), and match(), which I could use in externalScript to find strings inside localScript and then replace the values. I feel though as these could be performance no-no's, especially if the script grows.
Are there any easy ways to do this—with an emphasis on performance? I feel like there must be some easy way to reference one of the items in the script, though, I suppose a script is all one large string.. and maybe there is no simple way.
BTW—I'm using AngularJS, if there are any built in methods—though I think this is mostly just a javascript thing.
Thanks a bunch!
It looks like a bad idea, but... well, if it is imperative...
It makes no sense to change a script in a <script> tag - if it is in DOM, it has already executed (and no longer matters). Thus, to change the script before it has a chance to execute, you need to load it using AJAX, change the text, then eval it.
You can easily change the variables. Refer following steps
Include external script just below the script you have written.
Access the variables in the external script as if they are locally declared.
The variables you have created in above script are available in global scope and hence should be accessible from everywhere.
Note: This answer was added before the function clause was added.

putting model variables inside js code

i have issues alternating js and razor syntax.
i am trying to pass the value of a model variable to a javascript function, let's say something like this
<script>
//this is my javascript function setTitle that simply changes the title
of a modal window, and i want to pass to it the title from the model
...
setTitle(#Model.titleName);
...
</script>
so when i do this it doesn't work, and the script seems to break.
If it's a string you have to surround it with quotes.
setTitle('#Model.titleName');
If it's an integer you obviously don't need that.
In situations like these it's helpful to Right Click -> View Source, and take a look at the javascript it generated, and also report any errors the console window showed when asking a question.
You need to encase the Razor code in quotes so the result is a JavaScript string
setTitle("#Model.titleName");

Can the string "</script>" cause any problems when returned as part of some JSON data?

There are no inline scripts involved, whatsoever. I have an external file script, which fetches some JSONP from twitter. Let's suppose that a property of the object represented in the returned JSONP was a string that contained somewhere in it the substring "</script>". Could this cause any problems on its own, without getting added to the DOM at all? (It gets scrubbed clean well before that point.)
I can't see why it would, but HTML parsing is notoriously whacky and quirky, so who knows? I know that if you want to have a string literal within an inline script, you need to break it up, like var slashScriptContainingString = 'foo</scr' + 'ipt>bar'; Again, I feel like it should be fine, but just checking to see if anyone knows why it might not be.
<!doctype html>
<script src="file.js"></script>
File.js:
var f = function(twobj) {
console.log(twobj);
doOtherStuffWith(twobj);
}
<script src="https://api.twitter.com/statuses/user_timeline/user.json?callback=f"></script>
Returned JSONP:
f(["this is an object, returned as part of the JSONP response, except it contains a string literal with the substring \"</script>\". Is this a problem? Note: I haven't said anything about injecting this string in the DOM in any way shape or form. I can't think of a reason why it might be, but I'd just like to be sure."]);
No, string literals can contain whatever you want. As long as you are not blindly trying to set the innerHTML of something, a string is just a string. The example you have posted is safe.
The reason that you need to split up your </script> tag in your JavaScript source is that you are missing CDATA blocks. Without them, technically everything in your inline JavaScript needs to be properly escaped for HTML. (< becomes <, etc.) Browsers are nice to you and let it slide, but </script> inside inline JavaScript becomes ambiguous. You should be using CDATA blocks to keep things like this from happening.
<script type="text/javascript">
//<![CDATA[
...code...
//]]>
</script>
See this question for more details: When is a CDATA section necessary within a script tag?

ASP.NET inline server tags

I'd like to start by saying that my code is working perfectly, this is more a "how best to do it" kind of question.
So I have code like this in my .aspx file:
function EditRelationship() {
var projects=<%= GetProjectsForEditRelationship() %>;
// fill in the projects list
$('#erProjectsSelect').empty();
for(var i in projects)
$('#erProjectsSelect').append('<option value='+projects[i][0]+'>'+projects[i][1]+'</option>');
var rels=<%= GetRelationshipsForEditRelationship() %>;
// etc
}
Again, it's working fine. The problem is that VS2008 kinda chokes on code like this, it's underlining the < character in the tags (with associated warnings), then refusing to provide code completion for the rest of the javascript. It's also refusing to format my document anymore, giving parsing errors. The last part is my worst annoyance.
I could put some of these in evals I guess, but it seems sorta dumb to add additional layers and runtime performance hits just to shut VS up, and it's not always an option (I can't remember off the top of my head where this wasn't an option but trust me I had a weird construct).
So my question is, how do you best write this (where best means fewest VS complaints)? Neither eval nor ajax calls fit this imo.
If your aim is to reduce VS complaints, and if you are running asp.net 4 (supporting Static client Ids), maybe a strategy like the following would be better?
Create a ASP:HiddenField control, set its ClientIdMode to "Static"
Assign the value of GetRelationshipsForEditRelationship() to this field on page load
In your javascript, read the value from the hidden field instead, I assume you know how to do this.
It's more work than your solution, and you will add some data to the postback (if you perform any) but it won't cause any VS complaints I guess :)
You could do this from your page in the code-behind
ClientScript.RegisterArrayDeclaration("projects", "1, 2, 3, 4");
or to construct something like JSON you could write it out
ClientScript.RegisterClientScriptBlock(GetType(), "JSONDeclarations", "your json stuff");
UPDATE Based on my comment
<script id="declaration" type="text/javascript">
var projects=<%= GetProjectsForEditRelationship() %>;
var rels=<%= GetRelationshipsForEditRelationship() %>;
</script>
<script type="text/javascript">
function EditRelationship() {
// fill in the projects list
$('#erProjectsSelect').empty();
for(var i in projects)
$('#erProjectsSelect').append('<option value='+projects[i][0]+'>'+projects[i][1]+'</option>');
}
</script>
I don't have VS2008 installed to test with, so take this with a grain of salt, but have you tried something like this?
var projects = (<%= GetProjectsForEditRelationship() %>);
Something like that might trick the JavaScript parser into ignoring the content of your expression.
For what it's worth, VS2010 correctly parses and highlights your original code snippet.
Is it an option to move this to VS2010? I just copied and pasted your code and the IDE interpreted it correctly.
The best solution is to put javascript in a separate file and avoid this entirely. For this particular function, you're doing server-side work. Why not build the list of options that you intend to add dynamically in codebehind, put them in a hidden div, and then just have jQuery add them from the already-rendered HTML?
If you have a situation where you really want to dynamically create a lot javascript this way, consider using ScriptManager in codebehind to set up the variables you'll need as scripts and register them, then your inline script won't need to escape
ScriptManager.RegisterClientScript("projects = " + GetProductsForEditRelationship());
(Basically, that is not the complete syntax, which is context dependent). Then refer to "projects" in your function.
(edit)
A little cleaner way to do this on a larger scale, set up everything you need like this in codebehind:
string script = "var servervars = {" +
"GetProductsForEditRelationship: " + GetProductsForEditRelationship() +
"GetRelationshipsForEditRelationship: " + GetRelationshipsForEditRelationship() +
"}"
and refer to everything like:
servervars.GetProductsForEditRelationship
If you do this a lot, of course, you can create a class to automate the construction of the script.

Categories

Resources