How to access literal control in javascript - asp.net

I have got a literal control on page (with some data on it). i want to access it in javascript and want to put some text on it. please tell me how can i access literal control in javascript. (i am using asp.net)
My code in javascript (but not working):
lths = document.getElementById("<%= lblhs.ClientID %>");
lths.innerHTML = 'this is text line"

You can find it using document.getElementById('<%= myControl.ClientID %>') or if you are using .NET 4.0 you can directly set the id field to be pulled by javascript. Alternatively you can use jquery's selectors. Your code isn't working because the Literal control doesn't render as an element, just static text. You can place a span around it, or use a Label control, which renders as a span for you.

I don't think that you can access a literal control from your javascript client code because a literal control just renders it's pure value without any surrounding tags. So you don't really have an element which you could get by id.
What you could to is changing the literal control to a label control. This renders out as a html span tag by default. Like that you can select it on the client side.
Another option would be to write a span or div tag in your literal control on the server side like this:
myLiteral.Text = "<div id=\"myDiv\">Some Text here</div>"
on the client you could select the elemnt by using:
var myDiv = document.getElementById('myDiv');

Just to rule out the obvious (since no one else mentioned it), this is a syntax error in JS:
lths.innerHTML = 'this is text line"
Not sure if this was a typing error here, or if you copied it from your code. You can use either " or ' but not both to surround a string. Also, you should use terminating semi-colons as best practice (although it's not required).
lths.innerHTML = 'this is text line';

The <%= myControl.ClientId %> technique does not work when you are using master pages. That could be the case.
What you can do is: Take a hidden field. Save the ID of the label in the hidden field. Access the value attribute to get the ID and then use document.getElementByID('HiddenField.Value') to get the control.

Related

ASP.NET dynamic controls and validators - Unable to find control id '...' referenced by the 'ControlToValidate' property of '...'

I have seem many forum posts / responses on this subject but I am no closer to a solution.
I am loading a repeating data structure from the DB into UpdatePanel controls in an event handler. The number of repeats varies so controls are all created and added to a container panel dynamically. The user has the ability to edit the data so I am also dynamically creating validator controls (RegularExpressionValidators)
The problem is in setting the ControlToValidate property of the validator. No matter how I set this I get the Unable to find control id '...' referenced by the 'ControlToValidate' property of '...' error response from the server which is then raised by ASP.NET AJAX JS.
The short version of the control adding code looks like this:
TextBox licenseCode = new TextBox();
licenseCode.ID = this.getNextId(); // generated ID contains only [A-Za-Z], [0-9], :, -, .
licenseCode.MaxLength = 50;
this.purchaseEdit.Controls.Add(licenseCode); // this.purchaseEdit is an asp:Panel
RegularExpressionValidator licenseCodeVal = new RegularExpressionValidator();
licenseCodeVal.ControlToValidate = licenseCode.ClientID;
licenseCodeVal.ID = this.getNextId();
licenseCodeVal.ValidationGroup = this.purchaseEditSave.ValidationGroup; // save button within the panel
licenseCodeVal.ValidationExpression = #"^.{1," + licenseCode.MaxLength.ToString() + "}$";
licenseCodeVal.ErrorMessage = "Between 1 and " + licenseCode.MaxLength.ToString() + " chars.";
this.purchaseEdit.Controls.Add(licenseCodeVal);
As you can see both controls are added to the same container, the validator is added after the TextBox, and the ControlToValidate property is currently set to the ClientID of the TextBox. I have tried the ID value too but no joy.
The really irritating thing is that if I don't add the validator, and using a breakpoint inspect the ClientID of the TextBox, I can inspect the DOM of the updated page and find the ID attribute of the TextBox:
<input type="text" id="ctl00_ContentBody_PCTL::4890cc3a-8d07-4dee-aa9f-bdd8735fcaf8::licCode"... />
As far as I can tell I'm not doing anything wrong, so why am I getting this error??
Any suggestions much appreciated.
You should not use the ClientID but the ID of the TextBox.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.basevalidator.controltovalidate.aspx
"I have tried the ID value too but no joy."
But you didn't get an exception and only the validation didn't work?!
My suggestion is to wrap the control and the validator in an UserControl and add this dynamically to your container-control. On this way you can use fix ID's because they all have distinct NamingContainers.
The code will be cleaner. Encapsulation also increases reusability.
ARGH so I finally figured this thing out - it came down to special characters in the ID. I was having an issue with a JQuery selector which contained ':' and figured I should just check if that was causing the validator issues - it was.
In the end I created my GUIDs without any hyphens and replaced ':' with '_' and the problem went away. This question helped.
I haven't seen anything from MSDN saying certain characters are not permitted in IDs, but then I tend to refer to MSDN with specific problems after jumping in, so maybe there is something on there.. See comment below

How to make a textbox accept html tags

I have a textbox in my aspx page. The user wants to have the ability to input html tags in the textbox. The only way so far I know to by pass the validation error is set the ValidateRequest to false. I tried couple of other ways:
(1) using Server.HtmlEncode in a javascript like this
<%# Import Namespace="System.Web" %>
var tb = document.getElementById("<%=synopsisTextBox.ClientID%>");
var value =Server.HtmlEncode(tb.value);
But I got compiler error. Can anyone tell me what I did wrong?
(2) creating my own encode function
function escapeHTML (str)
{
var div = document.createElement('div');
var text = document.createTextNode(str);
div.appendChild(text);
return div.innerHTML;
}
somehow it didn't work quite well. When I click some button that causes postback in the same page, it gets stuck.
Can anyone tell me if there is a better way to make your textbox accept html tags? Thanks.
Just disable input validation (for the page only) and make sure you encode input from other textboxes in the page. Input validation is on by default not because it shouldn't be disabled ever but because you should know what you are doing and do it explicitly. This way you are sure to pay attention and do your own input validation.
If you need to encode html tags and show them on a browser remember that
<%= Server.HTMLEncode("The paragraph tag: <P>") %>
produces the following output:
The paragraph tag: <P>
that will be displayed by a Web browser as:
The paragraph tag: <P>
Your trial with Server.HTMLEncode is not working, since it works when data are on the server and need to be encoded before sending to the browses. In your sample, data are on the browser and request is blocked on validation before being recieved on the server .
If you want user to edit TextBox and enter html tags you can disable this via
<%# Page validateRequest="false" ...>
or in the web.config for your entire application:
<system.web>
<page validateRequest="false" />
</system.web>
Note that this ValidateRequest property is not existing without
reason. When you change its default value, insecure input will be
accepted. Because of that, you need to validate every user's input to
avoid cross-site scripting attacks, like inserting of malicious
JavaScript, ActiveX, Flash or HTML
Another smart solution is to replace via javascript text written by user to make it safe for validation.
< tag> , instead of <tag> is considered safe!
function validateTxt() {
$("textarea, input[type='text']").change(function () {
html = $(this).val(); //get the value
//.replace("a" , "b") works only on first occurrence of "a"
html = html.replace(/< /g, "<"); //before: if there's space after < remove
html = html.replace(/</g, "< "); // add space after <
$(this).val(html); //set new value
});
}
$(document).ready(function () {
validateTxt();
});
IMO, you have these following solutions:
Follow #Stilgar and also use Anti-XSS for encoding.
Use Textile or BBCode markup language instead of HTML.

How to output results in color to a web page? (Response.Write alternative?)

I am converting an old script from ASP to ASP.NET and would like some advice. The original ASP script used Response.Write to output information about what happened during execution. I have rewritten the entire thing in ASP.NET but it is new to me as an old-school C programmer. The job requirements include using the VB flavor of ASP.NET, btw.
I originally put up a TextBox and edited the text property to dump my final report. Now they want different colors for different message importance and I find that the TextBox can only do one color for all lines. I fell back to the old standby R.W but I get a message that it's not declared and from looking around I see that it's an issue because I'm calling it from the code behind and that is 'out of scope' from the HTML elements of the page itself.
My question is what is the best way to output information to the web page with different lines being different colors from a page's code-behind?
Secondary question - if I have misunderstood anything feel free to correct my thinking. :)
Thanks!
Literal is the correct approach in my opinion too, to prevent messiness you can wrap it nicely with some functions.
First, have one literal control that will be the messages placeholder:
<asp:Literal id="litMessages" runat="server" />
Second, use CSS for the colors it's more elegant and flexible.. for example:
<style type="text/css">
.msg_information { color: blue; }
.msg_error { color: red; }
.msg_warning { color: purple; }
</style>
Now have this function:
void AddMessage(string message, string type)
{
string strHTML = string.Format("<div class=\"msg_{0}\">{1}</div>", type, message);
litMessages.Text += strHTML;
}
And finally to add message have such code anywhere in your code:
AddMessage("method started successfully", "information");
AddMessage("Failed to do this: " + someErrorMessage, "error");
AddMessage("Value is empty", "warning");
You can make it even more elegant by using enum for message type and more, but the above is enough for basic needs. :)
By having each message in its own <div> you make it be in its own line automatically and you can control each message easier with CSS.
Edit: my code is C# but can be converted easily to VB.NET as well.
Why not just wrap your Response.Write in a span with a color attribute based on what you are outputting? e.g.
Response.Write(String.Format(#"<span style=""color: #{0}"">{1}</span>", System.Drawing.ColorTranslator.ToHtml(Color.Red),yourMessage))
To make it simpler, you could then do something like this:
private void ReponseWriteEx(string output, Color color)
{
Response.Write(String.Format(#"<span style=""color: #{0}"">{1}</span>", System.Drawing.ColorTranslator.ToHtml(color),output))
}
And then call it, e.g. ResponseWriteEx("Hello World!",Color.Blue);
#Deverill,
Could you use a grid view and each row is a message? That way you can apply colors to the grid view.
I am not sure why you were using a text box and not a label.
Wince you were using Response.Write i am going to assume that you do not need user input.
your best bet here is the Literal control.
LiteralControl Class Unlike a label (or textbox) it can contain any html. This will let you place spans with classes around any text that you need. You may have to set some options on the literal to allow html

How to add client side OnClick actions to text in ASP.NET

I'm generating a table of content in an ASP.NET page and I want to add client side OnClick actions to each cell (the action should be to set the value of a named TextBox control to the text in the clicked cell). If I could directly add stuff to the HTML output, I think I could do this with a single line of JavaScript in each cell.
Given that I'me not now using JQuery (and never have before), what is the simplest solution to adding this (including the time spent learning stuff)?
Edit: this seems to work
If you are creating your table programmatically, using HtmlControls, you can set the onclick client attribute of the HtmlTableCell:
HtmlTableCell cell = new HtmlTableCell();
cell.Attributes.Add("onclick", "someFunction();");
However, if you're using jQuery you can do something like this:
$('td').click(function(){ // Select all the table cells on the document.
$(this).html($('#textboxId').val()); // When clicked, change the innerHTML
}); // with a textbox value.
it depends how you're generating that table of content.
If bulding up using a table control, you can add JavaScript to TableCell controls using the Attributes.Add() method.
If building up with the GridView, you can add JavaScript when the RowDataBound event is raised
You should give each cell a css class... class="contentsCell"
You can then add the following script to your head tag (along with a jquery include)
$(document).ready(function(){
$(".contentsCell").click(function(){
CallYourFunction();
})
})
Where CallYourFunction() is you own function...
This will basically attach an
onclick=" CallYourFunction();"
to each td cell (or any other element) with the class "contentsCell"
Also, if you want to grab the text inside the cell, something like:
$(document).ready(function(){
$(".contentsCell").click(function(){
var mytext = $(this).text();
CallYourFunction(mytext);
});
});
Check out visualjquery.com for a great reference for jquery
Well, your question is kind of difficult to follow, but I'll give you a few pointers.
Each control has a ClientID property. This is useful for injecting into your javascript so you know the client side id of the control.
jQuery syntax for putting text into a textbox would be like the following:
$("#" + clientId).attr("value", theValue);
and the jQuery syntax for getting text from a cell would be:
$("#" + cellId).html()

How can you move ASP.Net controls to different places on the Web form at runtime?

Is there an accepted way to "move" a control.
My client wants to place a certain chunk of markup (representing some visual element) in one of several different places on the page. The locations are different to the point that I can't effect the change on CSS along (by floating it or something).
I considered just putting the control in multiple spots with Visible set to "false," then displaying the one in the place they wanted for that particular page.
However, the code for this control is not trivial -- there's a couple template sections, for instance. Having to dupe this in multiple places would get unwieldy. Also, I don't want to have to work with this control strictly from the code-behind for the same reason.
So, I'd like to put it in one place on the Web form, the move it around based on where I want it. Could I put Placeholders in different spots, have the control in one spot, then remove and add it to the right spot? I suspect this would work.
Does someone have a better idea? Is there a best practice for this?
I'd recommend using a placeholder control, moving your markup into a separate user control, then loading this at runtime and adding it to the relevant placeholder.
Eg.
// Load a user control
MyControl userCtrl = (MyControl) LoadControl("~/Controls/MyControl.ascx");
// Or create an instance of your control
SubclassedControl subclassedCtrl = new SubclassedControl();
// Do stuff with controls here
userCtrl.LoadData();
subclassedCtrl.Text = "Hello World";
// Check which placeholder to add controls to
PlaceHolder placeHolder = (foo=="bar") ? placeHolder1 : placeHolder2;
// Add the controls
placeHolder.Controls.Add(userCtrl);
placeHolder.Controls.Add(subclassedCtrl);
This will avoid cluttering up your page with unnecessary markup, and loading it at runtime will also avoid unnecessary confusion later, when another developer looks at the code and can't immediately see why a control is in one place in the markup, but renders on a completely different part of the page.
An alternative (and one I've seen done many times before) is through javascript and the DOM. Render your control inside a hidden div tag. So you would render your content here:
<div id='rendercontent' style='display:none'>
.. control here ..
</div>
Then, lets say you wanted to move it all here (the span tag is inside because that's what we're going to replace):
<div id='newlocation1'><span></span></div>
You would define the following javascript:
<script language="JavaScript">
function replaceNode(newElementID, targetElementID)
{
var targetElement=document.getElementById(targetElementID);
var newElement=document.getElementById(newElementID);
targetElement.replaceChild(newElement, targetElement.firstChild);
}
</script>
And when you want to move the content to the new location, call:
<script language="JavaScript">
replaceNode('rendercontent','newlocation1');
</script>
Do Web Parts do what you want to do?
Or, you can change the parent programmatically of your controls to move them into a separate area.
You can override the Render method and place the controls wherever you want in the html.
You only need to add controls to the Controls collection that must interact on the server. The rest of your HTML can just be written to the response stream. If you override Render you can create the html anyway you see fit, placing the controls in any order.
Below is an example of how to write out your html.
protected override void Render(HtmlTextWriter writer)
{
AddAttributesToRender(writer);
writer.RenderBeginTag(TagKey);
writer.RenderBeginTag(HtmlTextWriterTag.Div);
_control.RenderControl(writer);
writer.RenderEndTag();
writer.RenderEndTag();
}
You could always put panels in the pre-defined locations and add the control to the specific panel at runtime.. Here's an example adding a label (the label could be replaced with any control).
Dim lblDisplay As Label = New Label()
lblDisplay.ID = "myLabel"
lblDisplay.Text = "Some Text"
pnlDisplay.Controls.Add(lblDisplay)
As far as...
"Also, I don't want to have to work
with this control strictly from the
code-behind for the same reason."
I think you're going to have to do most of your work in the code behind.
PS.. a good example of the whole usercontrol setup can be downloaded here..
http://www.asp.net/downloads/starter-kits/time-tracker/

Resources