Can I mix & match javascript with server-side code in javascript? - javascript

I know this might be an odd situation but currently I need to mix javascript with server side code as follows:
function PerformGlobalCallback(sender, value) {
var index = hfCurrentTabIndex.Get("activeIndex"));
window['<%= ((ASPxCallbackPanel)myTabControl.TabPages[index].Controls[0]).ClientInstanceName %>'].PerformCallback(sender + "|" + value);
}
where hfCurrentTabIndex is a hidden field which correctly holds the value of the current tab index.
I know I cannot simply put the "index" variable in the <%= %> section so I need to come up with a way to do it.
The reason I need this is because the myTabControl current tab index is somehow lost in between callbacks. Also, even though I store it in Session, I get null when I access it in the above code.
Please let me know if you have any insights. Appreciate your help.

var clientInstanceNames = [];
<%
for(int x=0; x<myTabControl.TabPages.Count; x++)
{
Response.Write("clientInstanceNames[" + x.ToString() + "] = \"" + (ASPxCallbackPanel)myTabControl.TabPages[x].Controls[0]).ClientInstanceName + "\";");
}
%>
function PerformGlobalCallback(sender, value) {
var index = hfCurrentTabIndex.Get("activeIndex"));
window[clientInstanceNames[index]].PerformCallback(sender + "|" + value);
}
That should do what you want.
Server side code is processed first so the page gets sent to the client browser before the client browser processes the JavaScript. You could also use an AJAX call to get the .ClientInstanceName. But the way demonstrated above builds the JavaScript array on the server for you, so your client code just has to look-up the index.
Note The code was written inside my browser window and is not tested, so syntax errors may exist.

Yes.
Done quite regularly when setting up javascript with server-generated data.
var myjsVariable = "<%= SomeServerSideVariable %>'
But, the way you've done it wont work.
This bit is javascript (client side)
var index = hfCurrentTabIndex.Get("activeIndex");
But then you try to use that client side variable in a server-side call:
<%= ((ASPxCallbackPanel)myTabControl.TabPages[index].Controls[0]).ClientInstanceName %>
-----------------------------------------------^

Related

Pass string variable in C# to javascript function for use in alert box

so what I'm trying to do is pass a simple string variable that contains my error message in C# into my javascript function when I call the function. My function call works fine, but it keeps outputting the wrong thing. This might be important too, I'm calling the Response.Write pieces within my Global.asax.cs file and my javascript file is within my Scripts folder in my MVC project. Based on the research I've found, this is what I currently have after help from the comments:
function KickOutUnwantedUsers(aMesssage) {
console.log("Inside KickOutUnwantedUsers"); //for debugging
console.log(aMesssage); //for debugging
alert(aMessage);
window.open('', '_self').close();
}
It just continues to output this
<%=errorMessage%>
I'm not sure how to fix it, as everything I've found says to pass the variable that way, but I'm wondering if I need to pass it as an actual parameter into the function, and if so, how to do that.
UPDATE: Here is the C# code:
else
{
string user = s.Remove(0, 4);
string errorMessage = "THE FOLLOWING ERRORS MIGHT HAVE OCCURRED: " + user +
" has either been disabled or the account does not exist." +
" PLEASE CONTACT YOUR ADMINISTRATOR. ";
Response.Write("<script type=\"text/javascript\" src=\"Scripts/HelpfulFunctions.js\">");
Response.Write("</script>");
Response.Write("<script type=\"text/javascript\">");
Response.Write("KickOutUnwantedUsers('" + errorMessage + "');");
Response.Write("</script>");
}
SOLVED
#Igor was very helpful in the comments, and I did things as he suggested, which for some reason would not work at first, but then the following day I deletedmy JavaScript file, remade it under the same name and retyped out the javascript code and it worked. Coding is strange sometimes. I must've had a typo or something.
This is what the (badly documented) HttpUtility.JavaScriptStringEncode is for:
// the second argument "true" causes quotation marks to be inserted as well
var message = <%= HttpUtility.JavaScriptStringEncode(errorMessage, true) %>;
First. Such line as
var message = '<%=errorMessage%>';
only makes sense in ASP.NET markup file. In js file it is meaningless, since javascript files are not processed by ASP.NET server-side.
Second. Since you are passing message string as parameter, you need function signature to reflect this:
function KickOutUnwantedUsers(aMessage) {
alert(aMessage);
window.open('', '_self').close();
}
and - note the quotes around the parameter value:
Response.Write("KickOutUnwantedUsers('" + errorMessage + "');");

can't get ajax to work with jsp

Ok, so I'm learning web design as a co-op at a company. However, the department I'm in is lacking in knowledgeable people in web design. So here we go...
Building a site that will allow the department to manage PTO. I want to implement ajax b/c the main page will have a calendar system so the manager can view the PTO week by week. As a precursor to that, I'm attempting to implement ajax with the "add Employee" page for practice.
However, I can't seem to figure out what I'm missing (aka, why it's not doing anything)
This page just needs to add the new employee to the database. No display needed.
The main page just has 4 text fields and I get the information from those fields in javascript like so
var firstName = document.getElementById("firstNameField");
var lastName = document.getElementById("lastNameField");
var manager = document.getElementById("managerField");
var networkID = document.getElementById("networkIDField");
Simple enough so far.
So I set up the ajax code like so, (this is gathered from what I've read.
var url = "addEmpJSP.jsp?firstNameField=" + escape(firstName)+"&lastNameField="+escape(lastName)+"&managerField="+escape(manager)+"&networkIDField="+escape(networkID);
xmlhttp.open("POST",url,true);
xmlhttp.onreadystatechange=dummy;
xmlhttp.send(null);
This is the part where I'm assuming it's correct as I'm still learning ajax and how it works. I don't think I need to handle a response as I simply want the called jsp file to automatically do whats needed. (if that's possible).
The jsp file looks like this
<%
ResultSet rsEmpl;
Connection connection1 = getDBConnection();
Statement statment1=connection1.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
String fName = request.getParameter("firstNameField");
String lName = request.getParameter("lastNameField");
String manager = request.getParameter("managerField");
String networkID = request.getParameter("networkIDField");
Int empId = 0;
String EditEmplSQL = "select * from PTO_employee";
rsEmpl=statment1.executeQuery(EditEmplSQL);
rsEmpl.last();
empId = rsEmpl.getRow() - 1;
statement1.execute("INSERT INTO PTO_employee VALUES ("+empID+","+lName+","+fName+","+0+","+2+","+networkID);
%>
I have a button on the page that executes the javascript function that contains the ajax info. I'm avoiding jquery atm b/c I'm trying to understand this stuff and how it works before I attempt to use "shortcuts" like jquery. I'm working towards a degree in Software Engineering so understanding this stuff is my priority, not getting it done.(that's just a bonus) If you need anymore information I can provide it. Sorry for my lack of knowledge and if this is completely off base then :(
The main page just has 4 text fields and I get the information from those fields in javascript like so
var firstName = document.getElementById("firstNameField");
var lastName = document.getElementById("lastNameField");
var manager = document.getElementById("managerField");
var networkID = document.getElementById("networkIDField");
That gives you whole HTML DOM elements back, not the values of those elements. HTML DOM elements are like Java classes, having properties, methods and so on. Assuming that it are HTML input elements like <input>, then use their value property instead to get the value. So:
var firstName = document.getElementById("firstNameField").value;
var lastName = document.getElementById("lastNameField").value;
var manager = document.getElementById("managerField").value;
var networkID = document.getElementById("networkIDField").value;
So I set up the ajax code like so, (this is gathered from what I've read.
var url = "addEmpJSP.jsp?firstNameField=" + escape(firstName)+"&lastNameField="+escape(lastName)+"&managerField="+escape(manager)+"&networkIDField="+escape(networkID);
xmlhttp.open("POST",url,true);
xmlhttp.onreadystatechange=dummy;
xmlhttp.send(null);
The escape() is the wrong function. It escapes JS syntax, it does not encode URI components. You should be using encodeURIComponent() function instead.
The jsp file looks like this
...
Int empId = 0;
...
This doesn't compile. It should be int instead.
...
String EditEmplSQL = "select * from PTO_employee";
rsEmpl=statment1.executeQuery(EditEmplSQL);
rsEmpl.last();
empId = rsEmpl.getRow() - 1;
...
Unnecessarily overcomplicated. Learn how to use DB builtin sequences/autoincrement IDs. Refer the DB specific manual or ask DB admin for help.
...
statement1.execute("INSERT INTO PTO_employee VALUES ("+empID+","+lName+","+fName+","+0+","+2+","+networkID);
...
You should put quotes around string values in the SQL query. Assuming that lName, fName and networkID are strings, not numbers, then it should look like this:
statement1.execute("INSERT INTO PTO_employee VALUES (" + empID + ",'" + lName + "','" + fName + "'," + 0 + "," + 2 + ",'" + networkID + "'");
But you have there a huge SQL injection attack hole and you also don't seem to close DB resources at all after use, so they may leak away and cause your webapp to crash sooner or later because the DB runs out of resources. Use PreparedStatement to create a parameterized SQL query and use its setters to set the values. Close the resources in finally block.
After all, reading the server logs should provide you information about compile errors and any server exceptions. Reading the ajax response should provide you information about the response status and body. Your core problem was that you ignored it and thus didn't have any chance to understand what is happening.

Embed javascript Variable within ASP.NET MVC 2 tag

I have a Javascript statement in an MVC view that looks like this and works:
win.attachURL('<%: Url.Action("GraphDetails", "Dashboard", new { area = "Anglian", OSName = "Hello" }) %>');
When I try to extract the variable 'Hello' and put it into a javascript variable (id) and subsequently embed it into my tag like this, it breaks:
var id = "Hello";
win.attachURL('<%: Url.Action("GraphDetails", "Dashboard", new { area = "Anglian", OSName = "' + id + '" }) %>');
Question is, how do I embed a JS variable inside an ASP server tag, that itself is already embedded within Javascript? This is for a local prototype, security concerns are not an issue.
Thank you,
Tom.
One is server-side, the other is client-side, you can't mix the two.
When you do it on the server side with the id as a variable it will break because id doesn't exist in the server side context.
Why don't u try break up the statement on the client side?
var id = "Hello";
var actionInit = "<%: Url.Action("GraphDetails", "Dashboard", new { area = "Anglian"}) %>";
win.attachURL(actionInit + "?OSName=" + id");
Note: when appending ?OSName, this may cause some issue if your route doesn't map 100% correctly. eg. u get /Dashboard/GraphDetails?area="Anglian" and u append another "?" that will be an invalid URL. On the other hand, it will also be invalid if your route matches 100% and you append "&OSName". So just check that out first
I don't think you can in general. In this case at least the <%: ... %> part is evaluated at page load time and will never run again.
Instead, you can compute this in JavaScript, e.g.
var id = "Hello";
var baseURL = '<%: Url.Action("GraphDetails", "Dashboard",
new { area = "Anglian" }) %>';
win.attachURL(baseURL + '&OSName=' + id);
However that makes assumptions about how you're assembling your routing parameters for that route. You could use Url.Action to generate the full route with a dummy value and then substitute, e.g.
var id = "Hello";
var baseURL = '<%: Url.Action("GraphDetails", "Dashboard",
new { area = "Anglian", OSName="ZZZ" }) %>';
win.attachURL(baseURL.replace('ZZZ', id);
but then there's a subtle chance this could go wrong, particularly if you're feeding user generated string into other parameters in the string where they could hit on the value you substitute.
If you really did want to run Url.Action again you'd have to make an AJAX call back to a known URL with the parameters to get the URL, which is overkill really.

using jstl in Javascript

in my jsp page I have:
<form:select path="index" id="sIndex" onchange="showDetails()">
<form:options items="${smth}" itemLabel="name" itemValue="index"/>
</form:select>
And in my javascript function:
*function showDetails() {
var sIndex=document.getElementById("sIndex");
var index=sIndex[sIndex.selectedIndex].value;
var name = '${smth[index].name}';
var address = '${smth[index].address}';
var message = "<table><tr><td>Name:</td><td>" + name + "</td></tr>";
message = message + "<tr><td>Address:</td><td>" + address + "</td></tr>"
message = message + "</table>"
document.getElementById("candDetails").innerHTML = message;
}*
And it doesn't takes the index in ${}, but if I use alert(index) it recognize it.
Java/JSP/JSTL runs at the server side, produces HTML/CSS/JS output and sends it to the client. HTML/CSS/JS runs at the client side, not at the server side as you apparently expected. Open the page in your browser and do a 'view source'. Do you see it?
Javascript only sees the HTML DOM tree in the client side and can access it. You need to get the name and address from the HTML DOM tree. You already have the name in the option element, but the address is nowhere available. You could use JSTL to generate a Javascript array variable so that the Javascript code can use it further.
To learn more about the wall between Java/JSP and Javascript you may find this article useful.
The EL expressions (the code between ${}) are evaluated at runtime of the JSP servlet, not once the page has been rendered in the browser, which is when your JavaScript is being called.
View the generated source of the page and you will probably see the problem.

Best way to get server values into JavaScript in .NET MVC?

Using ASP.NET MVC + jQuery:
I need to use some values owned by the server in my client-side JavaScript.
Right now, I've temporarily got a script tag in the actual view like this:
<script>
var savePath = '<%= Url.Action("Save") %>';
</script>
But I want to move it into something cleaner and more maintainable. I'm thinking of something along the lines of creating a JavaScript controller/action and returning a JSON object that would contain all the data I need, then using the view as the src for a script tag.
Any other ideas?
This actually depends. For simple inliners, the line above works just fine. If you need a LOT of server data in the JavaScript, your view approach may work. However you'll get the same result if you just render partial view that outputs the required JavaScript.
There's a problem with this, since you may end up mixing server data with JavaScript. The best approach would be to minimize server data to absolute minimum, and pass it to JavaScript functions instead of mixing with JavaScript code. That is, not
function func() {
var path = '<%= Url.Action("my") %>';
$(".selector").append("<img src='" + path + "' />");
}
but
function AppendImageToSelector(path) {
$(".selector").append("<img src='" + path + "' />");
}
function func() {
var path = '<%= Url.Action("my") %>';
AppendImageToSelector(path);
}
This makes the code cleaner and easier to understand, helps to move JavaScript out to separate .js files, helps to re-use JavaScript when needed, and so on.
If you need a lot of server-related URLs in JavaScript, you may want to create global (in master page) function like
function url(relative) {
return '<%= Url.Content("~") %>' + relative;
}
and use it from JavaScript scripts. This technique is questionable, though; for example it doesn't use MVC routing rules so URLs may not be out of sync; etc.
I know this is not applicable in all cases but when I need to pass an Url to a client script (as in your example) it is often to ajaxify some anchor or button I already have in the DOM:
<%= Html.ActionLink("Save data", "save") %>
and in my script:
$('a').click(function() {
$.get(this.href);
return false;
});
Stephen Walther - ASP.NET MVC Tip #45 – Use Client View Data

Categories