How do I read the SelectedValue of a DropDownList in code behind, when the option has been added using JavaScript? - asp.net

How do I read the SelectedValue of a DropDownList in code behind, when the option has been added using JavaScript?
A little more background: I have cascading drop down lists, and I would like to fill in the values using JavaScript, so that I avoid postbacks when the user changes the selection in the first drop down list.
I am not allowed to use an Update Panel.
I have build a simple demo demonstrating problem. Here is my markup code:
<p>
<asp:DropDownList runat="server" ID="FilterDropDownList" />
</p>
<p>
<asp:Button runat="server" ID="SearchButton" Text="Search"
onclick="SearchButton_Click" /><br/>
<asp:TextBox runat="server" ID="QueryTextBox" />
</p>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
var filterDropDownListId = '#<%= FilterDropDownList.ClientID %>';
$(filterDropDownListId).append($('<option>').prop('value', 'Alpha').html('A'));
$(filterDropDownListId).append($('<option>').prop('value', 'Beta').html('B'));
});
</script>
And in the code behind I have the following:
protected override void Render(HtmlTextWriter writer)
{
// Register the allowed values for the down down list.
Page.ClientScript.RegisterForEventValidation(FilterDropDownList.UniqueID, "Alpha");
Page.ClientScript.RegisterForEventValidation(FilterDropDownList.UniqueID, "Beta");
base.Render(writer);
}
protected void SearchButton_Click(object sender, EventArgs e)
{
Response.Redirect(
String.Format("{0}?dropdown={1}&query={2}",
Request.Url.AbsolutePath,
FilterDropDownList.SelectedValue,
QueryTextBox.Text));
}
The problem is, that FilterDropDownList.SelectedValue is empty. I would have expected it to be either "Alpha" or "Beta". I can read the value of QueryTextBox.Text without problems.
It is possible to read MyDropDownList.SelectedValue when the values have been populated using JavaScript? Or do a have to use a different approach?

You can always write the selected value to a hidden textbox with javascript and read the value in the code-behind.

Related

Where to catch user control properties being wrapped to be loaded inside a modal?

I have a user control which has a public property (e.g. AlarmID) and this control is wrapped inside a div and when user presses a button on the page, in code-behind the public property of that user control becomes set. then a ScriptManager.RegisterStartupScript is called to show a modal popup which is a div wrapping that control.
My problem is that although in code-behind I first set the public property of that user control, but when the modal popup shows that user control, I cannot access that property
I used Control_PreRender, and Control_Load events but none of them were able to show the correct value of that property in a label inside that control.
For more clarification, here is my code in the code-behind of the control:
protected void Control_Load(object sender, EventArgs e)
{
lblAlarmCode.Text = alarmID.ToString();
}
public int AlarmID
{
get
{
return this.alarmID;
}
set
{
this.alarmID = value;
}
}
What is the exact life-cycle event in which I can catch the property to be shown correctly by that label?
Thanks
Make sure that the modal is attached to the <form> element on the page otherwise it will not be a part of the page lifecycle at all.
Just as a sample, not saying this is your code, but I had to use something similar in order to have <asp:Textbox> and <asp:Button> controls to be brought back and forth across the Request
ASPX code:
<asp:Panel runat="server" ID="pnlWorkItem">
<fieldset>
<legend></legend>
<label>Job Code</label>
<asp:DropDownList runat="server" ID="ddlJobCode" Width="50%" />
<label>Hours</label>
<asp:TextBox runat="server" ID="txtHours" />
</fieldset>
<fieldset>
<legend></legend>
<p><asp:Button runat="server" ID="btnAddWorkItem" OnClick="btnAddWorkItem_Click" text="Add Work Item" /></p>
</fieldset>
</asp:Panel>
Javascript:
$(function () {
var workItemPanel = $("#<%= pnlWorkItem.ClientID %>");
workItemPanel.hide();
$("#add-work").on("click", function () {
$(workItemPanel).dialog({
width: 450,
height: 300
}).parent().appendTo($("form:first"));
});
});
It will append your element to the form element generated by ASP.net and should have your properties set and carried across.
One solution is to set the label in setter. However there might be other solutions but this ways is just working.

Webforms : Simplest way to allow a user to add/remove textboxes?

I don't want to use a gridview because the rest of the form isn't.
I simply need to be able to create a control to dynamically add/remove textboxes and get the value back either as a list of objects or a comma separated string.. It's proving to be much more difficult than it should.
I tried using Jquery + a regular asp.net textbox, but that only works nicely when they're starting from scratch--prepopulating the DOM with their information becomes a pain.
Is there something painfully simple that I'm missing?
It sounds like you could benefit from creating a CompositeControl.
I recently answered a similar question based on dynamically creating textboxes in which I provided a fairly detailed example.
See: Dynamically add a new text box on button click
Hope this helps.
You can add/remove the input[type=text] elements with jquery, and then use Request.Form in your code behind to get the values by element name.
javascript:
var itemCount = 0;
$("#list .add").click(function(){
itemCount++;
$(this).append("<input type='text' name='item"+itemCount+"'/><button class='remove'>Remove</button>");
});
$("#list .remove").click(function(){
$(this).prev().remove();
});
code behind:
string value1 = Request.Form["item1"];
string value2 = Request.Form["item2"];
There are two ways. The following is made using pure WebForm capabilities. Never do it in the production. It uses too much viewstate and too much updatepanel
this is a code behind
public List<String> ValueContainer {
get {
return (List<String>)ViewState["ValueContainer"];
}
set {
ViewState["ValueContainer"] = value;
}
}
protected void Page_Load(object sender, EventArgs e) {
if (!IsPostBack) {
ValueContainer = new List<string>();
}
}
private void PopulateRepeater() {
rp1.DataSource = ValueContainer;
rp1.DataBind();
}
protected void lbAdd_Click(object sender, EventArgs e) {
ValueContainer.Add("");
rp1.DataSource = ValueContainer;
rp1.DataBind();
}
protected void rp1_ItemCommand(Object Sender, RepeaterCommandEventArgs e) {
ValueContainer.RemoveAt(e.Item.ItemIndex);
rp1.DataSource = ValueContainer;
rp1.DataBind();
}
Here is the markup
<asp:ScriptManager runat="server" ID="sm1" />
<asp:UpdatePanel runat="server" ID="up1">
<ContentTemplate>
<asp:Repeater runat="server" OnItemCommand="rp1_ItemCommand" ID="rp1">
<ItemTemplate>
<asp:TextBox runat="server" ID="myTextBox" /> <asp:LinkButton Text="Remove" runat="server" ID="lbRemove" />
</ItemTemplate>
</asp:Repeater>
<asp:LinkButton runat="server" ID="lbAdd" onclick="lbAdd_Click" Text="Add" />
</ContentTemplate>
</asp:UpdatePanel>
This is more lightweight version
<asp:HiddenField runat="server" ID="hfMyField" ClientIDMode="Static" />
<script type="text/javascript">
//<![CDATA[
function addTextBox() {
$("#myTextboxesContainer").append($("<input type='text' />").keyup(function () {
var Data = "";
$("#myTextboxesContainer input").each(function () {
Data += $(this).val() + ",";
});
$("#hfMyField").val(Data);
}));
}
//]]>
</script>
<div id="myTextboxesContainer">
</div>
Add textbox
The idea here is doing all dom manipulations using client script and storing everything in a hidden field. When the data is posted back you can retrive the value of the hidden field in a standard way i.e. hfMyField.Value. In this example it is CSV.

how to invoke server side and client side events in asp web forms

within an asp.net webform I have the following code
<asp:UpdatePanel ID="udpNames" runat="server">
<ContentTemplate>
<div class="expanderheaders">
<asp:Image ID="epImgNames" runat="server" ImageAlign="Middle" CssClass="expanderimage" />
<asp:LinkButton ToolTip="Expand Names" ID="lbtnNames" runat="server" OnClick="lbName_Click"
Text="Names" CssClass="detaillinks" />
</div>
<div class="detailsectionBorders">
<ajax:CollapsiblePanelExtender ID="epNames" runat="server" ExpandControlID="lbtnNames"
CollapseControlID="lbtnNames" Collapsed="true" ExpandedSize="420" ScrollContents="true"
ImageControlID="epImgNames" CollapsedImage="~/images/expandwn.png" ExpandedImage="~/images/expanup.png"
TargetControlID="namePanel" CollapsedSize="0" CollapsedText="Names" AutoExpand="false" />
<asp:Panel ID="namePanel" runat="server">
<asp:PlaceHolder runat="server" ID="PlaceHolderNames" />
</asp:Panel>
</div>
</ContentTemplate>
</asp:UpdatePanel>
DIV tag expanderheaders is a used as a header to the section. It contains a link button an image similar to a expander panel bar.
CollapsiblePanelExtnder is an ajax toolkit control that expands when a asp.net control is clicked (LinkButton) a user control is then loaded into the PlaceHolder to display a new section of data.
This all works fine but I am currently only able to click on the link button to expand the section (as expected). What I would like to do is have the ability to click on the entire div section (expanderHeaders) and have it serve as the control to expand the section.
I have looked at using jQuery and I have been able to duplicate the panel expansion as well as set the DIV layer to function as desired in accepting a client event and not just on an server side control. However, I have been unsuccessful in being able to invoke a server side method to load the user control when using jQuery.
Can anyone provide some guidance on how to either set the existing control up to where the link button could span the entire content of the div layer or use client side script/ jQuery to allow me to call a server side method to load a user control in the page?
Thanks in advance
update to James answer
I tried something similar to this
jquery
$(function () {
$("#panel").hide();
});
$(document).ready(function () {
$(".slide").click(function () {
$("#panel").show("slow");
});
});
and aspx
<div>
<div id="panel" >
<p>stuff here</p>
</div>
<div class="slide" id="div1" runat="server">
<p class="btn-slide">Expand Panel</p>
</div>
</div>
I'll omit the CSS as it is not that important for now
Using this approach clicking on the div layer seems to causes a postback each time clicked so the codebhind is never accessed.
protected void Page_Load (object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
div1.Attributes["onclick"] = ClientScript.GetPostBackEventReference(this, "ClickDiv");
}
}
protected override void RaisePostBackEvent (IPostBackEventHandler source, string eventArgument)
{
//call the RaisePostBack event
base.RaisePostBackEvent(source, eventArgument);
if (eventArgument.ToUpper() == "CLICKDIV")
{
}
}
still no dice.
It would probably be easier to do this with jQuery:
//obviously, adjust this to your needs
$(document).ready(function(){
$(".expanderheaders").click(function(){
$(".detailsectionBorders").hide("slow");
}
});
To do it server-side, if you give the div an ID and can specify runat="server", you can do something like this:
<div id="div1" runat="server">
Expand Me
</div>
Code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
div1.Attributes["onclick"] = ClientScript.GetPostBackEventReference(this, "ClickDiv");
}
}
protected override void RaisePostBackEvent(IPostBackEventHandler source, string eventArgument)
{
//call the RaisePostBack event
base.RaisePostBackEvent(source, eventArgument);
if (eventArgument.ToUpper() == "CLICKDIV")
{
//logic here
}
}

How to use ASP.NET <%= tags in server control attributes?

This works:
<span value="<%= this.Text %>" />
This doesn't work:
<asp:Label Text="<%= this.Text %>" runat="server" />
Why is that?
How can I make the second case work properly, i.e., set the label's text to the value of the "Text" variable?
Use Data binding expressions
<asp:Label ID="Label1" runat="server" Text="<%# DateTime.Now %>" ></asp:Label>
Code behind,
protected void Page_Load(object sender, EventArgs e){
DataBind();
}
you can do this
<asp:Label ID="Label1" runat="server" ><%= variable%></asp:Label>
You will need to set the value of the server control in code
First of all, assign an ID to the label control so you can access the control
<asp:Label ID="myLabel" runat="server" />
Then, in your Page_Load function, set the value of your labels 'Text' field
protected void Page_Load(object sender, EventArgs e)
{
myLabel.Text = 'Whatever you want the label to display';
}
This function will be in your code behind file, or, if you are not using the code behind model, inside your aspx page you will need
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
myLabel.Text = 'Whatever you want the label to display';
}
</script>
Good luck.
In my code i am using something like this easily but in the databound control like ListView Item template
<asp:HyperLink ID="EditAction" class="actionLinks" Visible='<%#Eval("IsTrue").ToString() != "True"%>' runat="server" NavigateUrl='<%# Eval("ContentId","/articles/edit.aspx?articleid={0}")%>' />
But when i tried to use outside the databound control using <%# .. %>, it simply doesn't work.
You can easily do with
My href
But for server controls, and outside of databound control. We need to call DataBind() in pageload event explicitly
<asp:Hyperlink ID="aa" NavigateUrl='<%#myHref%>' >
Not sure how to mark this as such, but this is a bit of a duplicate. See this thread.
I don't think embedding code in to your markup will really make your markup any clearer or more elegant.
<asp:Label> is compiling at runtime and converting to html tags. You can set text with codebehind or like this:
<asp:Label id="Text1" runat="server" />
<% Text1.Text = this.Text;%>
UPD: Seems like my variant doesnt work, this is better:
protected void Page_Load(object sender,EventArgs e)
{
Text1.Text = this.Text;
}
Just pitching this little nugget in for those who want a good technical breakdown of the issue -- https://blogs.msdn.microsoft.com/dancre/2007/02/13/the-difference-between-and-in-asp-net/
I think the crux is in pretty decent agreement with the other answers:
The <%= expressions are evaluated at render time
The <%# expressions are evaluated at DataBind() time and are not evaluated at all if DataBind() is not called.
<%# expressions can be used as properties in server-side controls. <%= expressions cannot.

How do I find the Client ID of control within an ASP.NET GridView?

I have a asp:GridView which contains a asp:TextBox within a TemplateField. I would like to obtain it's ID for use in javascript. Something like this:
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="textDateSent" runat="server" />
<input type="button" value='Today'
onclick="setToday('<%# textDateSent.ClientID %>');" />
</ItemTemplate>
</asp:TemplateField>
But when I compile, I get an error:
The name 'textDateSent' does not exist in the current context
Anybody know how to get the client ID of this TextBox?
Try this:
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="textDateSent" runat="server">
</asp:TextBox>
<input type="button" value='Today' onclick="setToday('<%# ((GridViewRow)Container).FindControl("textDateSent").ClientID %>');" />
</ItemTemplate>
</asp:TemplateField>
Maybe you don't want to do it where you need the ClientID. Check out this post here where the controls in a row are referenced in a generic way.
Change <%# textDateSent.ClientID %> to <%= textDateSent.ClientID %>.
Argh, you may need to use the OnDataBinding event of the grid view. Then put a literal control in your javascript. Then you can get the clientID of the text box and feed that into your literal control.
protected void GridViewName_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//Create an instance of the datarow
DataRowView rowData = (DataRowView)e.Row.DataItem;
//locate your text box
//locate your literal control
//insert the clientID of the textbox into the literal control
}
}
Look here for a great detailed tutorial on working within this context.
You can get client id like this:
protected void Gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string strClientID = ((TextBox)e.Row.FindControl("txtName")).ClientID;
}
}
This will give unique client ID for each textbox in all rows.
I just do this...
var tbl = document.getElementById('<%=GridView.ClientID%>');
var checkBox = tbl.rows[i].cells[11].getElementsByTagName("input")[0].id;
the cell should always be the same and it gets rendered into an input. You may have to change the number at the end if you have more then one input in that cell. This will give you the new clientid/id of the input object (checkbox or whatever)
This is what I did. In the aspx page I just passed the entire object to the javascript function, so I didn't even meed to client id. In my case the object was a drop down list in the EditItemTemplate of the GridView. I added an html onchange(this) event in the aspx code.
<asp:DropDownList ID="custReqRegionsDDL" runat="server" onchange='custReqRegionsDDLOnChange(this)'>
</asp:DropDownList>
here is my javascript
function custReqRegionsDDLOnChange(myDDL)
{
alert('selected text=' + myDDL.options[myDDL.selectedIndex].text);
}

Resources