I am making a project in ASP.NET WebForms. Although I have done it so many times but dropdown list is troubling me a lot this time.
I fetch items from DB and then add them to my dropdown list one by one using FOR loop. That works fine. But the problem is that I cannot select an item from list comfortably, whenever I try to select an item from the drop down list, it snaps the selection to the first element, it becomes very difficult to select the desired item.
How could I fix that?
Suppose I move my cursor over the 9th item in the list then also it selects the 1st and 9th item alternatively so fast that I see both of them as selected.
CodeBehind
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DropDownList1.Items.Clear();
con.ConnectionString = ConfigurationManager.ConnectionStrings["familyConnectionString"].ConnectionString;
con.Open();
adp = new SqlDataAdapter("select distinct family_head from family", con);
DataSet ds = new DataSet();
adp.Fill(ds, "family");
con.Close();
for (int i = 0; i < ds.Tables["family"].Rows.Count; i++)
DropDownList1.Items.Add(ds.Tables["family"].Rows[i][0].ToString());
}
}
ASPX
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:DropDownList ID="DropDownList1" runat="server" Width="150px">
</asp:DropDownList>
<asp:DropDownList ID="DropDownList2" runat="server" Width="150px">
</asp:DropDownList>
<asp:Button ID="Button1" runat="server" Height="30px" onclick="Button1_Click"
Text="Submit" Width="145px" BackColor="#465767" ForeColor="White" />
<asp:RoundedCornersExtender ID="Button1_RoundedCornersExtender" runat="server"
Enabled="True" TargetControlID="Button1" Corners="All" Radius="10">
</asp:RoundedCornersExtender>
<br />
<br />
<br />
</asp:Content>
A CSS Keyframes Animation is working in page background, Can that be a cause?
There seems to be some kind of confusion, as to how databinding works for WebControls. The best reference for that is: http://msdn.microsoft.com/en-us/library/ms178472.aspx
Under the assumption, that all the binding code for DropDownList1 is shown:
DropDownList1.Items.Clear();
shouldn't be neccesary, as the items shouldn't persist per PostBack. (At least I assume that, because all Items will be lost after each PostBack if the DataSource isn't bound again).
The DropDownList needs have the items on each PostBack, if you want to use the DropDownList. You are using
if (!Page.IsPostBack)
which means, that you don't bind the items again, if you have a PostBack. In the link posted above, you can see that Controls set their properties (like which item was selected before clicking a Button) during the LoadEvent, which means that the items need to be binded earlier in the lifecycle, like during OnInit.
Try something like this:
protected void BindDropDownList1()
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["familyConnectionString"].ConnectionString;
con.Open();
adp = new SqlDataAdapter("select distinct family_head from family", con);
DataSet ds = new DataSet();
adp.Fill(ds, "family");
con.Close();
for (int i = 0; i < ds.Tables["family"].Rows.Count; i++)
DropDownList1.Items.Add(ds.Tables["family"].Rows[i][0].ToString());
}
protected override void OnInit(EventArgs e)
{
this.BindDropDownList1();
base.OnInit(e);
}
Another suggestion would be to you the DataSource property of the DropDownList, instead of DropDownList1.Items.Add. If you use this approach, you need to set the DataKeyValue and DataKeyMember properties of the DropDownList:
protected void BindDropDownList1()
{
con.ConnectionString = ConfigurationManager.ConnectionStrings["familyConnectionString"].ConnectionString;
con.Open();
adp = new SqlDataAdapter("select distinct family_head from family", con);
DataSet ds = new DataSet();
adp.Fill(ds, "family");
con.Close();
DropDownList1.DataSource = ds;
DropDownList1.DataBind();
}
Edit:
I think I found your error. You are using controls from the AjaxControlToolKit, but are still using the ScriptManager. For about 2 years, controls from the AjaxControlToolKit require the ToolkitScriptManager. Replace the ScriptManager with a ToolkitScriptManager.
Related
Currently i have two problems.
Problem 1. Im trying to change the Visibility of two Panels based on what value the reader gets from reader["Maskine_Type"].ToString() as you can see in the Codebehind below. Because the Panels are inside a repeater i also use the:
Panel PanelTilbud = (Panel)Page.FindControl("PanelTilbud"); again you can see below. however, when i run the code it gives me a Object reference not set to an instance of an object on PanelTilbud.Visible = true; i assume because it still cant find the Panels. i tested with panels outside of the repeater and it works fine.
I also tried to make the Repeater OnItemDataBound="Repeater1_ItemDataBound"
and changed to Panel PanelTilbud = (Panel)e.Item.FindControl("PanelTilbud");
However then i get the error Insufficient stack to continue executing the program safely
Problem 2.
Inside one of the panels, i run this code
<%# (Eval("Maskine_Tilbud").ToString().Substring(Eval("Maskine_Tilbud").ToString().Length - 2))%>
in order to remove the first two characters in the string from Eval("Maskine_Tilbud") which works fine, however most records in the database will have a null inMaskine_Tilbud and if its null i get the error StartIndex cannot be less than zero which makes sense, but i dont know how else to remove the first two characters from Eval("Maskine_Tilbud")
.aspx markup
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:Panel ID="PanelTilbud" runat="server" Visible="false">
<hr />
<h4 class="radfont text-center">Tilbud! -<%# (Eval("Maskine_Tilbud").ToString().Substring(Eval("Maskine_Tilbud").ToString().Length - 2))%>% pr dag!</h4>
</asp:Panel>
<asp:Panel ID="PanelNormal" runat="server">
<hr />
<h4 class="text-center orangeFont"><%#Eval("Maskine_pris") %><span class="hvidfont">,- pr dag inkl moms</span>
<span class="orangeFont">(<%#Eval("Maskine_Upris") %>,- ekskl)</span>
</h4>
<hr />
</asp:Panel>
</ItemTemplate>
</asp:Repeater>
My Codebehind - in Page_Load
SqlConnection conn = new SqlConnection();
conn.ConnectionString = ConfigurationManager.ConnectionStrings["DatabaseConnectionString1"].ToString();
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT top 1 * FROM [Maskiner] INNER JOIN Maskine_kategori ON Maskiner.Maskine_Kategorinavn = Maskine_kategori.Maskine_kategori_id WHERE ([Maskine_id] = #Maskine_id)";
cmd.Parameters.Add("#Maskine_id", SqlDbType.Int).Value = Request.QueryString["Maskine_id"];
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
Panel PanelTilbud = (Panel)Page.FindControl("PanelTilbud");
Panel PanelNormal = (Panel)Page.FindControl("PanelNormal");
if (reader.Read())
{
if (reader["Maskine_Type"].ToString() == "Tilbud")
{
PanelTilbud.Visible = true;
PanelNormal.Visible = false;
}
if (reader["Maskine_Type"].ToString() == "Normal")
{
PanelTilbud.Visible = false;
PanelNormal.Visible = true;
}
}
conn.Close();
DataTable select_favorit_db = new DataTable();
SqlDataAdapter dt = new SqlDataAdapter(cmd);
dt.Fill(select_favorit_db);
Repeater1.DataSource = select_favorit_db;
Repeater1.DataBind();
I hope you can understand my questions.
Late to the party here. Just thought I should add that you can have methods in your page and use them in your data binding expressions. Sample:
ASPX:
<form id="form1" runat="server">
<asp:Repeater ID="rep" runat="server">
<ItemTemplate>
<asp:Label ID="lab" runat="server"
Text='<%# Trim2Chars(Eval("test")) %>'></asp:Label>
</ItemTemplate>
</asp:Repeater>
</form>
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
//create fake data for demo and bind to repeater
var data = Enumerable.Range(0, 10).Select(i => new { test = "foo " + i });
rep.DataSource = data;
rep.DataBind();
}
public string Trim2Chars(object input)
{
string inputString = input as string;
if (inputString == null)
return "";
if (inputString.Length < 2)
return inputString;
return inputString.Substring(2);
}
This way, you can keep the ASPX file a bit cleaner and have more complex data binding expressions evaluated in the code behind.
You can set the Visibility in the Control itself
<asp:Panel ID="PanelTilbud" runat="server" Visible='<%# Eval("Maskine_Type").ToString() == "myValue" %>'>
</asp:Panel>
Or in the ItemDataBound event code behind
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
//use findcontrol to find the panel and cast it as one
Panel panel = e.Item.FindControl("PanelTilbud") as Panel;
//get the current datarowview
DataRowView row = e.Item.DataItem as DataRowView;
//check the value and change the panel visibility
if (row["Maskine_Type"].ToString() == "myValue")
{
panel.Visible = true;
}
}
To check for NULL values you have to use a ternary operator.
<%# !string.IsNullOrEmpty(Eval("Maskine_Type").ToString()) ? Eval("Maskine_Type").ToString().Substring(0, Eval("Maskine_Type").ToString().Length - 2) : "Field is empty" %>
I am programming in ASP.NET, visual studio. I have a dropdown list created in HTML form. If I dropdown the list, it displays the record from associated column in the table. But what I want is to show the corresponding value / record with that list item.
For example in the table, I have column id, productname and price. After choosing a particular product name (from drop down list), the associated price with it must be displayed in front of it (in a label).
However, By default, I want the drop down list to shows nothing in the beginning.
UPDATE:
Store.aspx:
<form id="form1" runat="server">
<div>
Welcome
<asp:Label ID="Label3" runat="server" ></asp:Label>
<br />
<br />
Products: <asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged" ></asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" SelectCommand="SELECT * FROM [productdata]"></asp:SqlDataSource>
Price:
<asp:Label ID="Label1" runat="server" ></asp:Label>
<br />
<br />
<asp:Button ID="Button1" runat="server" Text="Add to Cart" />
<br />
<br />
Items in cart: <asp:DropDownList ID="DropDownList2" runat="server"></asp:DropDownList>
<br />
<br />
Total Price: <asp:Label ID="Label2" runat="server"></asp:Label>
</div>
</form>
Store.aspx.cs:
public partial class Store : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Label3.Text = Request.QueryString["name"];//show welcome text
String cs = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
if (!IsPostBack)
{
using (SqlConnection sc = new SqlConnection(cs))
{
SqlCommand sqlcom = new SqlCommand("Select id, productname, price from productdata", sc);
sc.Open();
DropDownList1.DataTextField = "productname";//show in the dropdown list
DropDownList1.DataValueField = "price"; //show in the label
DropDownList1.DataSource = sqlcom.ExecuteReader();
DropDownList1.DataBind();
}
}
}
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
String cs = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
SqlDataReader rd;
using (SqlConnection sc = new SqlConnection(cs))
{
SqlCommand sqlcom = new SqlCommand("Select id, productname, price from productdata where id=" + Convert.ToUInt32(DropDownList1.SelectedValue), sc);
sc.Open();
rd = sqlcom.ExecuteReader();
if (rd.Read())
{
Label1.Text = rd[2].ToString();
}
sc.Close();
}
}
}
Database:
CREATE TABLE [dbo].[productdata] (
[Id] INT NOT NULL,
[productname] VARCHAR (50) NULL,
[price] FLOAT (53) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
);
This Edit according to using AutoPostBack=True and if (!IsPostBack) in Page_Load thanks to Arindam:
For simply solution using postback event:
First you should add OnSelectedIndexChanged event for dropdownlist
<asp:DropDownList ID="DropDownList1" runat="server"
OnSelectedIndexChanged="GetPrice" AutoPostBack="true">
</asp:DropDownList>
Then in code behind you just get selected value and fill to the label price
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Label3.Text = Request.QueryString["name"];//show welcome text
String cs = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using (SqlConnection sc = new SqlConnection(cs))
{
SqlCommand sqlcom = new SqlCommand("Select id, productname, price from productdata", sc);
sc.Open();
DropDownList1.DataTextField = "productname";//show in the dropdown list
DropDownList1.DataValueField = "price"; //show in the label
DropDownList1.DataSource = sqlcom.ExecuteReader();
DropDownList1.DataBind();
}
}
}
protected void GetPrice(object sender, EventArgs e)
{
Label1.Text = DropDownList1.SelectedValue;
}
You have to use AutoPostBack=True so that when you change index of dropdownlist, it will trigger a postback to server so the function GetPrice(...) will be called.
Every time the page postback, it will call function Page_Load(...) first, so you must use propertive IsPostBack to check if case1_this is the first time the page is loaded, or case2_a postback event, and you only set the ddl datasource at case1 because if you set datasource, by default the dropdownlist will reset to select first item in list.
When you go advance, you should consider using Javascript and Jquery to solve this, so the page will not load again like this postback solution.
And one more thing, you should name your controls well, don't make them default like that. It's one of two hard things in programming.
Yes you can but if not please use datatable and i am sure that work fine .if u not able do that just post I will give the correction.
I have a nested repeater on my page like:
Aspx page:
<asp:Repeater ID="parentRepeater" runat="server">
<ItemTemplate>
<br />
<b><%# DataBinder.Eval(Container.DataItem,"question") %></b><br>
<!-- start child repeater -->
<asp:Repeater ID="childRepeater" DataSource='<%# ((DataRowView)Container.DataItem).Row.GetChildRows("relation") %>'
runat="server">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" OnCommand="LinkButton1_Command" CommandName="MyUpdate" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "[\"AnsId\"]")%>'><%# DataBinder.Eval(Container.DataItem, "[\"Ans\"]")%></asp:LinkButton>
<br>
</ItemTemplate>
</asp:Repeater>
<!-- end child repeater -->
</ItemTemplate>
</asp:Repeater>
Code behind:
SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["star_report_con"].ConnectionString);
SqlDataAdapter cmd1 = new SqlDataAdapter("select questionId, question from questions", cnn);
//Create and fill the DataSet.
DataSet ds = new DataSet();
cmd1.Fill(ds, "questions");
//Create a second DataAdapter for the Titles table.
SqlDataAdapter cmd2 = new SqlDataAdapter("SELECT AnsId, Ans, questionId FROM answers", cnn);
cmd2.Fill(ds, "answers");
//Create the relation bewtween the Authors and Titles tables.
ds.Relations.Add("relation",
ds.Tables["questions"].Columns["questionId"],
ds.Tables["answers"].Columns["questionId"]);
//Bind the Authors table to the parent Repeater control, and call DataBind.
parentRepeater.DataSource = ds.Tables["questions"];
Page.DataBind();
//Close the connection.
cnn.Close();
protected void LinkButton1_Command(object sender, CommandEventArgs e)
{
if (e.CommandName == "MyUpdate")
{
//e.CommandArgument --> contain the Ansid value
//I want to also find which questions ans is clicked i.e the questionId
}
}
In my child repeater I have a linkbutton on click of which i need to do some computaion for which I need to know which questions answers wa being clicked. i.e in my LinkButton1_Command I want to fetch the AnsId along with QuestionId.
How will I get parent repeaters Id in button click event?
Try this ,
<%# ((RepeaterItem)Container.Parent.Parent).DataItem %>
If this does not work then try
<%# DataBinder.Eval(Container.Parent.Parent, "DataItem.YourProperty")%>
if you're in code-behind in the ItemDataBound method:
((Repeater)e.Item.NamingContainer.NamingContainer).DataItem
I have two dropdown , the items in the second drop down solely depends on the selected item from the first dropdown. So therefore i want the second dropdows item changes on item selection from the first dropdown. My first drop down is as follows
<td>
<asp:DropDownList ID="DropClient" runat="server" style="margin-left: 0px" AutoPostBack="true" Width="200px" OnTextChanged="DropClient_TextChanged">
</asp:DropDownList> </td>
<td>
I wanted to use onselectedindexchanged previously , but it does not fires as required. Therefore i put my method in the onTextChanged events as below.
protected void DropClient_TextChanged(object sender, EventArgs e)
{
bindDrEmail();
}
and my bindEmail();
connection.Open();
string sql = "SELECT a.clientID,a.cname,c.name FROM [CLIENT] a INNER JOIN [BRANCH] b ON a.clientID=b.clientID JOIN [CONTACT] c ON b.bid=c.bid WHERE a.cname =#clientname";
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#clientname", DropClient.SelectedItem.Text);
SqlDataReader reader = cmd.ExecuteReader();
drEmail.Enabled = true;
drEmail.DataSource = reader;
drEmail.DataTextField = "name";
drEmail.DataValueField = "clientID";
drEmail.DataBind();
reader.Dispose();
reader.Close();
connection.Close();
the above works as expected, but after i select an item in the second dropdown, it does not submit the selected item as chosen . It rather submit the first item in the list by default. Also when i click the submit button, it quickly refresh and submit the first item in the list. I am confused, any help would be appreciated.
Why don't you use onSeletedIndexChanged event, call same function on onSeletedIndexChanged event, may be it will be helpful for you
OnSelectedIndexChanged="cboRegion_SelectedIndexChanged"
Place the code to bind the first dropdown inside the !IsPostBack check
if (!Page.IsPostBack)
{
//Bind your first dropdown here
}
The page load gets triggered everytime a postback happens so to prevent your code loading everytime and resetting your dropdownlists do the following:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
//Put your code in here. This will only load the first time the page loads.
bindDrEmail();
}
}
You can use Update Panel .
This is example code ,
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="true">
<asp:ListItem Value="0">Choose...</asp:ListItem>
<asp:ListItem Value="1">test1</asp:ListItem>
<asp:ListItem Value="2">Test2</asp:ListItem>
</asp:DropDownList>
<asp:DropDownList ID="DropDownList2" runat="server">
</asp:DropDownList>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DropDownList1" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
Guys thank all for your time. I finally figured out the problem. First the reson why it does not fires the events previously was because i set the second Dropdown "AutoPostback" as true, and didn't set the same for the first DropDown which i want to fires. When i reverse this process it fires as below.
<asp:DropDownList ID="DropDownClient" runat="server" style="margin-left: 0px" AutoPostBack="true"
Width="200px" onselectedindexchanged="DropDownClient_SelectedIndexChanged">
</asp:DropDownList>
And
<asp:DropDownList ID="drContact" runat="server" style="margin-left: 0px" Width="200px"> </asp:DropDownList>
Now it fires. Second the very reason why the selecteditem from the second Dropdown changes quickly on button click and submit the first item instead, was because of the dataValueField of the second DropDown. My convine the two tables as follows.
string sql = "SELECT a.clientID,a.cname,c.contactID,c.name FROM [CLIENT] a INNER JOIN [BRANCH] b ON a.clientID=b.clientID JOIN [CONTACT] c ON b.bid=c.bid WHERE a.cname =#clientname";
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#clientname", DropDownClient.SelectedItem.Text);
SqlDataReader reader = cmd.ExecuteReader();
drContact.Enabled = true;
drContact.DataSource = reader;
drContact.DataTextField = "name";
drContact.DataValueField = "clientID";
drContact.DataBind();
Notice the drContact.DataValueField is set as "clientID" . And clientID and the drContact.DataTextField are from different tables. The column i required is "name" and therefore have to change the drContact.DataValueField to the primary key of the table where name is a column. And therefore.
drContact.Enabled = true;
drContact.DataSource = reader;
drContact.DataTextField = "name";
drContact.DataValueField = "contactID";
drContact.DataBind();
The above works fine for me. Thanks for your time.
I am new to ASP.NET, I am making a search box in my application.
For example: if a user enters "abc" in the textbox, then the textbox will fetch data from the database which starts with "abc". I am passing this data to DataTable.
It works properly,
Here is my code snippet:
DataTable result = new DataTable();`
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
connString = System.Configuration.ConfigurationManager.ConnectionStrings["MyConsString"].ConnectionString;
SqlConnection conn = new SqlConnection(connString);
conn.Open();
string query = string.Format("SELECT DISTINCT Scrip FROM dbo.SearchBoxData where Scrip Like '{0}%'", TextBox1.Text);
SqlCommand cmd = new SqlCommand(query, conn);
result.Load(cmd.ExecuteReader());
conn.Close();
}
Now I want to retrieve all this data in my <div> tag. How should I retrieve and display?
Any help will be appreciated.
You should use a databound control like a ListView or GridView. I'd recommend creating a separate control to hold one row in the list and using the RowDataBound method to assign the row data. Example of using ListView's ItemDatabound event - http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.itemdatabound.aspx
On a side note your code is vulnerable to SQL Injection
You could probably better use a databound control, like the ListView (or the GridView) control. This way you can create nice layouts you want with the data in the datatable.
For instance, a ListView could be used:
<asp:ListView ID="lvwItems" runat="server" ItemPlaceholderID="plhItems">
<LayoutTemplate>
<div>
<asp:PlaceHolder ID="plhItems" runat="server"></asp:PlaceHolder>
</div>
</LayoutTemplate>
<ItemTemplate>
<div>
<%# Eval("ColumnFromDataTable")%>
</div>
</ItemTemplate>
</asp:ListView>
In your code behind you can then do:
lvwItems.DataSource = result;
lvwItems.DataBind();
Remark: code is just out of my head, could contain some errors