Populating a drop down list using AJAX - asp.net

I have 3 drop down boxes, created using the HTML select tag. On page load, the first box has a few names. Now, when I click on one of the names in the first box, some more names should appear in the second and when I click on a name in the second box, some more names should appear in the third box. How can I achieve this using AJAX? I have to use ASP.Net and MS SQL Server only. I'm a complete noob to AJAX and I've been educating myself about it, but nothing's working out. I've been looking for the code for close to a week. I looked up w3schools.com, but when I tried that code, it didn't work. Please help me out and please tell me step by step, the things required in order to make it work, and what goes where. I have a deadline that is fast approaching and am at my wit's end trying to make it work. HELP ME!!

I would recommend placing the three dropdownlists in an UpdatePanel and adding a trigger to each for the updatepanel. Then, when the value changes, re-populate the dropdown and let the updatepanel push the update. Also keeps session-state in case you want to submit the values.
I don't have a compiler in front of me, but if need be just post a comment and I'll post the code tomorrow.
Working Example
I'm using the "Traditional template" that comes with visual studio and the master page, so excuse the content place holders. But this should demonstrate what I mean:
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="MultiDropDown.aspx.cs" Inherits="AppSettingsRetrieval.MultiDropDown" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
String[] options = new[] { "ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VWX", "YZA" };
foreach (String option in options)
{
this.DropDownList1.Items.Add(new ListItem(option, option));
}
}
}
public void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
this.DropDownList2.Items.Clear();
this.DropDownList2.Items.Add(new ListItem("--- Please Select One ---"));
String[] options = new[] { "123", "456", "789", "101", "112", "131", "415", "161", "718" };
foreach (String option in options)
{
var str = String.Format("{0} {1}", this.DropDownList1.SelectedValue, option);
this.DropDownList2.Items.Add(new ListItem(str, str));
}
this.DropDownList2.Enabled = true;
this.DropDownList3.Enabled = false;
}
public void DropDownList2_SelectedIndexChanged(object sender, EventArgs e)
{
this.DropDownList3.Items.Clear();
this.DropDownList3.Items.Add(new ListItem("--- Please Select One ---"));
String[] options = new[] { "test", "testing", "tester", "foo", "bar", "foobar" };
foreach (String option in options)
{
var str = String.Format("{0} {1}", this.DropDownList2.SelectedValue, option);
this.DropDownList3.Items.Add(new ListItem(str, str));
}
this.DropDownList3.Enabled = true;
}
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:ScriptManager runat="server" ID="ScriptManager1"></asp:ScriptManager>
<asp:UpdatePanel runat="server" ID="UpdatePanel1" UpdateMode="Conditional">
<ContentTemplate>
<fieldset>
<legend>Consecutive Dropdown List</legend>
<p>
Primary Filter:
<asp:DropDownList runat="server" ID="DropDownList1" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" AutoPostBack="true">
<asp:ListItem Text="---Please Select One---" />
</asp:DropDownList>
</p>
<p>
Secondary Filter:
<asp:DropDownList runat="server" ID="DropDownList2" OnSelectedIndexChanged="DropDownList2_SelectedIndexChanged" AutoPostBack="true" Enabled="false">
<asp:ListItem Text="---Please Select One---" />
</asp:DropDownList>
</p>
<p>
Final Filter:
<asp:DropDownList runat="server" ID="DropDownList3" Enabled="false">
<asp:ListItem Text="---Please Select One---" />
</asp:DropDownList>
</p>
</fieldset>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>

Related

Play a song selected from a dropdownlist in ASP.Net

I'm using 'label1' like a global variable to pass info from 1 script (type="text/javascript") to another script (runat="server"), however the setAttribute("src",...) with a variable doesn't seem to work. Note that it does work if hardcoded. Here is a portion of my ASP.Net code:
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<script type="text/javascript" >
var soundObject = null;
function PlaySound() {
if (soundObject != null) {
document.body.removeChild(soundObject);
soundObject.removed = true;
soundObject = null;
}
soundObject = document.createElement("embed");
soundObject.setAttribute("src", label1.Text);
soundObject.setAttribute("hidden", true);
soundObject.setAttribute("autostart", true);
document.body.appendChild(soundObject);
}
window.onload = PlaySound;
</script>
<script runat="server" >
void Selection_Change(Object sender, EventArgs e)
{
label1.Text = SongList.SelectedItem.Value.ToString();
Response.Write(SongList.SelectedItem.Value);
}
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<asp:DropDownList id="SongList" AutoPostBack="True" OnSelectedIndexChanged="Selection_Change"
runat="server">
<asp:ListItem Selected="True" Value="Love Is All Around.mp3">
Love Is All Around.mp3</asp:ListItem>
<asp:ListItem Value="Om.mp3">Om.mp3</asp:ListItem>
<asp:ListItem Value="Nights In White Satin.mp3">
Nights In White Satin.mp3</asp:ListItem>
</asp:DropDownList>
<asp:Label ID="label1" Text="Om.mp3" runat="server" />
<input type="button" onclick="PlaySound()" value="Play Sound" />
Your issue is, that your javascript does not find the label1 variable.
You can not just reference asp.net server controls in javascript - javascript doesn't know about them.
Find your label1 via javascript with getElementById and then read the content of the element (in javascript this will be a span). The ID you use in getElementById has to be the ClientID of your label, so if you want to use label1 for an id, you need to set the ClientIDMode property to static.

RegisterStartupScript from code behind not working when Update Panel is used

I have created a radiobutton list followed by one button. I can select one of the item from the radiobutton list and then click the button to execute something. And I want the page to pop up a window if the button is clicked without selecting any of the options from the radiobutton list. My codebehide is like this:
protected void ButtonPP_Click(object sender, EventArgs e)
{
if (radioBtnPP.SelectedIndex < 0)
{
String csname1 = "PopupScript";
Type cstype = this.GetType();
// Get a ClientScriptManager reference from the Page class.
ClientScriptManager cs = Page.ClientScript;
// Check to see if the startup script is already registered.
if (!cs.IsStartupScriptRegistered(cstype, csname1))
{
StringBuilder cstext1 = new StringBuilder();
cstext1.Append("<script type=text/javascript> alert('Please Select Criteria!') </");
cstext1.Append("script>");
cs.RegisterStartupScript(cstype, csname1, cstext1.ToString());
}
}
}
and my html part is:
<asp:RadioButtonList class ="radioBtn" ID="radioBtnACO" runat="server">
<asp:ListItem Text="All Dim" />
<asp:ListItem Text="Select Dim" />
</asp:RadioButtonList>
<asp:Button id ="ButtonPP" class ="buttonRight" runat="server" Text="Run PP" OnClick="ButtonPP_Click" />
This works fine. However, now I don't want to refresh the whole page when i click the button, so I use updatepanel. And I changed my html code to the following:
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="ControlUpdatePanel" runat="server" Visible="True">
<ContentTemplate>
<asp:RadioButtonList class ="radioBtn" ID="radioBtnACO" runat="server">
<asp:ListItem Text="All Dim" />
<asp:ListItem Text="Select Dim" />
</asp:RadioButtonList>
<asp:Button id ="ButtonPP" class ="buttonRight" runat="server" Text="Run PP" OnClick="ButtonPP_Click" />
</ContentTemplate>
</asp:UpdatePanel>
But now my code doesn't work anymore... If I don't select any option from the radiobutton list and just click the button, no window would pop up :( I am sure my codebehind is still executed but seems like it just doesn't passed to my .aspx page...
Anyone please help me out? I don't know what to do now... Millions of thanks!
You need to use ScriptManager.RegisterStartupScript for Ajax.
protected void ButtonPP_Click(object sender, EventArgs e)
{
if (radioBtnACO.SelectedIndex < 0)
{
string csname1 = "PopupScript";
var cstext1 = new StringBuilder();
cstext1.Append("alert('Please Select Criteria!')");
ScriptManager.RegisterStartupScript(this, GetType(), csname1,
cstext1.ToString(), true);
}
}

asp.net create uzer wizard getting a handle on controls in custom steps

I have added an extra step to my uzerwizard
<asp:TemplatedWizardStep id="stpPayment" runat="server" Title="Payment">
<ContentTemplate>
<asp:DropDownList ID="cmbSubs" runat="server" ClientIDMode="Static"
Width="200px">
<asp:ListItem Value="month">Monthly Subscription</asp:ListItem>
<asp:ListItem Value="year">Annual Subscription</asp:ListItem>
</asp:DropDownList>
i am successfully navigating to the new step
protected void NewUserprofileWizard_NextButtonClick(object sender, WizardNavigationEventArgs e)
{
if (NewUserprofileWizard.ActiveStepIndex == 0)
{
NewUserprofileWizard.ActiveStepIndex = 1;
}
}
but I cant get access to the dropdownlist from my codebehind
note: i can get a handle onto the controls in the 1st (createuser) step.
but any controls in the next step always return a null.
this is the code i am using
DropDownList cmb = (DropDownList)NewUserprofileWizard.WizardSteps[1].FindControl("cmbSubs");
i always return a null.
note that this works just fine
TextBox tmp = (TextBox)NewUserprofileWizard.CreateUserStep.ContentTemplateContainer.FindControl("Email");
userProfile.AccountEmail = tmp.Text;
problem seems unique to custom steps
Thanks for the help
Tried Gregors suggestion. no luck. mine always comes up as null.
if thsi helps any:
my wizard is inside a user control..
the page that uses the user control is inside a master page.....
Here is little sample I have created for you, first aspx code:
<asp:CreateUserWizard ID="CreateUserWizard1" runat="server" OnNextButtonClick="CreateUserWizard1_NextButtonClick">
<WizardSteps>
<asp:WizardStep runat="server" Title="My Custom Step">
<asp:DropDownList ID="cmbSubs" runat="server" ClientIDMode="Static"
Width="200px">
<asp:ListItem Value="month">Monthly Subscription</asp:ListItem>
<asp:ListItem Value="year">Annual Subscription</asp:ListItem>
</asp:DropDownList>
</asp:WizardStep>
<asp:CreateUserWizardStep runat="server" />
<asp:CompleteWizardStep runat="server" />
</WizardSteps>
</asp:CreateUserWizard>
And now the code to find first dropdown:
protected void CreateUserWizard1_NextButtonClick(object sender, WizardNavigationEventArgs e)
{
if (e.CurrentStepIndex == 0)
{
//get instance to dropdown...
string selectedValue = null;
string controlId = null;
foreach (var item in CreateUserWizard1.WizardSteps[0].Controls)
{
DropDownList ddl = item as DropDownList;
if (ddl != null)
{
selectedValue = ddl.SelectedValue;
controlId = ddl.ClientID;
break;
}
}
}
}
Of course you can also find your dropdown like this:
DropDownList cmbSubs = CreateUserWizard1.WizardSteps[0].FindControl("cmbSubs") as DropDownList;
Happy coding!
it appears that today my google foo was doing much better
because i am in a templateswizardstep, i have to cast the wizardstep into the templatedwizardstep.
from here i can now find the control. whooohoo!
TemplatedWizardStep step = (TemplatedWizardStep)NewUserprofileWizard.WizardSteps[1];
cmb = (DropDownList)step.ContentTemplateContainer.FindControl("cmbSubs");
Thanks all for the help

ASP.Net AJAX UpdatePanel not working with Repeater and RadioButtons

I have a repeater which includes a radio button in each item, and the whole thing sites inside an update panel. When I select a radio button the whole page reloads. Why is it not just updating the update panel. I've reduced this to a pretty simple example to avoid clutter. Code here...
ASPX...
<asp:ScriptManager ID="SM1" runat="server" />
<asp:UpdatePanel ID="up1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:Repeater runat="server" ID="history">
<ItemTemplate>
<asp:RadioButton runat="server" ID="radioButton" AutoPostBack="true" GroupName="HistoryGroup" OnCheckedChanged="RadioButton_CheckChanged" /><br />
</ItemTemplate>
</asp:Repeater>
<p><asp:Literal runat="server" ID="output" /></p>
</ContentTemplate>
</asp:UpdatePanel>
Code...
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
List<int> list = new List<int>();
for (int i = 0; i < 20; i++)
list.Add(i);
history.DataSource = list.ToArray();
history.DataBind();
}
}
protected void RadioButton_CheckChanged(Object sender, EventArgs e)
{
output.Text = DateTime.Now.ToString();
}
}
Setting ClientIDMode=Auto on the RadioButton should fix it (it's an infamous .NET bug, http://connect.microsoft.com/VisualStudio/feedback/details/584991/clientidmode-static-in-updatepanel-fails-to-do-async-postback)
please add up1.Update() after output.Text = DateTime.Now.ToString(). Your RadioButton is not the trigger for updatepanel
Turns out the solution was to remove the GroupName from the RadioButton. When I remove this tag it fires asynchronously and just updates the panel. I don't actually need this tag anyway (due to the known bug where GroupName doesn't work on RadioButtons in Repeaters) as I handle the grouping within my click event (i.e. uncheck any other RadioButtons of the same name in other repeater items).

Modal ASP.net user control

I have a web form app where a couple of user-controls have been developed and placed on a page where a customer is building an order. The user-controls are pretty extensive in what they do, causing post-backs, etc.
I'd like to display them in a modal fashion without putting them in a separate page (if possible). So therein lies my question.
Is it possible to place user-controls within divs/panels, display them modally and keep them displayed modally (even through postbacks) until the user clicks a button on the control to dismiss it?
I'm basically looking at the modal option because I need to disable the rest of the form while the user is dealing with the sections the user-control is on. So I'm looking for a best-practice approach I suppose and some nudges in the right direction for this.
Thanks!
ADDITION:
I wanted to update this with the code I wrote in hopes that it might help somebody else and also if there is a better way to implement this, then I'm all ears too.
The basics of this is that I'm passing everything back and forth between my user control and the container page through session vars. I use this to tell the container page whether or not the user control is "finished" and until the flag is set to true, the container page just keeps re-displaying the user control modally on each postback. Seems to work well so far.
Markup:
<%# Register Src="../controls/mylabel.ascx" TagName="mylabel" TagPrefix="uc1" %>
<div style="width: 100%;">
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="ButtonAddToCart" runat="server" Text="Add to cart" OnClick="ButtonAddToCartClick" />
</div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Panel ID="pnlOutput" Visible="False" runat="server" Width="500px">
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
<div style="visibility: hidden;">
<asp:Button ID="ButtonHidden" runat="server" Text="Button" />
</div>
<asp:Panel ID="pnlDownload" Visible="False" runat="server">
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<div style="width: 100%;">
<uc1:mylabel ID="mylabel1" runat="server" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Panel>
Code behind:
protected void Page_PreRender(object sender, EventArgs e)
{
InitializeControls();
}
protected void Page_Load(object sender, EventArgs e)
{
InitializeControls();
}
private void InitializeControls()
{
DisplayDownloadPanel(!SessionDownloadComplete);
if (SessionDownloadItemNumber != string.Empty)
{
Label1.Text = SessionDownloadItemNumber != "CANCEL" ? "Item ordered from control was: [" + SessionDownloadItemNumber + "]" : "Order was canceled.";
pnlOutput.Visible = true;
}
}
protected void ButtonAddToCartClick(object sender, EventArgs e)
{
bool haveWeSomeText = string.IsNullOrEmpty(TextBox1.Text) == false;
if (haveWeSomeText == true)
{
SessionDownloadComplete = false;
DisplayDownloadPanel(true);
}
}
private void DisplayDownloadPanel(bool show)
{
pnlDownload.Visible = show;
if (show == true)
{
ModalPopupExtender1.Show();
}
else
{
ModalPopupExtender1.Hide();
}
}
private string SessionDownloadItemNumber
{
get { return Session["DownloadItemNumber"] != null ? Session["DownloadItemNumber"].ToString() : string.Empty; }
}
private bool SessionDownloadComplete
{
get { return Session["DownloadComplete"] == null || Convert.ToBoolean(Session["DownloadComplete"]); }
set { Session["DownloadComplete"] = value; }
}
Have a look at ASP.NET Ajax Toolkit Modal popup extender
Take a look at the jQuery UI dialog.
It is a good solution for cross browser modal dialogs in the browser.
<script>
$(function() {
$( ".dialogClass" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"Delete all items": function() {
$( this ).dialog( "close" );
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
});
</script>
There are a few initial hiccups integrating it with asp.net. But all those are very well documented here on stackover flow itself.

Resources