2 Dropdownlists for a Year Range - c#

I am stuck at a problem where i really didn't expect to get held up so many hours and it's driving me nuts
As mentioned in the title i need two DropDownLists where the ToYears List has values starting with the selection of FromYear:
FromYear
2000
2001
2002
2003
2004
ToYear
2002
2003
2004
So i tried to use 2 <asp:dropdownlist> and change the selected ToYear during the SelectedIndexEvent of FromYear but this was triggering the selected FromYear event and somehow it wouldn't fire again.
Now i found the CascadingDropDown from the Ajax Control Toolkit and thought this might be a good thing. But i don't want to call a web service, instead i would like to use a Method in the code behind the actual page.
Also the selection should be remembered after a postback - and the range of years changes depending on properties in the Code behind.
I read somewhere that autopostback does not work with the CascadingDropDown.
What would you think would be the most elegant and easy solution?
Thank you very much in advance.
EDIT: i am going to post a few parts of my post - hope that helps
Markup:
<asp:DropDownList AutoPostBack="True" ID="DropDownFromYear" runat="server" OnSelectedIndexChanged="FromYearChanged" />
<asp:Label ID="UntilLabel" runat="server" Text=" until " />
<asp:UpdatePanel ID="ToYearUpdatePanel" runat="server" style="display: inline-block;">
<ContentTemplate>
<asp:DropDownList AutoPostBack="true" ID="DropDownToYear" runat="server" OnSelectedIndexChanged="ToYearChanged" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="DropDownFromYear" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
CodeBehind (called from OnInit):
private void InitializeDropDownYears()
{
//Calculate the YearMin YearMax Properties
CalculateYearMinMax();
int adaptedFromYear = 0, adaptedToYear = 0;
//get the previously selected Years
if (DropDownToYear.SelectedItem != null) adaptedToYear = int.Parse(DropDownToYear.SelectedValue);
if (DropDownFromYear.SelectedItem != null) adaptedFromYear = int.Parse(DropDownFromYear.SelectedValue);
//check the minimum year constraints 2005 was selected but minYear is 2010 -> adpated is set to 2010
if (YearMin > adaptedFromYear || adaptedFromYear == 0) adaptedFromYear = YearMin;
if (YearMax < adaptedToYear || adaptedToYear == 0) adaptedToYear = YearMax;
//check the 5 year range constraint
if ((YearMax - YearMin) > 5)
{
adaptedFromYear = DateTime.Now.Year - 2;
adaptedToYear = DateTime.Now.Year + 2;
}
Dictionary<string, string> toYears = new Dictionary<string, string>();
Dictionary<string, string> fromYears = new Dictionary<string, string>();
for (int tempYear = YearMin; tempYear <= YearMax; tempYear++)
{
fromYears.Add(tempYear.ToString(), tempYear.ToString());
if (tempYear >= adaptedFromYear)
{
toYears.Add(tempYear.ToString(), tempYear.ToString());
}
}
DropDownFromYear.DataSource = fromYears;
DropDownFromYear.DataValueField = "Key";
DropDownFromYear.DataTextField = "Value";
DropDownFromYear.SelectedValue = adaptedFromYear.ToString();
DropDownFromYear.DataBind();
DropDownToYear.DataSource = toYears;
DropDownToYear.DataValueField = "Key";
DropDownToYear.DataTextField = "Value";
DropDownToYear.SelectedValue = adaptedToYear.ToString();
DropDownToYear.DataBind();
if(!IsPostBack)
{
SelectedFromYear = adaptedFromYear;
SelectedToYear = adaptedToYear;
}
}
private void CalculateYearMinMax()
{
IList<Task> taskList = CurrentLicense.TaskList;
List<DateTime> startDates = taskList.Select(task => task.StartDate).ToList();
YearMin = startDates.Min(date => date).Year;
List<DateTime> endDates = taskList.Select(task => task.EndDate).ToList();
YearMax = endDates.Max(date => date).Year;
}
EventHandler:
protected void FromYearChanged(object sender, EventArgs e)
{
SelectedFromYear = int.Parse(DropDownToYear.SelectedValue);
SelectedToYear = int.Parse(DropDownFromYear.SelectedValue);
if (SelectedFromYear > SelectedToYear)
{
SelectedToYear = SelectedFromYear;
}
UpdateGanttTables();
}
protected void ToYearChanged(object sender, EventArgs e)
{
SelectedFromYear = int.Parse(DropDownToYear.SelectedValue);
SelectedToYear = int.Parse(DropDownFromYear.SelectedValue);
UpdateGanttTables();
}

Filling DropDownList controls might sound easy right? and it is, when you use the default behavior of ASP.NET WebForms. However you could face several problems when you want to get specific functionality, for example, in WebForms, trying to fill DropDownLists using AJAX (this is a real pain, and the only solution I have found is to disable the security check on the page <%# Page EnableEventValidation="false")
For reference:
How to fill an asp:DropDown client side?
Since you are using WebForms probably the best way is to use the gross UpdatePanel
Example:
Result
ASPX markup
<asp:ScriptManager runat="server" ID="sm" />
<asp:UpdateProgress runat="server" AssociatedUpdatePanelID="updatePanel" DisplayAfter="0" DynamicLayout="true">
<ProgressTemplate>
Working...
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel runat="server" ID="updatePanel">
<ContentTemplate>
<div>
<asp:Label ID="Label1" Text="From" runat="server" AssociatedControlID="from" />
</div>
<div>
<asp:DropDownList runat="server" ID="from" AutoPostBack="true" CausesValidation="false" OnSelectedIndexChanged="from_SelectedIndexChanged">
</asp:DropDownList>
</div>
<div>
<asp:Label ID="Label2" Text="To" runat="server" AssociatedControlID="to" />
</div>
<div>
<asp:DropDownList runat="server" ID="to" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
Page code behind
private const int MaxYear = 2030;
private const int MinYear = 1959;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
var fromRange = Enumerable.Range(MinYear, MaxYear - MinYear);
this.from.DataSource = fromRange;
this.from.DataBind();
}
}
protected void from_SelectedIndexChanged(object sender, EventArgs e)
{
var selectedYear = Convert.ToInt32(this.from.SelectedValue);
var toRange = Enumerable.Range(selectedYear, MaxYear - selectedYear);
this.to.DataSource = toRange;
this.to.DataBind();
}
I just uploaded this sample to my GitHub for reference

In the end I figured it out and got - as I think a nice solution because it enables me to:
initially fill both DDLs with data
preselect items in both DDLs
still use EnableEventValidation="true" on the Page
i can update the DDLs by simply calling DataBind(); on them
The main difference to my previous approaches is, that I fill the DDLs with data during their OnDataBinding event. So it will happen automatically when i execute DataBind() during PageLoad. Only thing i have to make sure first is to fill the dictionaries that contain my information.
If I want to update ToYearsDDL from the selectionChangeEvent of FromYearsDDL I simply update the Data for ToYearsDDL and call ToYearsDDL.DataBind();
Hope this helps someone else that runs into the same wall!
Here comes the markup:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="LinkedDropDownsBound.aspx.cs"
Inherits="ASP.Net_Spielwiese.LinkedDropDownsBound" EnableEventValidation="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div>
<asp:UpdatePanel runat="server" ID="updatePanel">
<ContentTemplate>
<div>
<asp:Label ID="FromLabel" Text="From" Enabled="false" runat="server" />
</div>
<div>
<asp:DropDownList runat="server" ID="FromYearsDDL" AutoPostBack="true" CausesValidation="false" OnDataBinding="DDLFromDataBind"
OnSelectedIndexChanged="DDLFromSelectedIndexChanged">
</asp:DropDownList>
</div>
<div>
<asp:Label ID="ToLabel" Text="To" Enabled="false" runat="server" />
</div>
<div>
<asp:DropDownList runat="server" ID="ToYearsDDL" AutoPostBack="true" CausesValidation="false" OnDataBinding="DDLToDataBind"
OnSelectedIndexChanged="DDLToSelectedIndexChanged"/>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
And here comes the code behind:
public partial class LinkedDropDownsBound : System.Web.UI.Page
{
public Dictionary<String, Boolean> FromYears
{
get
{
if (ViewState["FromYears"] == null)
{
ViewState["FromYears"] = new Dictionary<String, Boolean>();
}
return ViewState["FromYears"] as Dictionary<String, Boolean>;
}
set
{
ViewState["FromYears"] = value;
}
}
public Dictionary<String, Boolean> ToYears
{
get
{
if (ViewState["ToYears"] == null)
{
ViewState["ToYears"] = new Dictionary<String, Boolean>();
}
return ViewState["ToYears"] as Dictionary<String, Boolean>;
}
set
{
ViewState["ToYears"] = value;
}
}
public int MinYear = 1975;
public int MaxYear = 2015;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
InitFromYears();
InitToYears();
DataBind();
}
}
private void InitFromYears()
{
FromYears = new Dictionary<string, bool>();
IEnumerable<int> fromRange = Enumerable.Range(MinYear, MaxYear - MinYear);
foreach (var fromYear in fromRange)
{
FromYears.Add(fromYear.ToString(), fromYear == (DateTime.Now.Year - 2));
}
}
private void InitToYears()
{
ToYears = new Dictionary<string, bool>();
//get the selected FromYear Value
int minToYear = Convert.ToInt32(FromYears.FirstOrDefault(dict => dict.Value).Key);
//make sure ToYears is at least FromYears
if (minToYear < Convert.ToInt32(FromYears.Min(k => k.Key)))
{
minToYear = Convert.ToInt32(FromYears.Min(k => k.Key));
}
IEnumerable<int> toRange = Enumerable.Range(minToYear, MaxYear - minToYear);
foreach (var toYear in toRange)
{
ToYears.Add(toYear.ToString(), toYear == (DateTime.Now.Year + 2));
}
}
protected void DDLFromDataBind(object sender, EventArgs e)
{
FromYearsDDL.DataSource = FromYears;
FromYearsDDL.DataValueField = "Key";
FromYearsDDL.DataTextField = "Key";
FromYearsDDL.SelectedValue = FromYears.FirstOrDefault(y => y.Value).Key;
}
protected void DDLFromSelectedIndexChanged(object sender, EventArgs e)
{
//update the FromYear Dictionary
var tempDictionary = FromYears.ToDictionary(fromYear => fromYear.Key, fromYear => fromYear.Key.Equals(FromYearsDDL.SelectedValue));
FromYears = tempDictionary;
//Call Bind on the ToYear DDL
ToYearsDDL.DataBind();
//do my other update stuff here
FromLabel.Text = FromYearsDDL.SelectedValue;
ToLabel.Text = ToYearsDDL.SelectedValue;
}
protected void DDLToSelectedIndexChanged(object sender, EventArgs e)
{
//do my other update stuff here
FromLabel.Text = FromYearsDDL.SelectedValue;
ToLabel.Text = ToYearsDDL.SelectedValue;
}
protected void DDLToDataBind(object sender, EventArgs e)
{
InitToYears();
ToYearsDDL.DataSource = ToYears;
ToYearsDDL.DataValueField = "Key";
ToYearsDDL.DataTextField = "Key";
ToYearsDDL.SelectedValue = ToYears.FirstOrDefault(y => y.Value).Key;
}
}

This is The HTML page
In the code behind c# page
private void BindYearDropdown()
{
int year;
for (year = DateTime.Now.Year; year >= 2010 ; year--)
{
DDLYear.Items.Add(year.ToString());
}
}
The above code is for Years Back ward

Related

asp.net web page, getting jQuery Accordion plugin to work with asp:Repeater control

I'm working on a asp.net project. I've been asked to create a page so site admins could add articles and everyone else could add comments under those articles.
I have 2 separate tables in my db, Articles/Comments. On page load I'm populating all the articles with their own related comments within a panel.
I've also been asked to use an accordion so all comments would display in a collapsible manner!
My problem is that only the first article shows up with collapsible comments under it, and the rest do not!
Here is my aspx page:
<%# Page Title="Ref Notes" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="RefNotes.aspx.cs" Inherits="Root.RefNotes" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:Panel ID="refNotes" CssClass="col-xs-12 data-container" runat="server">
</asp:Panel>
</asp:Content>
aspx.cs code:
public partial class RefNotes : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
populateNotes();
Page.Title = "Latest Ref Notes";
}
protected void populateNotes()
{
string tag = "";
if (Request.QueryString["tag"] != null) tag = Request.QueryString["tag"];
int post = 0;
if (Request.QueryString["post"] != null) post = Int32.Parse(Request.QueryString["post"]);
MediaService.Article[] articles = Global.mediaService.GetArticles(1, 1); //gets all articles
for (int i = 0; i < articles.Length; i++)
{
if (post > 0 && articles[i].ID != post) continue;
Root.Controls.Blog.RefNotesPost p = (Root.Controls.Blog.RefNotesPost)LoadControl("~/Controls/Blog/RefNotesPost.ascx");
p.SetData(articles[i]);
refNotes.Controls.Add(p);
Root.Controls.Blog.CommentControl c = (Root.Controls.Blog.CommentControl)LoadControl("~/Controls/Blog/CommentControl.ascx");
c.SetData(articles[i].ID);
refNotes.Controls.Add(c);
}
if (articles.Length == 0)
{
Literal l = new Literal();
l.Text = "<h1>No content currently available.</h1>";
refNotes.Controls.Add(l);
}
}
}
CommentControl.ascx code:
# Control Language="C#" AutoEventWireup="true" CodeBehind="CommentControl.ascx.cs" Inherits="Root.Controls.Blog.CommentControl" %>
<div class="row">
Comments:
<asp:Panel ID="errorPanelID" runat="server" CssClass="loginbox-textbox" Visible="false" Style="margin-top: 20px;">
<div class="alert alert-danger fade in">
<button class="close" data-dismiss="alert">
×
</button>
<i class="fa-fw fa fa-times"></i>
<asp:Label ID="errorMsgID" runat="server"></asp:Label>
</div>
</asp:Panel>
</div>
<div id="dvAccordion" style="width: auto">
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<h3>
<asp:Label ID="Label1" runat="server" Text='<%#Eval("user") + " at " + Eval("dateTime") + " says:"%>'></asp:Label></h3>
<div style="background-color: #CFDEE3">
<asp:Literal ID="lit" runat="server" Text='<%#Eval("comment")%>' Mode="Transform" />
</div>
</ItemTemplate>
</asp:Repeater>
</div>
<div>
Add a Comment:<br />
<asp:TextBox ID="txtComment" runat="server" Rows="5" TextMode="MultiLine"></asp:TextBox>
<br />
<asp:Button ID="Button1" runat="server" OnClick="saveBtn_Click" Text="Submit " />
<asp:HiddenField runat="server" ID="articleID" Value="0" />
</div>
<script type="text/javascript">
$(function () {
$("#dvAccordion").accordion();
});
</script>
CommentControl.ascx.cs code:
public partial class CommentControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void SetData(int artID)
{
Services.Comment[] comments = Global.Tools.GetComments(artID);
articleID.Value = artID.ToString();
if (comments.Length > 0)
{
Repeater1.Visible = true;
Repeater1.DataSource = comments;
Repeater1.DataBind();
}
else
{
Repeater1.Visible = false;
}
}
protected void saveBtn_Click(object src, EventArgs e)
{
AdminService.Employee emp = Global.Tools.GetEmployee(Int32.Parse(Session["eid"].ToString()));
Blog.Comment a = new Blog.Comment();
a.CommentOn = txtComment.Text;
a.CreatedBy = emp.username;
a.DatePosted = DateTime.Now;
a.isVisible = 1;
a.ArticleID = int.Parse(articleID.Value);
if (Request.QueryString["post"] != null)
{
a.ID = Int32.Parse(Request.QueryString["post"]);
}
int result = Global.Tools.CreateComment(a);
if (result <= 0)
{
errorMsgID.Text = "Failed to create comment.";
errorPanelID.Visible = true;
}
else
{
Response.Redirect("/News.aspx");
}
}
txtComment.Text = string.Empty;
}
In the CommentControl.ascx file I had set the accordion based on id (#dvAccordion). I changed it to be based on class (.dvAccordion) and that solved the issue.
So for future references: when you're on a page an "id" can only be called once but a "class" can be called multiple times!

textbox value inside a repeater and save

I have a code here that gets a transaction number on a search bar and show it on the page. I also have 2 textbox wherein the client will enter the price payed and the OR No of the receipt. However, I am getting an error
"Object reference not set to an instance..."
.ASPX
<form id="form1" runat="server">
<div>
<asp:Repeater ID="rptrCashierTable" runat="server">
<ItemTemplate>
<div>
<h1 align="center">Transaction Number: <label><%# Eval("TXNNo") %></label>
<h2>Name:<label><%# Eval("FName") %></label>
<label><%# Eval("MName") %></label>
<label><%# Eval("LName") %></label></h2>
<h2>Contact Number: <label><%# Eval("MOBILE") %></label></h2>
<h2>Product Ordered: <label><%# Eval("PName") %></label></h2>
<h2>Product ID:<label><%# Eval("ProductID") %></label></h2>
<h2>Price:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox></h2>
<h2>OR No.:
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox></h2>
<asp:Button ID="Button1" runat="server" Text="Submit" OnClick="btn_Update" />
</div>
</ItemTemplate>
</asp:Repeater>
</div>
</form>
.CS
public partial class TransactionDetails : System.Web.UI.Page
{
SQLQuery sql = new SQLQuery();
DataSet ds = new DataSet();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindCasierTable();
}
}
private void BindCasierTable()
{
string TransctID = Request.QueryString["TXNNo"];
ds = sql.dsGetClientDetails(TransctID);
rptrCashierTable.DataSource = ds;
rptrCashierTable.DataBind();
}
protected void btn_Update(object sender, EventArgs e)
{
foreach (RepeaterItem item in rptrCashierTable.Items)
{
if (item.ItemType == ListItemType.Item)
{
var txtPrice = item.FindControl("TextBox1") as TextBox;
var txtORNo = item.FindControl("TextBox2") as TextBox;
string TXNNo = Request.QueryString["TXNNo"];
ds = sql.dsAddPayment(txtPrice.Text, txtORNo.Text, TXNNo);
txtPrice.Text = string.Empty;
txtORNo.Text = string.Empty;
BindCasierTable();
}
}
}
}
I am using MSSQL 2008 and stored procedure. I just want to update and put the Price payed and OR number to their respective field.
That error message means you are assigning something with null value. I guess the error pops out here:
string TransctID = Request.QueryString["TXNNo"]
you should check if its null first:
if(Request.QueryString["TXNNo"]!=null)
{
// make the assignation here
}

ASP.NET - SelectedValue/Index in Listbox always changing after a postback

I've been wrestling with this problem for days and so far I haven't been able to find an answer that fits this specific issue. Here's the code to load the list in the PageLoad():
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
lstEmprendimientos.DataSource = Emprendimiento.DevolverEmprendimientosConEvaluacionesIncompletas();
lstEmprendimientos.DataValueField = "id";
lstEmprendimientos.DataTextField = "titulo";
lstEmprendimientos.DataBind();
pnlEvaluador.Visible = false;
}
}
The first method loads a list made up of 'Emprendimiento' objects, and on that list's SelectedIndexChanged I call another method to load a list through a method that uses the SelectedValue of the item selected.
My problem is that, no matter what I do, the SelectedIndex is always reset to 0 after a postback, so I can't load the second list using the SelectedValue properly. I've worked with lists for a long while now and I've never had this problem, so it's really baffling. I'd appreciate some help with this.
Here's the code for the whole page:
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
ddlEmprendimientos.DataSource = Emprendimiento.DevolverEmprendimientosConEvaluacionesIncompletas();
ddlEmprendimientos.DataValueField = "id";
ddlEmprendimientos.DataTextField = "titulo";
ddlEmprendimientos.DataBind();
pnlEvaluador.Visible = false;
}
}
protected void lstEmprendimientos_SelectedIndexChanged(object sender, EventArgs e)
{
}
protected void lstEvaluadores_SelectedIndexChanged(object sender, EventArgs e)
{
Evaluador ev = Evaluador.FindByID(lstEvaluadores.SelectedValue);
}
protected void btnAsignarEvaluador_Click(object sender, EventArgs e)
{
Emprendimiento emp = Emprendimiento.FindByID(Convert.ToInt32(ddlEmprendimientos.SelectedValue));
Evaluador ev = Evaluador.FindByID(lstEvaluadores.SelectedValue);
Evaluacion eva = new Evaluacion(emp, ev, 0, "justificacion", DateTime.Now, false);
if (eva != null)
{
if (eva.Insertar())
{
lblFeedback.Text = "Alta exitosa.";
emp.listaEvaluaciones.Add(eva);
lstEvaluadores.DataSource = emp.DevolverListaEvaluadoresQueNoEvaluanEmprendimiento();
lstEvaluadores.DataTextField = "Nombre";
lstEvaluadores.DataValueField = "Email";
lstEvaluadores.DataBind();
pnlEvaluador.Visible = true;
CargarEvaluadores();
}
else
{
lblFeedback.Text = "Error en el ingreso de datos.";
}
}
else
{
lblFeedback.Text = "Error en el ingreso de datos.";
}
}
protected void btnSeleccionarEmp_Click(object sender, EventArgs e)
{
CargarEvaluadores();
}
private void CargarEvaluadores()
{
Emprendimiento emp = Emprendimiento.FindByID(Convert.ToInt32(ddlEmprendimientos.SelectedIndex));
lstEvaluadores.DataSource = emp.DevolverListaEvaluadoresQueNoEvaluanEmprendimiento();
lstEvaluadores.DataTextField = "Nombre";
lstEvaluadores.DataValueField = "Email";
lstEvaluadores.DataBind();
pnlEvaluador.Visible = true;
}
protected void ddlEmprendimientos_SelectedIndexChanged(object sender, EventArgs e)
{
CargarEvaluadores();
}
Page markup:
<%Page Title="" Language="C#" MasterPageFile="~/masterPage.Master" AutoEventWireup="true" CodeBehind="asignarEvaluador.aspx.cs" Inherits="InterfazUsuario.asignarEvaluador">
<asp:DropDownList ID="ddlEmprendimientos" runat="server" OnSelectedIndexChanged="ddlEmprendimientos_SelectedIndexChanged">
</asp:DropDownList>
<br />
<br />
<asp:Button ID="btnSeleccionarEmp" runat="server" OnClick="btnSeleccionarEmp_Click" Text="Seleccionar emprendimiento" Width="195px" />
<br />
<br />
<asp:Panel ID="pnlEvaluador" runat="server">
<asp:ListBox ID="lstEvaluadores" runat="server" OnSelectedIndexChanged="lstEvaluadores_SelectedIndexChanged"></asp:ListBox>
<br />
<br />
<asp:Button ID="btnAsignarEvaluador" runat="server" OnClick="btnAsignarEvaluador_Click" Text="Asignar evaluador" Width="135px" />
<br />
<br />
<asp:Label ID="lblFeedback" runat="server"></asp:Label>
<br />
</asp:Panel>
You need to change your DropDownList and ListBox controls to AutoPostback
DropDownList
<asp:DropDownList ID="ddlEmprendimientos" runat="server"
OnSelectedIndexChanged="ddlEmprendimientos_SelectedIndexChanged"
AutoPostBack="True">
</asp:DropDownList>
ListBox
<asp:ListBox ID="lstEvaluadores" runat="server"
OnSelectedIndexChanged="lstEvaluadores_SelectedIndexChanged"
AutoPostBack="True">
</asp:ListBox>
AutoPostBack:
Set this property to true if the server needs to capture the selection
as soon as it is made. For example, other controls on the Web page can
be automatically filled depending on the user's selection from a list
control.
This property can be used to allow automatic population of other controls on > the Web page based on a user's selection from a list.
The value of this property is stored in view state.
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.autopostback(v=vs.110).aspx
I found the problem after checking everything out again.
The DataValueField in the list was 'id', and the id field in the 'Emprendimiento' class wasn't defined, so it was always returning a null int (0). Thank you kindly for the help, it was just a dumb mistake in the end.

Set checkbox as checked in Repeater/CheckboxList

I'm using a Repeater to show some data coming from a web service.
My Repeater structure is:
<asp:Repeater ID="rptgrp" runat="server">
<ItemTemplate>
<asp:CheckBoxList ID="chkBoxListGoup" runat="server"
DataSource='<%# DataBinder.Eval(Container.DataItem, "Titles")%>'
DataTextField="Title"
DataValueField="IDTitle">
</asp:CheckBoxList>
</ItemTemplate>
</asp:Repeater>
Now, my web service returns these fields in "Titles":
1) Title
2) IDTitle
3) isUserTitle
Now, I would like to set checked a checkbox when isUserTitle is = 1.
How can I do that?
You can find checkboxlist as follows
Find checkboxlist in itemdatabound,
check item text of every checkboxlist using loop,
select the item whose text is 1
Protected void Repeater_ItemDataBound(Object Sender, RepeaterItemEventArgs e) {
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
CheckBoxList chklst = (CheckBoxList)e.Item.FindControl("chkBoxListGoup");
for (int i = 0; i < chk.Items.Count; i++)
{
if (chk.Items[i].Text == "1")
{
chk.Items[i].Selected = true;
}
}
}
}
Try changing <asp:CheckBoxList ID="chkBoxListGoup" runat="server"
to
<asp:CheckBoxList ID="chkBoxListGoup" Checked='<%#Eval("Flag")%>' runat="server"
Flag being your Column..
Then in your method or event handler you want to run some code to say if this value = 1 checked, elseif value = 0 unchecked...
Here is sample code that demonstrates the idea:
Code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using WebApp.RepeaterCheckboxList.TODODatasetTableAdapters;
namespace WebApp.RepeaterCheckboxList
{
public partial class WebForm1 : System.Web.UI.Page
{
IEnumerable<TODODataset.TasksViewRow> view;
IEnumerable<TODODataset.TasksViewRow> subview;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TasksViewTableAdapter adp = new TasksViewTableAdapter();
var dt = adp.GetData();
view = dt.AsEnumerable();
var names = (from x in view
select new
{
Person = x.Name,
ID = x.PersonID
}).Distinct();
DataList1.DataSource = names;
DataList1.DataBind();
}
}
protected void CheckBoxList1_DataBound(object sender, EventArgs e)
{
CheckBoxList theList = (CheckBoxList)sender;
var person = ((DataListItem)theList.Parent).DataItem as dynamic;
var name = person.Person;
var id = person.ID;
var vw = subview;
for (int i = 0, j = vw.Count(); i < j; i++)
{
var task = vw.ElementAt(i);
theList.Items[i].Selected = task.Completed;
}
}
protected IEnumerable<TODODataset.TasksViewRow> GetTasks(object data)
{
var vw = data as dynamic;
return subview = (from x in view
where x.PersonID == vw.ID
select x);
}
}
}
Aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApp.RepeaterCheckboxList.WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DataList ID="DataList1" runat="server">
<ItemTemplate>
<div style="padding:5px">
<h3><%# Eval("Person") %></h3>
<div>
<asp:CheckBoxList OnDataBound="CheckBoxList1_DataBound" ID="CheckBoxList1"
runat="server"
DataTextField="TaskDesc" DataValueField="TaskID"
DataSource="<%# GetTasks(Container.DataItem) %>"></asp:CheckBoxList>
</div>
</div>
</ItemTemplate>
</asp:DataList>
</div>
</form>
</body>
</html>
If you are interested in the data, click here
Try just setting the Checked value to the object being Evaled.
<asp:Repeater ID="rptgrp" runat="server">
<ItemTemplate>
<asp:CheckBoxList ID="chkBoxListGoup" runat="server"
Checked=<%# Eval("isUserTitle") %>>
</asp:CheckBoxList>
</ItemTemplate>
</asp:Repeater>

Checkboxlist inside a usercontrol going as null when control passed from an aspx page

Have landed into a scenario again. The summary is as follows:
I have a user-control which is basically a mix up of a textbox,imagebuttons,checkboxlist incorporated together to look like a single-select dropdown with checkboxes..works pretty fine. One of the images inside the usercontrol opens up an aspx page as a popup.have few functionalities there viz saving values to database and stuffs.
On the OK button click of the popup page, I should be able to save the values to the DB as well as populate the usercontrol(which acts as a dropdown) with the value which I have saved to the DB.
Here the problem arises, when trying to bind the checkboxlist(present in the usercontrol) to the values from the DB, I get the error that the checkboxlist object is null and has not been created.
I feel that on the OK button click, the usercontrol has to refresh and hence the checkboxlist will be active.
PFB the relevant codes:
Usercontrol.ascx:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="SingleSelectCustomDropDown.ascx.cs" Inherits="MS.IT.Informa.UI.UserControls.SingleSelectCustomDropDown" %>
<asp:Panel ID="panel" runat="server">
<div id="FirstDiv">
<table>
<tr>
<td align="right">
<asp:TextBox ID="txtSelect" runat="server" ReadOnly="true"></asp:TextBox>
</td>
<td>
<asp:Image ID="imgShow" ImageUrl="../Images/DDGlyph.png" onmouseover="this.src='../Images/DDGlyphHOVER.png'" onmouseout="this.src='../Images/DDGlyph.png'" runat="server" />
</td>
</tr>
<tr>
<td colspan="2">
<div id="SecondDiv" style="display:none;">
<asp:CheckBoxList ID="chkBoxList" runat="server">
<asp:ListItem Value="0" Text="Standard" Selected="True"></asp:ListItem>
</asp:CheckBoxList>
</div>
<div id="ThirdDiv" style="display:none;">
<asp:ImageButton ID="btnNew" runat="server" Height="20px" ImageUrl="~/Images/new.png" Width="20px" OnClientClick="ShowPopup();" />
<asp:ImageButton ID="btnEdit" runat="server" Height="20px" ImageUrl="~/Images/edit.png" Width="20px" />
<asp:ImageButton ID="btnDefault" runat="server" Height="20px" ImageUrl="~/Images/default.png" Width="20px" />
<asp:ImageButton ID="btnDelete" runat="server" Height="20px" ImageUrl="~/Images/delete.png" Width="20px" />
</div>
</td>
</tr>
</table>
</div>
</asp:Panel>
<script type="text/javascript">
//Displays the divs containing checkboxlist and images
function ShowList() {
document.getElementById("SecondDiv").style.display = "block";
document.getElementById("ThirdDiv").style.display = "block";
}
//Hides the divs containing checkboxlist and images
function HideList() {
document.getElementById("SecondDiv").style.display = "none";
document.getElementById("ThirdDiv").style.display = "none";
}
//Displays the selected item from the checkboxlist into the textbox placed in the Custom Control
function DisplaySelectedItem(sender, txtBoxID) {
var x = document.getElementById(sender.id);
var chkBoxPrefix = sender.id + "_";
var selectedText;
for (i = 0; i < x.rows.length; i++) {
if(document.getElementById(chkBoxPrefix+i).checked)
{
selectedText = document.getElementById(chkBoxPrefix+i).parentNode.innerText;
}
}
document.getElementById(txtBoxID.id).value = selectedText;
}
//Ensures that only one item is selected from the checkboxlist
function SelectOnlyOneCheckBox(e) {
if (!e) e = window.event;
var sender = e.target || e.srcElement;
if (sender.nodeName != 'INPUT') {
return;
}
var checker = sender;
var chkBox = document.getElementById('<%= chkBoxList.ClientID %>');
var chks = chkBox.getElementsByTagName('INPUT');
for (i = 0; i < chks.length; i++) {
if (chks[i] != checker)
chks[i].checked = false;
}
}
function ShowPopup() {
window.open("ViewColumnOptions.aspx", "ViewColumnOptions", "height=300,width=600,left=300,top=150");
}
</script>
The codebehind for the usercontrol as below:
public partial class SingleSelectCustomDropDown : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
chkBoxList.Attributes.Add("onclick", "SelectOnlyOneCheckBox(event);DisplaySelectedItem(this," + txtSelect.ClientID + ");HideList();");
txtSelect.Attributes.Add("onclick", "ShowList();");
imgShow.Attributes.Add("onclick", "ShowList();");
}
}
public void PopulateOtherViews()
{
SaveReportViewFilter<ReportFilterBase> newObj = new SaveReportViewFilter<ReportFilterBase>();
ViewColumnOptions vwobj = new ViewColumnOptions();
newObj.UserName = vwobj.Page.User.Identity.Name;
SaveReportView<ReportFilterBase> obj2 = new SaveReportView<ReportFilterBase>();
DataTable dt = obj2.GetSaveReportViewFromDataBase(newObj);
chkBoxList.DataSource = dt;//chkBoxList becomes null here..we have ample data in the datatable though
chkBoxList.DataTextField = dt.Columns[0].ToString();
chkBoxList.DataValueField = dt.Columns[0].ToString();
chkBoxList.DataBind();
}
}
The function PopulateOtherViews is called on the button click of the aspx page.
Below is the code:
protected void btnOK_Click(object sender, EventArgs e)
{
if (chkSaveView.Checked)
{
if (!string.IsNullOrEmpty(txtViewName.Text))
{
//some code here to save the view name from txtViewName to the DB
SingleSelectCustomDropDown obj22 = new SingleSelectCustomDropDown();
obj22.PopulateOtherViews();
Page.ClientScript.RegisterStartupScript(this.GetType(),"close","CloseWindow();",true);
}
else
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "alertEnterViewName", "alertMessage('Please enter the view name');", true);
}
}
}
Any help, suggestions, pointers will be greatly appreciated.
Regards
Anurag
In btnOK_Click you are creating a new instance of the user control and not attaching it to the page. My suggestion is:
1.Register the user control and add it to the page.
<%# Register Src="~/UserControl/SingleSelectCustomDropDown.ascx" TagPrefix="uc1" TagName="SingleSelectCustomDropDown" %>
and ...
<uc1:SingleSelectCustomDropDown runat="server" id="obj22" />
2.Now modify in code behind:
protected void btnOK_Click(object sender, EventArgs e)
{
if (chkSaveView.Checked)
{
if (!string.IsNullOrEmpty(txtViewName.Text))
{
//some code here to save the view name from txtViewName to the DB
//Do not create the control again
//SingleSelectCustomDropDown obj22 = new SingleSelectCustomDropDown();
obj22.PopulateOtherViews();
Page.ClientScript.RegisterStartupScript(this.GetType(), "close", "CloseWindow();", true);
}
else
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "alertEnterViewName", "alertMessage('Please enter the view name');", true);
}
}
}

Categories