ASP.NET Generated Output Not Effected By JQuery/Javascript - c#

I have the below code that is dynamically generates a directory tree in html list format. When I try to manipulate the list items with javascript to add a '+' to the end of the item, it doesn't work. I know the jquery is correct, I have used it on another page on the same server. Is jquery not able to manipulate data that is dynamically generated server side with asp.net?
<script langauge="C#" runat="server">
string output;
protected void Page_Load(object sender, EventArgs e) {
getDirectoryTree(Request.QueryString["path"]);
itemWrapper.InnerHtml = output;
}
private void getDirectoryTree(string dirPath) {
try {
System.IO.DirectoryInfo rootDirectory = new System.IO.DirectoryInfo(dirPath);
foreach (System.IO.DirectoryInfo subDirectory in rootDirectory.GetDirectories()) {
output = output + "<ul><li>" + subDirectory.Name + "</li>";
getDirectoryTree(subDirectory.FullName);
if (subDirectory.GetFiles().Length != 0) {
output = output + "<ul>";
foreach (System.IO.FileInfo file in subDirectory.GetFiles()) {
output = output + "<li><a href='" + file.FullName + "'>" + file.Name + "</a></li>";
}
}
output = output + "</ul>";
}
} catch (System.UnauthroizedAccessException) {
//This throws when we don't have access, do nothing and move one.
}
}
</script>
I then try to manipulate the output with the following:
<script langauge="javascript">
$('li > ul').not('li > ul > li > ul').prev().append('+');
</script>
Just an FYI the code for the div is below:
<div id="itemWrapper" runat="server">
</div>

Have you tried execute your JS after the page loads?
Something like this ...
$(function(){
$('li > ul').not('li > ul > li > ul').prev().append('+');
});

It looks like you have a couple of problems here. First you should put your jQuery code inside of $(document).ready. That ensures that the DOM has fully loaded before you try to mess with it. Secondly, your selector is looking for ul elements that are direct children of li elements. Your code does not generate any such HTML. You have li's inside of ul's but not the other way around. Also, if your directory has files in it, you are going to leave some ul elements unclosed which will mess up your HTML and Javascript.

Related

Proper way to output HTML to the page

I realize this is probably a fundamental thing I should know but I am self-teaching myself C# and asp.net so I am a little lost at this point.
I have a stored procedure, which will return around 700-800 image URLs.
I need to build HTML like this for all the 800 image URLs and return the HTML to the page:
<div class="tile">
<img src="source.png" height="100" width="100" />
</div>
This is my code currently:
if (reader.HasRows)
{
string flagwallcontent = ""; //using a string to build html
while (reader.Read())
{
flagwallcontent = flagwallcontent + "<div class='tile'>";
flagwallcontent = flagwallcontent + "<img src='" + reader.GetString(0) + "' height='100' width='100'/>";
flagwallcontent = flagwallcontent + "</div>";
}
FlagWallLiteral.Text = flagwallcontent; //returning html to asp literal
}
I feel that this is not the efficient way to do it. Using string to build HTML and return HTML to asp literal. Can you suggest what the best way would be?
One way you could do it is to have an ASP.NET Panel (which renders as a <div>) to be the container for each of X hundred images you will add, like this:
if (reader.HasRows)
{
while (reader.Read())
{
// Create new image control
var newImage = new Image ();
newImage.ImageUrl = reader.GetString(0);
newImage.Height = 100;
newImage.Width = 100;
// Add new image to panel
Panel1.Controls.Add (newImage);
}
}
This allows ASP.NET to render the HTML while working with the strongly typed C# API.

How to write quotes (" or ') and quoted strings to a Razor view

I have a bunch of constants to be used in JS saved in a RESX file, such as:
DATE_PICKER_FORMAT yyyy-mm-dd
DATETIME_FORMAT yyyy-mm-dd hh:mm:ss
MONTH_PICKER_FORMAT yyyy-mm
I wrote a simple class to help write this into JS on a Razor view:
public static class JavascriptResourceRenderer
{
private static string Render(ResourceSet resources)
{
string resourceString = "";
foreach (DictionaryEntry resource in resources)
{
resourceString += String.Format("var {0} = '{1}'; ", resource.Key, resource.Value);
}
return resourceString;
}
public static string RenderPageConstants()
{
ResourceSet resources = PageConstants.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
return Render(resources);
}
}
And in my view, I'm doing this:
#section Scripts
{
<script>
#JavascriptResourceRenderer.RenderPageConstants()
</script>
}
The constants do get rendered when the view loads, except the quotes come out encoded.
Viewing the HTML using DOM inspector, this is what I see:
<script>
var MONTH_PICKER_FORMAT = 'yyyy-mm';
</script>
I've tried
"var {0} = '{1}'; " // writes 'yyyy-mm' to view
"var {0} = \"{1}\"; " // writes "yyyy-mm" to view
#"var {0} = "{1}"; " // syntax error in String.Format
How can I write
<script>
var MONTH_PICKER_FORMAT = "yyyy-mm"; // or 'yyyy-mm' (I want the quotes!)
</script>
to the view?
You should return your output as an MvcHtmlString instead, otherwise MVC will encode it:
private static MvcHtmlString Render(ResourceSet resources)
{
string resourceString = "";
foreach (DictionaryEntry resource in resources)
{
resourceString += String.Format("var {0} = '{1}'; ", resource.Key, resource.Value);
}
return new MvcHtmlString(resourceString);
}
Alternatively, you can use the Html Helper method Html.Raw in your view, but you need to remember to do that every time you call the method (which is why I would not recommend to do it this way):
#Html.Raw(JavascriptResourceRenderer.RenderPageConstants())
Your string is getting HTML encoded.
You'll need to output raw text. Your view needs to do this:
#section Scripts
{
<script>
#Html.Raw(JavascriptResourceRenderer.RenderPageConstants())
</script>
}

Script src tag breaks

I have made previous posts about my custom visualization not working in Spotfire:
https://stackoverflow.com/questions/25390099/awesomium-javascript-handler-being-called-indefinitely
Returning value to C# function from Javascript not working in Awesomium
and I have finally narrowed it down to the offending line.
In my document, I load a source script:
<script src="http://d3js.org/d3.v3.min.js"></script>
This seems to break my entire custom visualization; it infinitely tries to reload the page, from what I've seen. Here is my C# code:
private void WebViewOnDomReady(object sender, EventArgs eventArgs)
{
webView.DomReady -= WebViewOnDomReady;
webView.CreateObject("jsobject");
//webView.SetObjectCallback("jsobject", "callNETNoReturn", JSHandler);
webView.SetObjectCallback("jsobject", "callNETWithReturn", JSHandler);
//webView.ExecuteJavascript("myMethod()");
var result = webView.ExecuteJavascriptWithResult("myMethodProvidingReturn('foo')");
MessageBox.Show("Stuff:" + result.ToString());
}
private void JSHandler(object sender, JSCallbackEventArgs args)
{
var result = webView.ExecuteJavascriptWithResult("myMethodProvidingReturn('foo')");
MessageBox.Show(result.ToString());
MessageBox.Show("Got method call with no return request");
}
And here is my Javascript code:
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
function myMethod() {
document.write("In myMethod, calling .NET but expecting no return value.<br/>");
jsobject.callNETNoReturn();
}
function myMethodExpectingReturn() {
document.write("In myMethodExpectingReturn, calling .NET and expecting return value.<br/>");
var returnVal2 = jsobject.callNETWithReturn("foo");
document.write("Got value from .NET: " + returnVal2 + "<br/>");
}
function myMethodProvidingReturn(whatToReturn) {
var returnVal = whatToReturn + "bar";
document.write("Returning '" + returnVal + "' to .NET.");
return returnVal;
}
</script>
Interestingly enough, the HTML loads fine if I don't try and call a Javascript function and get the return value in C#. However, when I try to return the result of the JS function and print it in C#, including the script src line breaks my entire code; it infinitely returns a blank message judging from the MessageBoxes that I have set.
This is completely baffling me, as it seems to mean that the HTML is being loaded over and over again. Setting the script src tag, for some odd reason, causes this infinite loop.
What exactly is happening?
Thanks

How to dynamically generate and send jQuery to the webpage from C# AND have it work

So, I am dynamically generating jQuery using C# and sending it to the webpage.
The problem is it appears to be generating correct jQuery according to the file and according to Js Fiddle but it does not actually work on the page.
The jsFiddle is here http://jsfiddle.net/ER2hE/
Now I looked up how to send javacript to the website. It should work like this.
http://msdn.microsoft.com/en-us/library/bb359558.aspx
and my code which does that is this method
private void sendScript(string script)
{
const string someScript = "alertMe";
//send the built script to the website.
ScriptManager.RegisterStartupScript(this.Page, this.GetType(), someScript, script, true);
}
This is super simple it has worked for other pieces of code calling. But it has not for this instance.
The code that calls it is this in my C#
private void populateGroups()
{
//this generates correct javascript according to the file and JS fiddle but unfortunately doees not work.
string splitme = "USE ACES SELECT GroupName, GroupID FROM PrimaryGroup ORDER BY GroupName";
DataTable dt = fillDataTable(splitme);
string script = "";
foreach (DataRow dr in dt.Rows)
{
//add the locations to the <select> box
script += " $('#groupList').append('<option value=\" " + dr.ItemArray[1].ToString() + " \"> " + dr.ItemArray[0].ToString() + " </option>'); ";
}
sendScript(script);
JSErrorLog(script, "GROUPS");
}
The whole thing is being called on startup
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack == false)
{
populateMakes();
populateLocation();
populateGroups();
}
}
The jQuery its generating also works in JSFiddle I am pulling this from a method that writes the javascript it generates in a method calling here is the fiddle JSErrorLog.
http://jsfiddle.net/ER2hE/
Oh and my html in my aspx file looks like this
<div class="row2">
<span>Group</span>
<select id="groupList" multiple="multiple" onclick="setGroups()" class="normalsize">
</select>
</div>
I believe that is everything. I just want my stuff to work. I am willing to post any additional code, just ask. If you have an idea as to why its not working, let me know.
When does it actually execute that code? Before or after the element with id "groupList" exists in the DOM? My guess is before.
Solution? Wrap your code inside a document.ready handler.
jQuery(function($) {
$('#groupList').append('<option value=" 46 "> AC Units </option>');
// etc etc
});
Return simple string js code. And run it with eval()

How do I fill in text on an ASP.NET page from a C# program?

I am attempting to fill in an ASP.NET page textbox with some predefined text so that when it is displayed the value is predefined. I have tried
protected void Page_PreRender ()
{
mytextbox.Text = somestring;
}
which works fine in the development environment but on the server produces...
System.NullReferenceException: Object reference not set to an instance of an object
The same applies when I try this in Page_Load. As I read the answers to this question, what I am trying should work (in at least one of these places).
Can anyone see what I am doing wrong?
EDIT more code, as suggested. The C# looks like this:-
protected void Page_PreRender (Object sender, EventArgs e)
{
try
{
string [] file_list;
int i = 0;
file_list = Directory.GetFiles(MyProg.Common.GetDirectory(),
MyProg.Common.GetFileNameRoot() + "*.*");
foreach (string filename in file_list)
{
string filenameonly = Path.GetFileName (filename);
if (filenameonly == MyProg.Common.GetFileNameRoot() + "runlog.log")
{
nametextbox.Text = filenameonly;
}
}
}
catch (Exception ex)
{
string mystring = ex.ToString();
errorMessage.Text = "Page Load Error : " + mystring;
}
}
and the ASP.NET page like this...
<%# Page Language="C#"
AutoEventWireup="true"
CodeBehind="MyDialogue.aspx.cs"
Inherits="MyDialogue" %>
<%# Register assembly="ComponentArt.Web.UI"
namespace="ComponentArt.Web.UI"
tagprefix="ComponentArt" %>
<%# Register assembly="ComponentArt.Web.Visualization.Charting"
namespace="ComponentArt.Web.Visualization.Charting"
tagprefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
</head>
<body>
<form id="myForm" runat="server">
<div style="visibility:hidden">
<asp:TextBox ID="nametextbox"
TextMode="MultiLine"
runat="server"
Visible="true" />
</div>
</form>
</body>
</html>
Did you publish your site but did the filerefence to the codebehind stay in the aspx page?
are you sure the dll in the bin folder?
This should work without complaint. Does the mytextbox control have the runat="server" attribute? You can only access from the codebehind stuff with the runat="server" attribute.
There could be several areas that are causing this problem. How are you sure that you've narrowed it down to the textbox itself? Was this code completely bug-free before adding the textbox message? I'll post your code below with where I think potential null references may be occurring (in comments):
string [] file_list;
int i = 0;
file_list = Directory.GetFiles(MyProg.Common.GetDirectory(),
MyProg.Common.GetFileNameRoot() + "*.*");
// it is possible that file_list is null
// potentially due to an invalid path (missing / perhaps?)
foreach (string filename in file_list)
{
string filenameonly = Path.GetFileName (filename);
// It's possible that the MixedZone.Kernel.Common library
// is experiencing the null reference exception because it
// may not understand what file to get the name root of or
// maybe it is not capable of getting the root for some
// other reason (permissions perhaps?)
if (filenameonly == MixedZone.Kernel.Common.GetFileNameRoot() + "runlog.log")
{
nametextbox.Text = filenameonly;
}
Some possible solutions or safer code:
string [] file_list;
int i = 0;
file_list = Directory.GetFiles(MyProg.Common.GetDirectory(),
MyProg.Common.GetFileNameRoot() + "*.*");
if (file_list == null) throw new Exception("File List is null. Something is wrong.");
foreach (string filename in file_list)
{
string filenameonly = Path.GetFileName (filename);
string fileroot = MixedZone.Kernel.Common.GetFileNameRoot();
if(string.IsNullOrEmpty(fileroot) throw new Exception("MixedZone Library failed.");
if (filenameonly.Equals(fileroot + "runlog.log", StringComparison.OrdinalIgnoreCase)) // Choose your own string comparison here
{
nametextbox.Text = filenameonly;
}
Run with Antivirus disabled on the Production Server?
Compare .Net versions between Production and Development?
"which works fine in the development environment but on the server produces" - so, permissions or missing files perhaps?

Categories

Resources