In asp.net, buttons can have postback urls (ie by specifying a PostBackUrl - I have used this to truncate querystring parameters in the past - by just specifying the page url without any parameters). This is super easy with a button.
Does anyone know what the best approach to doing this is with a dropdownlist? If I specify AutoPostBack (post back when the selection changes), there doesn't seem to be an easy way to modify the postback url (ie postback to the page without querystring parameters).
I'm guessing maybe doing a custom postback with javascript... but is there a better method - like a property as in the asp.net button that I am missing?
No there isn't property with DropDownList. You can redirect the user using Response.Redirect method and use Session collection to persists data between requests.
There isn't that property for DropDownList but you can do some tricks to add this functionality to your pages. First of all let me describe a situation why this property may be necessary for you:
You've got a page with a gridview filled from a database. For example a list of employees of your company. The fields are id, name, surname, jobname etc.
You can open this page from other pages of your project and then in some cases you have to select one of your employees in the gridview. So you need a parameter with id of that employee that you can pass to the gridview page.
Of course for this purposes you can use session variables but in some cases they are not accepted. For example session varibles aren't so good with the back button. You can press back many times, return to the gridview page from the browser history with selected employee but the session variable will contain the last set id and not the opened now! And now imagine that you have a delete button that do its job by the session id. You see one gridview row as the selected one but delete a completely different row.
So the best way to pass parameters to other pages is the query string. You can read it with ease and be sure that the back button will not destroy them.
Now when you are on the page and click the gridview rows you have to modify your url in order to the url id parameter matches the selected row. It can be done with linkbuttons inserted in each row with right filled PostbackUrl property. You click a linkbutton in the row, the linkbutton contains the postbackurl with the correct row id, the postback goes as you want to and both the selected row and the url are ok.
And now imagine that you are in more complicated situation. You've got a dropdownlist on your page which should filter list of employees in your gridview. For example by departments. So you must refill the gridview and get rid of id in the url because after refill you don't need the gridview to have any selected rows. But you can't do it, the dropdownlist doesn't have this magic property...
So here is the solution:
namespace myspace
{
public partial class EmployeePage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//now you should get the correct url
//you can generate it right here but i prefer to use a special method to
//ensure that this url will be the same in all places of my code
string emptyEmpIdPostbackUrl = Utils.GetEmployeePageURL("");
//now call the main method
Utils.CreatePostbackUrl(this, "SetFilterUrl", emptyEmpIdPostbackUrl,
new List<WebControl> { ddlFilterCompany, ddlFilterDepartment, ddlFilterOwner,
ddlFilterType, ddlFilterDiscarded, ddlFilterChangeDate });
if (!IsPostBack)
{
...
}
}
...
}
public static class Utils
{
//page - your gridview page
//name - some custom name to ensure that different postbacks will work independently from each other
//url - the url with empty employee id
//controls - list of webcontrols for which you want to create postback url (i've got 6 dropdownlists on my own page)
public static void CreatePostbackUrl(Page page, string name, string url, List<WebControl> controls)
{
//create a hidden button with your postbackurl
Button btn = new Button();
btn.ID = name;
btn.PostBackUrl = url;
btn.Attributes.Add("style", "display: none;");
page.Form.Controls.Add(btn);
//register javascript that will simulate click on the hidden button
page.ClientScript.RegisterClientScriptBlock(page.GetType(), name + "Script",
"<script type=\"text/javascript\"> function " + name + "() {" +
"var btn = document.getElementById('" + btn.ClientID + "'); " +
"if (btn) btn.click();} </script>", false);
//and link this script to each dropdownlist in the list
foreach (WebControl ctrl in controls)
{
string attrName = "";
if (ctrl is DropDownList)
attrName = "onchange";
if (attrName != "")
ctrl.Attributes.Add(attrName, name + "()");
}
}
public static string GetEmployeePageURL(string empId)
{
return "emp.aspx" +
"?empid=" + empId;
}
}
}
After these manipulations you'll get the page with a hidden button and bunch of webcontrols that will be linked to this button and share its PostBackUrl property.
If you are wanting to POST directly to another page, use could try a hidden button approach
<asp:DropDownList ID="lstMyDropDown" runat="server" ClientIDMode="Static" onchange="javascript:$get('btnHidden').click(); ">
<asp:ListItem Value="0" Text="Some Value 1" />
<asp:ListItem Value="1" Text="Some Value 2" />
</asp:DropDownList>
<asp:Button ID="btnHidden" runat="server" ClientIDMode="Static" PostBackUrl="~/myProcessingPage.aspx" OnClientClick="javascript:if($get('lstPrinterModel').selectedIndex < 1){return false;}" style="display:none" />
Related
I have two dropdownlist in my project and get the items from sql server. One of them show list of something (And I named it DropdownSoore) and another one show list of members of it (And I named it DropdownAye) that update when select an item from DropdownSoore. then when select an item from DropdownAye go to page of them by forwarding query string. I have no problem to updating DropdownAye but when I select item from it and redirect to page of it, the DropdownAye lose the selected item and show the first item (as default) and index to query string in url.
what should I do?
Excuse me about my grammer, I'm not English...
I set DropdownSoore:
<asp:DropDownList ID="DropDownListSoore" runat="server" class="nav-link btn btn-outline-secondary dropdown-toggle" aria-haspopup="true" aria-expanded="true" AutoPostBack="True"></asp:DropDownList>
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
string IdSoore = Convert.ToString(dt.Rows[i]["IdSoore"]);
string NameSoore = Convert.ToString(dt.Rows[i]["NameSoore"]);
DropDownListSoore.Items.Add(IdSoore + "." + NameSoore);
}
string forwardedIdSoore = Request.QueryString["IdSoore"];
if (forwardedIdSoore != null)
{
DropDownListSoore.Items.FindByValue(forwardedIdSoore);
}
And then set DropdownAye:
<asp:DropDownList ID="DropDownListAye" runat="server" class="nav-link btn btn-outline-secondary dropdown-toggle" aria-haspopup="true" aria-expanded="true" OnSelectedIndexChanged="DropDownListAye_SelectedIndexChanged" AutoPostBack="True"></asp:DropDownList>
DropDownListAye.Items.Clear();
for (int i = 0; i <= dt1.Rows.Count - 1; i++)
{
DropDownListAye.Items.Add(Convert.ToString(dt1.Rows[i]["NumberAye"]));
}
int iSelectedAye = Convert.ToInt32(DropDownListAye.SelectedIndex) + 1;
string SelectedAye = Convert.ToString(dt1.Rows[iSelectedAye]["IdAye"]);
Session["SSelectedAye"] = SelectedAye;
string forwardedIdAye = Request.QueryString["IdAye"];
if (forwardedIdSoore != null)
{
DropDownListSoore.Items.FindByValue(forwardedIdAye);
}
in page_Load. and dont have problem to update DopdownAye but when I used it to redirect always get IdAye=1 in url and show the first item of DropdownAye ...:
protected void DropDownListAye_SelectedIndexChanged(object sender, EventArgs e)
{
int SelectedAye = Convert.ToInt32(Session["SSelectedAye"]);
int SelectedSoore = Convert.ToInt32(DropDownListSoore.SelectedIndex) + 1;
string forward = "~/contentAye.aspx?IdSoore=" + SelectedSoore + "&IdAye=" + SelectedAye;
Response.Redirect(forward);
}
I try !IsPostBack but dont have utility too.
I do all thing I think and i dont know what shoild i do.
And where are you loading up these infomration?
Remember, page load ALWAYS fires and triggers for each post-back, for each button click, and any OTHER event on the page that calls code behind.
What does the above really mean?
Well, it means that you need to ONLY ONE TIME load up the drop downs, the gridview(s), or whatever else you have.
So, for the last 200+ web pages I have built, I ALWAYS have this code stub in the page load event:
so this markup:
<h3>Select Hotel</h3>
<asp:DropDownList ID="DropDownList1" runat="server"
DataValueField="ID"
DataTextField="HotelName" Width="356px">
</asp:DropDownList>
<br />
<br />
<asp:Button ID="Button1" runat="server"
Text="Show/get/display drop selection" OnClick="Button1_Click"
CssClass="btn" />
<br />
<h3>Selected result</h3>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
and code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// load up data, controls etc.
string strSQL =
"SELECT ID, HotelName FROM tblHotelsA ORDER BY HotelName";
DataTable dt = General.MyRst(strSQL);
DropDownList1.DataSource = dt;
DropDownList1.DataBind();
DropDownList1.Items.Insert(0, new ListItem("Please Select Hotel", ""));
}
}
protected void Button1_Click(object sender, EventArgs e)
{
string sResault =
$#"dropdown list value (pkid) = {DropDownList1.SelectedItem.Value}
<br/>
Dropdown list Text (Hotel) = {DropDownList1.SelectedItem.Text}";
Label1.Text = sResault;
}
and the result:
SUPER important:
If I leave out the !IsPostBack test in page load, then for EVERY button click, the dropdown list re-load code will trigger, and runs BEFORE your button stubb, or post back. As a result, I will see/find/get no valid value from the drop down list, since page load ALWAYS runs before the given code stub, and thus if page load "every time" re-loads the data, then it will blow out the choosen value in the drop down list.
So, loading up of grids, data, dropdowns etc. can ONLY occur one time in page load, since page load ALWAYS runs before each button or event code stub you have behind.
If you thus only load up the controls and dropdowns on the first REAL page load, then the values the user selects in those dropdowns should work, but only will work if you ALWAYS include that all important if (!IsPostBack) code stub in your page load event.
Now, of course in place of that button to loadup + display the dropdown list into that label?
Well, of course that button click may well (like often) jump or navigate to another page. So, in place of that code to fill out the selected value(s) into that lable, we could pass the selected value to the next page. And how to do that? Well, you can use session(), you can use parmaters in the URL, or you can even use a post-back URL, and then the WHOLE previous page becomes available (Page.Previous), which then in theory allows you to grab ANY and ALL values from the previous page.
but, say we choose session() to pass the value, then this:
Session["HotelPK"] = DropDownList1.SelectedItem.Value;
Response.Redirect("GridFun3.aspx");
Page 1 - Ticket.aspx, DropDownList1, ModalPopUpextender with id mpe
Page 2 - Customer.aspx, btnSave
The index change event of dropdown will pop up mpe which has an iframe. This iframe loads Customer.aspx.
I am trying to access page1 controls in the button click event, but unable to.
Customer.aspx.cs:
protected void btnSave_Click()
{
Ticket page = new Ticket();
ModalPopUpExtender mpe = (ModalPopUpExtender)page.FindControl("mpe");
DropDownList ddl = (DropDownList)page.FindControl("DropDownList1");
//error here - Object reference not set to an instance
mpe.hide();
ddl.selectedindex=0;
}
Why is this not working. Using a Session variable should work right?
You may use Server.Transefer instead of Response.Redirect and then you can find the control in the current page.
Like:
TextBox tb = (TextBox)PreviousPage.FindControl("textbox1");
EDIT:
if (Page.PreviousPage != null)
{
DropDownList ddl1 =
(DropDownList)Page.PreviousPage.FindControl("DropDownList1");
if (ddl1 != null)
{
Label1.Text = ddl1.SelectedItem.Text; //your logic
}
}
What you are trying may not be doable from the server side, but it can be easily be done with a little javascript. Here is a link where you can get a working piece of code.
Hope this helps.
I have the following markup:
<td>
<asp:DropDownList runat="server" ID="ddlExtRouteBusyID" style="width: 320px;" />
</td>
And code behind that executes on page load:
//Bind the route busy drop down list:
DataTable dr = /*[some DataTable returned from a wrapper to an RDBMS*/;
this.ddlExtRouteBusyID.DataSource = dt;
this.ddlExtRouteBusyID.DataTextField = "description";
this.ddlExtRouteBusyID.DataValueField = "id";
this.ddlExtRouteBusyID.DataBind();
I cannot seem to access the description and ID data based upon the value of the SelectedItem/Value. For example if I select the second list item, the SelectedIndex is 1, but the description might be "server2" and the ID might be 1118. How can I pull the description and ID values?
Thanks.
You can use the following to get the text and the value:
ddlExtRouteBusyID.SelectedItem.Text
ddlExtReouteBusyID.SelectedItem.Value
If this doesn't work there may be some other problem with what the page is doing, since I just verified that these worked for me.
There are some things not cleared in question, so here are some of the Options I thought about..
1) If you want to access value and text client side you can use simple JQUERY as follows..
$("#ddlExtRouteBusyID.ClientID").change(function() {
selectval();
});
$("#ddlExtRouteBusyID.ClientID").click(function() {
selectval();
});
function selectval(){
alert('Text:' + $('#ddlExtRouteBusyID.ClientID :selected').text() + ', value = ' + $("#ddlExtRouteBusyID.ClientID").val());
}
2) Use the values on server side then HOW?, I mean onSelectedIndexChange or On Any ButtonClick event
Note : to use any way the dropdownlist databind method should be kept in if(!IsPostBack)
You need to add two properties to your DropDownList definition, OnSelectedIndexChanged and AutoPostBack, like this:
<asp:DropDownList runat="server" ID="ddlExtRouteBusyID" style="width: 320px;"
OnSelectedIndexChanged="Index_Changed" AutoPostBack="true" />
Now you need to write code in your code-behind to handle the SelectedIndexChanged event, like this:
protected void Index_Changed(Object sender, EventArgs e)
{
// Put logic here to grab values from drop down list
Label1.Text = "You selected " + ddlExtRouteBusyID.SelectedItem.Text +
" with a value of " + ddlExtRouteBusyID.SelectedItem.Value +
".";
}
Note: AutoPostBack=true is what causes the page to post back to the server when the drop down list value changes; otherwise the drop down list change event will not fire.
I currently have a dropdown list being populated with values from a database. I need to add an additional value in the dropdown to allow the users to add another value. This new value will be "Add Contact" and if selected will take the user to a new page. Is this possible to do and how would I go about doing it?
You can add "Add Contact ... " as a normal text and in the SelectedIndexChanged event of the dropdown (don't remember the exact name of the event), check if the selected value is "Add Contact", call the AddContact() method.
<asp:DropDownList ID="DrpDwnLstRecords" runat="server" AutoPostBack="True" OnSelectedIndexChanged="DrpDwnLstRecords_SelectedIndexChanged"/>
private void FillDrpDwnLstRecords()
{
DrpDwnLstRecords.Items.Clear();
ListItem listItem = new ListItem("Add Contact","addContact");
//fill the dropdown from database here
}
protected void DrpDwnLstRecords_SelectedIndexChanged(..,..)
{
string selectedRecordValue = DrpDwnLstRecords.SelectValue;
if(selectedRecordValue == "addContact")
{
//go to new page
}
}
For more help with DropDownLists and opening new page
a SO answer
DropDownList Web Server Control Declarative Syntax
DropDownList Class
How to add listitem in dropdownlist using C# behind code.
DropDownList in ASP .Net
HOW TO: Add a default ListItem to a DropDownList
Opening a New Window - How to open a new window with JavaScript
Hi I'm having a bit of an issue with a asp.net repeater
I'm building a categories carousel with the dynamic categories being output by a repeater.
Each item is a LinkButton control that passes an argument of the category id to the onItemClick handler.
a page variable is set by this handler to track what the selected category id is....
public String SelectedID
{
get
{
object o = this.ViewState["_SelectedID"];
if (o == null)
return "-1";
else
return (String)o;
}
set
{
this.ViewState["_SelectedID"] = value;
}
}
problem is that i cant seem to read this value while iterating through the repeater as follows...
<asp:Repeater ID="categoriesCarouselRepeater" runat="server"
onitemcommand="categoriesCarouselRepeater_ItemCommand">
<ItemTemplate>
<%#Convert.ToInt32(Eval("CategoryID")) == Convert.ToInt32(SelectedID) ? "<div class=\"selectedcategory\">":"<div>"%>
<asp:LinkButton ID="LinkButton1" CommandName="select_category" CommandArgument='<%#Eval("CategoryID")%>' runat="server"><img src="<%#Eval("imageSource")%>" alt="category" /><br />
</div>
</ItemTemplate>
</asp:Repeater>
calling <%=SelectedID%> in the item template works but when i try the following expression the value of SelectedID returns empty..
<%#Convert.ToInt32(Eval("CategoryID")) == Convert.ToInt32(SelectedID) ? "match" : "not a match"%>
the value is being set as follows...
protected void categoriesCarouselRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
SelectedID = e.CommandArgument.ToString();
}
Any ideas whats wrong here?
Within the categoriesCarouselRepeater_ItemCommand code you've shown, you're assigning the CommandArgument to a property called 'SelectedCategory'.
Should this not be assigning the property to the 'SelectedID' property instead?
** EDIT..
The problem I see is one of two scenarios:
1) You are not rebinding the repeater with each postback, and therefore the expression within your ItemTemplate is not being evaluated - The output from the repeater will remain unchanged with each postback.
OR
2) You are rebinding the repeater control with each postback, however, upon clicking on your LinkButton for the first time, the repeater control is re-binded PRIOR to the ItemCommand event handler firing, and therefore, the 'SelectedID' property has not been set until after the repeater has finished being output.
If you were to click on one of your LinkButtons a 2nd time, the previously selected ID would be in viewstate at the time of the repeater control contents being rendered, and therefore be one step behind in rendering which category has been clicked, and so on...