Implementing a pager for asp.net's DataList/Repeater - asp.net

I have a DataList showing the results, and a Repeater that is supposed to be the pager.
I decided to use the page number by redirecting with a QueryString parameter, so it will also be bookmarkable ... My problem is mainly in the UI actually.
If I put DIV's with their onclick calling a JS function that does window.location = url + pagenumber , then somehow I have to deal with QueryString operations via JS which is a bit messy.
If I use LinkButton objects within the ItemTemplate, then the Redirecting happens only when the linkbutton is clicked while whole div has cursor: pointer , you know what I mean.
What would be the best approach to this? Thanks in advance.
Note: I really want to spend the time and effort implementing my own server-side paging.
I think its more fun than reading 3rd party manuals.

Markup:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="SoruListe.ascx.cs" Inherits="SoruListe" %>
<%# Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<%# Register src="EtiketControl.ascx" tagname="EtiketControl" tagprefix="uc1" %>
<script type="text/javascript">
$(document).ready(function() {
if ($('.pageritem')) {
$('#pageritem-' + get_pagenumber()).addClass("pagerselected");
}
});
function soruyuac(id) {
var url = "SoruDetay.aspx?sid=" + id;
window.location = url;
}
function get_QueryString(fieldname) {
var qstr = window.location.search.substring(1);
var pairs = qstr.split('&');
for (i = 0; i < pairs.length; i++) {
var keyval = pairs[i].split('=');
if (keyval[0] && keyval[0] == fieldname) {
return keyval[1];
}
}
}
function set_QueryString(fieldname, value) {
var rawurl = window.location.href;
if (rawurl.indexOf('?') > -1) { rawurl = window.location.href.split('?')[0]; }
var qstr = window.location.search.substring(1);
var pairs = qstr.split('&');
var foundit = false;
for (i = 0; i < pairs.length; i++) {
if (i == 0 && rawurl.indexOf('?') == -1) { rawurl += '?' }; ///Buraya kadar saglam görünüyo
var curpair = pairs[i].split('=');
if (curpair[0] == fieldname) { /// paramname'i al ama deger için yeni geleni koy
foundit = true;
rawurl += curpair[0] + '=' + value;
if (i != pairs.length - 1) { rawurl += '&' }
}
else { ///aynen geri doldur
rawurl += curpair[0] + '=' + curpair[1];
if (i != pairs.length - 1) { rawurl += '&' }
}
}
if (!foundit) { rawurl += '&' + fieldname + '=' + value; }
///
return rawurl;
}
function changepage(pagenum) {
window.location = set_QueryString('pg', pagenum);
}
function get_pagenumber() {
var pgn = get_QueryString('pg');
if (pgn == null) return 1;
return pgn;
}
function skipfrom(from) {
window.location = set_QueryString('skip', from);
}
</script>
<div id="dvPager">
<asp:Repeater ID="pagerSorular" runat="server">
<ItemTemplate>
<div class="pageritem pagertext" id='<%# "pageritem-" + Container.DataItem %>'
onclick='<%# (Container.DataItem != "...")?("changepage(" + Container.DataItem + ");"): ("skipfrom(" + (this.PageNumber + 4) + ");") %>' >
<%# Container.DataItem %>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
<asp:DataList ID="gridSorular" runat="server" Width="100%" OnItemDataBound="gridSorular_ItemDataBound">
<ItemTemplate>
<div class="soruwrapper">
<asp:HiddenField ID="hfSoruID" runat="server" Value='<%# Eval("ID") %>' />
<div class="viewsbox boxtext">
<b class="boxtext"><%# Eval("VIEWS") %></b>
<br />Okuyan
<hr />
<div class='<%# "answersbox boxtext " + ((int.Parse(Eval("ANSWERS").ToString()) > 0) ? "isanswered" : "notanswered") %>'>
<b class="numtext"><%# Eval("ANSWERS")%></b>
<br />Cevap
</div>
</div>
<div class="item" onclick='<%# "soruyuac(" + Eval("ID") + ");" %>'>
<div class="soruheader" title='<%# Server.HtmlEncode(Eval("BODY").ToString())%>' >
<%# Eval("TITLE") %>
</div>
<div class="etiketwrapper">
<uc1:EtiketControl ID="EtiketControl1" runat="server" />
</div>
</div>
</div>
</ItemTemplate>
</asp:DataList>
Server-Side:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DataLayer;
public partial class SoruListe : System.Web.UI.UserControl
{
public int PageNumber
{
get
{
string strPgNum = Request.QueryString["pg"] as String;
if (!String.IsNullOrEmpty(strPgNum))
{
int pgnum;
if (int.TryParse(strPgNum, out pgnum))
{
if (pgnum <= 0)
{
return pgnum;
}
else
{
return 1;
}
}
else
{
return 1;
}
}
else
{
return 1;
}
}
}
public int PageSize { get { return 1; } }
public string PageName {
get
{
string url = Request.Url.ToString();
string[] parts = url.Split(new char[]{'/'});
return parts[parts.Length - 1];
}
}
public void Page_Load(object sender, EventArgs e)
{
}
public void SonSorular()
{
gridSorular.DataSource = BLL.SonSorular(300,300);
gridSorular.DataBind();
///
}
protected void CreatePager()
{
int pagenumber = this.PageNumber;
int start = 1;
if (PageNumber > 3)
{
start = pagenumber - 3;
}
int finish = pagenumber + 3;
int sorucount;
using (DataAccessDataContext db = new DataAccessDataContext())
{
sorucount = db.Sorus.Count();
}
List<string> pageritemlist = new List<string>();
int c = start;
for (int i = 0; i < finish; i++)
{
pageritemlist.Add((c++).ToString());
}
pageritemlist.Add("...");
pageritemlist.Add(sorucount.ToString());
pagerSorular.DataSource = pageritemlist.ToArray();
pagerSorular.DataBind();
}
public void ListAll()
{
CreatePager();
int pagesize = this.PageSize;
int skip = this.PageNumber * pagesize;
ListSorular(skip, pagesize);
}
public void Popular()
{
}
public void Active()
{
}
public void Unanswered()
{
}
public void ListSorular(int skip, int take)
{
using (DataAccessDataContext db = new DataAccessDataContext())
{
List<SoruGridView> sorular = (from s in db.Sorus
select new SoruGridView() {
ID = s.ID, TITLE = s.TITLE, BODY = s.BODY, TARIH = s.DATECREATED, VIEWS = s.VIEWS, ANSWERS = s.Cevaps.Count
}).Skip(skip).Take(take).ToList();
gridSorular.DataSource = sorular;
gridSorular.DataBind();
}
}
protected void gridSorular_ItemDataBound(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem )
{
HiddenField hfsoruid = e.Item.FindControl("hfSoruID") as HiddenField;
if (hfsoruid != null)
{
int sid;
if (int.TryParse(hfsoruid.Value, out sid))
{
EtiketControl tagsctrl = (EtiketControl)e.Item.FindControl("EtiketControl1");
tagsctrl.GetTags(sid);
}
}
}
}
}
There is also my JavaScript querystring parser written by me :)

Related

ASP.NET GridView RowDataBound TemplateField FindControl is null after invalid data entered

I am having trouble with my GridView RowDataBound event after I click on Save to save the data to the database.
I have a grid with 5 columns: Tag Name, Current Timestamp, Current Value, New Date, New Value.
The idea is the user will enter into the New Date/New Value to update the data in the database. The Current Timestamp and Current Value are what is already stored in the database.
I use a JQuery editor to enter the date.
When I click on Save, I have server side validation in place to check the entered values. If the data is valid, a message under the text in the New Value column is displayed to indicate this. If the validation fails, then a message in the New Value column is displayed.
New Date and New Value columns are TemplateField's. The New Value TemplateField contains a panel with two labels - one for OK status and the other for error.
The error occurs in MyDataGrid_RowDataBound when I call any e.Row.FindControl(...) which is triggered from the Save button click when I rebind.
It works ok if a valid value has been entered but if an invalid value is entered then it errors. In order to simplify the scenario, enter 100 for a valid value and anything else for an invalid.
This WebForm has been the trouble of my life. Maybe I shouldn't have used a GridView.
Anyway, I would appreciate any help here to identify the issue. And maybe a better approach to the form code.
I've took the code from my solution and moved it into a standalone solution to reproduce the issue. I've removed the database access and populated a datastructure. This is only ever done (once) in the Page Load when the page is initially loaded.
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="stylesheet" href="Styles/jquery-ui-timepicker-addon.css" />
<link rel="stylesheet" href="Styles/jquery-ui-1.10.1.custom.css" />
<link rel="stylesheet" href="Styles/jquery-ui-1.10.1.custom.min.css" />
<script src="Scripts/jquery-1.9.1.js"></script>
<script src="Scripts/jquery-ui-1.10.1.custom.js"></script>
<script src="Scripts/jquery-ui-1.10.1.custom.min.js"></script>
<script src="Scripts/jquery-ui-timepicker-addon.js"></script>
</head>
<body>
<script type="text/javascript">
/** Disable backkey */
$(document).unbind('keydown').bind('keydown', function (event) {
var doPrevent = false;
if (event.keyCode === 8) {
var d = event.srcElement || event.target;
if ((d.tagName.toUpperCase() === 'INPUT' && (d.type.toUpperCase() === 'TEXT' || d.type.toUpperCase() === 'PASSWORD' || d.type.toUpperCase() === 'FILE'))
|| d.tagName.toUpperCase() === 'TEXTAREA') {
doPrevent = d.readOnly || d.disabled;
} else {
doPrevent = true;
}
}
if (doPrevent) {
event.preventDefault();
}
});
$(function () {
$(".datetimepicker").datetimepicker({
changeMonth: true,
changeYear: true
});
});
$(function () {
$(".datepicker").datepicker({
changeMonth: true,
changeYear: true
});
});
$(function () {
$(".timepicker").timepicker({ showTimezone: false });
});
</script>
<form id="form1" runat="server">
<div>
<asp:GridView ID="MyDataGrid" runat="server"
EnableModelValidation="True"
DataKeyNames="Id"
AutoGenerateColumns="False"
AutoGenerateSelectButton="False"
EmptyDataText="There is no plant data configured."
OnRowDataBound="MyDataGrid_RowDataBound">
<Columns>
<asp:BoundField DataField="Name" SortExpression="Name" HeaderText="Tag Name"></asp:BoundField>
<asp:BoundField DataField="Date" SortExpression="Date" HeaderText="Current Timestamp"></asp:BoundField>
<asp:BoundField DataField="Value" SortExpression="Value" HeaderText="Current Value"></asp:BoundField>
<asp:TemplateField HeaderText="New Date<BR/>MM/DD/YYYY HH:MM">
<ItemTemplate>
<asp:TextBox ID="txtNewDate" runat="server" CssClass="datetimepicker"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="New Value">
<ItemTemplate>
<asp:TextBox ID="txtNewValue" runat="server"></asp:TextBox>
<asp:Panel ID="ErrorPanel" runat="server">
<br />
<asp:Label ID="lblError" runat="server" ForeColor="Red"></asp:Label>
<asp:Label ID="lblStatus" runat="server" ForeColor="#66cc00"></asp:Label>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="SaveButton" runat="server"
Text="Save Values"
ToolTip="Save the current changes."
OnClick="SaveButton_Click" />
</div>
</form>
</body>
</html>
Code Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
private const int COL_NEW_DATE = 3;
private const int COL_NEW_VALUE = 4;
bool canEdit = true;
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
PopulateDataGrid();
}
}
private void PopulateDataGrid()
{
// this is where i load from the database
List<RowData> data = new List<RowData>() {
new RowData() { Date = new DateTime(2000,1,1), Editable = true, Name = "Data Item 1", Value = 100.0 },
new RowData() { Date = new DateTime(2000,1,1), Editable = false, Name = "Data Item 2", Value = 120.0 },
new RowData() { Date = new DateTime(2000,1,1), Editable = true, Name = "Data Item 3", Value = 19.0 }
};
this.MyDataGrid.DataSource = data;
this.MyDataGrid.DataBind();
ViewState["GridData"] = this.MyDataGrid.DataSource;
}
private void SaveData()
{
for (int i = Page.Validators.Count - 1; i >= 0; i--)
Page.Validators.Remove(Page.Validators[i]);
ValidateData();
List<RowData> rowDataList = (List<RowData>)ViewState["GridData"];
if (this.IsValid)
{
foreach (GridViewRow row in this.MyDataGrid.Rows)
{
if (row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow && row.Enabled)
{
RowData dataItem = rowDataList[row.DataItemIndex];
var txtNewValue = row.Cells[COL_NEW_VALUE].FindControl("txtNewValue") as TextBox;
var txtNewDate = row.Cells[COL_NEW_DATE].FindControl("txtNewDate") as TextBox;
if (dataItem != null && txtNewDate != null && txtNewValue != null && !string.IsNullOrEmpty(txtNewValue.Text) && !string.IsNullOrEmpty(txtNewDate.Text))
{
var newValue = double.Parse(txtNewValue.Text);
var newDate = DateTime.Parse(txtNewDate.Text);
dataItem.InfoText = "Value written successfully for " + txtNewDate.Text;
dataItem.ErrorText = string.Empty;
dataItem.EnteredDateCache = string.Empty;
dataItem.EnteredValueCache = string.Empty;
if ((dataItem.Date.HasValue && DateTime.Compare(newDate, dataItem.Date.Value) >= 0) || !dataItem.Date.HasValue)
{
dataItem.Date = newDate;
dataItem.Value = newValue;
}
}
}
}
// save any outstanding changes if valid removed from demo
}
ViewState["GridData"] = rowDataList;
}
private void ValidateData()
{
List<RowData> rowDataList = (List<RowData>)ViewState["GridData"];
foreach (GridViewRow row in this.MyDataGrid.Rows)
{
if (row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow && row.Enabled)
ValidateDataRow(rowDataList, row);
}
}
private void ValidateDataRow(List<RowData> rowDataList, GridViewRow gridViewRow)
{
RowData rowData = rowDataList[gridViewRow.DataItemIndex];
bool valueOK = false;
var txtNewValue = gridViewRow.Cells[COL_NEW_VALUE].FindControl("txtNewValue") as TextBox;
var txtNewDate = gridViewRow.Cells[COL_NEW_DATE].FindControl("txtNewDate") as TextBox;
var labelError = gridViewRow.Cells[COL_NEW_VALUE].FindControl("lblError") as Label;
var labelInfo = gridViewRow.Cells[COL_NEW_VALUE].FindControl("lblStatus") as Label;
labelInfo.Text = string.Empty;
labelError.Text = string.Empty;
rowData.InfoText = string.Empty;
rowData.ErrorText = string.Empty;
rowData.EnteredDateCache = txtNewDate.Text;
rowData.EnteredValueCache = txtNewValue.Text;
if (rowData != null && (!string.IsNullOrEmpty(txtNewValue.Text) || !string.IsNullOrEmpty(txtNewDate.Text)))
{
if (!txtNewValue.Text.IsNumber())
{
rowData.ErrorText = rowData.Name + " must be a number.";
AddCustomValidatorForCell(rowData.ErrorText, gridViewRow, 4);
}
else
{
if (txtNewValue.Text != "100")
{
rowData.ErrorText = rowData.Name + " is invalid.";
AddCustomValidatorForCell(rowData.ErrorText, gridViewRow, 4);
}
else
{
valueOK = true;
}
}
}
}
private void AddCustomValidatorForCell(string errorMessage, GridViewRow gridViewRow, int cellIndex)
{
var labelError = gridViewRow.Cells[cellIndex].FindControl("lblError") as Label;
var divInfoError = gridViewRow.Cells[cellIndex].FindControl("ErrorPanel") as Panel;
labelError.Text = errorMessage;
labelError.ToolTip = errorMessage;
labelError.Attributes.Add("style", "color: red;");
CustomValidator validatePower = new CustomValidator()
{
IsValid = false,
ErrorMessage = errorMessage,
EnableViewState = false,
};
Page.Validators.Add(validatePower);
}
protected void SaveButton_Click(object sender, EventArgs e)
{
SaveData();
this.MyDataGrid.DataSource = ViewState["GridData"];
this.MyDataGrid.DataBind();
}
protected void MyDataGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow)
{
var rowData = e.Row.DataItem as RowData;
if (rowData != null)
{
DataControlFieldCell txtNewDate = (DataControlFieldCell)e.Row.Cells[COL_NEW_DATE];
DataControlFieldCell txtNewValue = (DataControlFieldCell)e.Row.Cells[COL_NEW_VALUE];
e.Row.Cells[1].Text = rowData.Date.HasValue ? rowData.Date.ToString() : string.Empty;
e.Row.Cells[2].Text = rowData.Value.HasValue ? rowData.Value.Value.ToString() : string.Empty;
txtNewValue.Enabled = txtNewDate.Enabled = (canEdit & rowData.Editable);
if (!string.IsNullOrEmpty(rowData.EnteredDateCache))
txtNewDate.Text = rowData.EnteredDateCache;
if (!string.IsNullOrEmpty(rowData.EnteredValueCache))
txtNewValue.Text = rowData.EnteredValueCache;
(e.Row.FindControl("lblStatus") as Label).Text = rowData.InfoText;
(e.Row.FindControl("lblError") as Label).Text = rowData.ErrorText;
//(e.Row.FindControl("ErrorPanel") as Panel).Visible = (!string.IsNullOrEmpty(rowData.InfoText) || !string.IsNullOrEmpty(rowData.ErrorText));
}
}
}
[Serializable()]
private class RowData
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime? Date { get; set; }
public double? Value { get; set; }
public string ValidationRule { get; set; }
public string ErrorText { get; set; }
public string InfoText { get; set; }
public string EnteredDateCache { get; set; }
public string EnteredValueCache { get; set; }
public bool Editable { get; set; }
}
}
public static class StringExtensionMethods
{
public static bool IsNumber(this String str)
{
double Number;
if (double.TryParse(str, out Number)) return true;
return false;
}
}
Looks like I was incorrectly setting the controls incorrectly in the RowDataBound event. This should be:
if (e.Row.RowType == System.Web.UI.WebControls.DataControlRowType.DataRow)
{
var rowData = e.Row.DataItem as RowData;
if (rowData != null)
{
DataControlFieldCell txtNewDate = (DataControlFieldCell)e.Row.Cells[COL_NEW_DATE];
if (!string.IsNullOrEmpty(rowData.EnteredValueCache))
{
var txtNewValue = (e.Row.FindControl("txtNewValue") as TextBox);
txtNewValue.Enabled = txtNewDate.Enabled = (canEdit & rowData.Editable);
txtNewValue.Text = rowData.EnteredValueCache;
}
(e.Row.FindControl("lblStatus") as Label).Text = rowData.InfoText;
(e.Row.FindControl("lblError") as Label).Text = rowData.ErrorText;
}
}
Remove the following lines from SaveData:
(row.FindControl("lblStatus") as Label).Text = dataItem.InfoText;
(row.FindControl("lblError") as Label).Text = dataItem.ErrorText;
Remove the following from ValidateDataRow:
labelInfo.Text = string.Empty;
labelError.Text = string.Empty;
I am assuming that calling the following:
DataControlFieldCell txtNewValue = (DataControlFieldCell)e.Row.Cells[COL_NEW_VALUE];
if (!string.IsNullOrEmpty(rowData.EnteredValueCache))
txtNewValue.Text = rowData.EnteredValueCache;
Will remove the controls from the template column when the data is set (which would be on the invalid value as it is not cleared in the cache) which is why I saw the error when an invalid value was entered.

ASP.NET: Prevent User Controls from disappearing

On my Webpage I try to add User Control elements dependant on checked boxes in a tree view. Therefore I create a table that contains the tree view and a panel in which these elements should be loaded. The structure is like this:
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<script language="javascript" type="text/javascript">
function doCheckBoxPostBack(e) {
var event = window.event ? window.event.srcElement : e.target;
if (event.tagName == "INPUT" && event.type == "checkbox")
__doPostBack("", "");
}
</script>
<form id="form1" runat="server">
<h1>Status</h1>
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<table>
<tr>
<td colspan="2" align="left" style="font-size:large">
Auswahl der anzuzeigenden Areas
</td>
</tr>
<tr>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<td valign="top">
<asp:TreeView ID="tvAreaSelect" runat="server"
onclick="doCheckBoxPostBack(event)" ShowCheckBoxes="All"
ontreenodecheckchanged="tvAreaSelect_TreeNodeCheckChanged">
<DataBindings>
<asp:TreeNodeBinding DataMember="System.Data.DataRowView" TextField="Text" ValueField="ID" />
</DataBindings>
</asp:TreeView>
</td>
<td>
<div style="overflow:auto; height:740px;">
<asp:Panel ID="panelContent" runat="server">
</asp:Panel>
</div>
</td>
</ContentTemplate>
</asp:UpdatePanel>
</tr>
</table>
</div>
</form>
</asp:Content>
In the code behind I load or unload my User Controls whenever one of the checkboxes changes its Checked value. This works just like it should, but when I press any button in one of the controls all of them disappear. Do I have to keep them in the cache or are there any other things to attend?
Here is a part of my code. I hope it makes clear what I'm doing.
protected void Page_Load(object sender, EventArgs e)
{
if (AreaIds.currList == null)
AreaIds.currList = new List<int>();
if (!this.Page.IsPostBack)
{
DataSet dsAreaGroups = dbStat.getDataSetAreaGroups();
DataSet dsAreasNotInAreaGroups = dbStat.getDataSetAreasNotInAreaGroups();
DataSet dsAreasInGroups = dbStat.getDataSetAreaGroupsWithAreas();
DataSet dsTree = new DataSet();
dsTree.Tables.Add("Table");
dsTree.Tables[0].Columns.Add("ID", typeof(string));
dsTree.Tables[0].Columns.Add("ParentID", typeof(string));
dsTree.Tables[0].Columns.Add("Text", typeof(string));
DataTableReader dtr = dsAreaGroups.CreateDataReader();
while (dtr.Read())
{
DataRow row = dsTree.Tables[0].NewRow();
object[] vals = new object[dtr.FieldCount];
dtr.GetValues(vals);
int inAreaGroupID = (int)vals.ElementAt(0);
string stName = (string)vals.ElementAt(1);
row["ID"] = inAreaGroupID;
row["Text"] = stName;
dsTree.Tables[0].Rows.Add(row);
}
dtr = dsAreasInGroups.CreateDataReader();
while (dtr.Read())
{
DataRow row = dsTree.Tables[0].NewRow();
object[] vals = new object[dtr.FieldCount];
dtr.GetValues(vals);
int inAreaID = (int)vals.ElementAt(0);
int inAreaGroupID = (int)vals.ElementAt(1);
string stName = (string)vals.ElementAt(2);
string stCombo = inAreaGroupID + "-" + inAreaID;
row["ID"] = stCombo;
row["ParentID"] = inAreaGroupID;
row["Text"] = stName;
dsTree.Tables[0].Rows.Add(row);
}
dtr = dsAreasNotInAreaGroups.CreateDataReader();
while (dtr.Read())
{
DataRow row = dsTree.Tables[0].NewRow();
object[] vals = new object[dtr.FieldCount];
dtr.GetValues(vals);
int inAreaID = (int)vals.ElementAt(0);
string stName = (string)vals.ElementAt(1);
row["ID"] = "0-" + inAreaID;
row["Text"] = stName;
dsTree.Tables[0].Rows.Add(row);
}
tvAreaSelect.SetDataSourceFromDataSet(dsTree, "ID", "ParentID");
tvAreaSelect.DataBind();
}
}
public void includeAreas(List<int> areaId)
{
int[] array = areaId.ToArray();
for (int i = 0; i < array.Length; i++)
{
Control ctrl = LoadControl("StatusArea.ascx", areaId[i]);
this.panelContent.Controls.Add(ctrl);
}
}
/// <summary>
/// Bereitstellung eines UserControl aus einer ascx-Datei
/// </summary>
/// <param name="UserControlPath">Das UserControl ascx-Datei</param>
/// <param name="constructorParameters">Parameter im Konstruktor der ascx.cs-Datei</param>
/// <returns>UserControl mit den entsprechenden Parametern</returns>
private UserControl LoadControl(string UserControlPath, params object[] constructorParameters)
{
List<Type> constParamTypes = new List<Type>();
foreach (object constParam in constructorParameters)
{
constParamTypes.Add(constParam.GetType());
}
UserControl ctl = Page.LoadControl(UserControlPath) as UserControl;
// Find the relevant constructor
System.Reflection.ConstructorInfo constructor = ctl.GetType().BaseType.GetConstructor(constParamTypes.ToArray());
//And then call the relevant constructor
if (constructor == null)
{
throw new MemberAccessException("The requested constructor was not found on : " + ctl.GetType().BaseType.ToString());
}
else
{
constructor.Invoke(ctl, constructorParameters);
}
// Finally return the fully initialized UC
return ctl;
}
protected void tvAreaSelect_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
{
TreeNode selNode = (TreeNode)e.Node;
TreeNode parentNode = selNode.Parent;
if (selNode.Checked && selNode.ChildNodes.Count == 0)
{
string stTest = selNode.Value.Substring(selNode.Value.IndexOf("-") + 1);
int inAreaID = Convert.ToInt32(stTest);
if (!AreaIds.currList.Contains(inAreaID))
AreaIds.currList.Add(inAreaID);
}
if (!selNode.Checked && selNode.ChildNodes.Count == 0)
{
string stTest = selNode.Value.Substring(selNode.Value.IndexOf("-") + 1);
int inAreaID = Convert.ToInt32(stTest);
if (AreaIds.currList.Contains(inAreaID))
AreaIds.currList.Remove(inAreaID);
}
foreach (TreeNode childNode in selNode.ChildNodes)
{
if (selNode.Checked)
{
string stTest = childNode.Value.Substring(childNode.Value.IndexOf("-") + 1);
int inAreaID = Convert.ToInt32(stTest);
childNode.Checked = true;
if (!AreaIds.currList.Contains(inAreaID))
AreaIds.currList.Add(inAreaID);
}
else
{
string stTest = childNode.Value.Substring(childNode.Value.IndexOf("-") + 1);
int inAreaID = Convert.ToInt32(stTest);
childNode.Checked = false;
if (AreaIds.currList.Contains(inAreaID))
AreaIds.currList.Remove(inAreaID);
}
}
includeAreas(AreaIds.currList);
}
Thanks in advance
I do believe your problem resides on the fact that unfortunately you need to reload your dynamic controls on each and every postback.
One solution is to keep a in-session list of 'loaded' controls, and recreate them at Page_Init.

ASP.NET Check UserName Availability using ClientSideEvents

This is the first post for me in this the greatest website.
Is there any possibility to change isValid property from OnCheckUserName function?If so how can I do that?
Actually in this example there is a code block which use web service:
<script type="text/javascript">
function OnloginIDValidation(s, e) {
if (e.value.toString().length > 0) {
e.errorText = "UserName is not available";
PageMethods.CheckUserName(e.value.toString(), OnCheckUserName);
}
}
function OnCheckUserName(unavailable) {
if (unavailable == true) {
e.isValid = true;
}
else if (unavailable != true) {
e.isValid = false;
}
}
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<dx:ASPxTextBox ID="txt_loginID" runat="server" AssociatedControlID="txt_loginID">
<InvalidStyle BackColor="#FFF5F5">
<Border BorderColor="Red" BorderStyle="Solid" BorderWidth="1px" />
</InvalidStyle>
<ClientSideEvents Validation="OnloginIDValidation" />
</dx:ASPxTextBox>
</asp:Content>
[WebMethod]
public static bool CheckUserName(string userName)
{
if (Membership.GetUser(userName) != null)
{
return true;
}
else
{
return false;
}
}
private void ApplyValidationSummarySettings()
{
vsValidationSummary1.RenderMode = (ValidationSummaryRenderMode)Enum.Parse(typeof(ValidationSummaryRenderMode), "BulletedList");
vsValidationSummary1.ShowErrorAsLink = true;
}
private void ApplyEditorsSettings()
{
ASPxEdit[] editors = new ASPxEdit[] {txt_loginID};
foreach (ASPxEdit editor in editors)
{
editor.ValidationSettings.ValidateOnLeave = true;
editor.ValidationSettings.SetFocusOnError = true;
}
}
It doesn't work
I hope to help me how can i fix it.
thanks
Set ASPxTextBox.ClientInstanceName attribute to some value, e.g. textBox1. Then use ASPxClientTextBox.SetIsValid method in OnCheckUserName method.
Like this:
function OnCheckUserName(unavailable) {
textBox1.SetIsValid(unavailable == true);
}
Check below links using JQuery & AJAX for username availability
http://www.aspsnippets.com/Articles/Check-UserName-Availability-in-ASP.Net-using-JQuery.aspx
http://www.aspsnippets.com/Articles/Check-Username-Availability-in-ASP.Net-using-AJAX-PageMethods.aspx

Duplicate Panel/List IDs upon recreating my List(s) of Controls

When I click my Remove button it is my intent to remove the Panel, then iterate through the remaining panels and give them a new ID from scratch I.E. if I removed Panel(3) from a list of 6 Panels I would iterate through and give them all new IDs Panels 0-5.
My issue is that I keep running into an error after I delete my panel where I have duplicate ID names. For the life of me I cannot see where I am going wrong so I am reaching out hoping I am just blind or for advice.
I was setting a breakpoint at my btnDelete function and step through it but I am not seeing my logic shortcoming in why I experience an issue with multiple Panels of the same ID.
ASPX:
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage/MasterPage.master" AutoEventWireup="true" CodeFile="Search.aspx.cs" Inherits="Search" EnableTheming="true" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
<link href="App_Themes/ui-lightness/jquery-ui-1.7.2.custom.css" rel="stylesheet"
type="text/css" />
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css"
rel="stylesheet" type="text/css" />
<script src="Includes/JavaScript/jquery-1.7.1.js" type="text/javascript"></script>
<script src="Includes/JavaScript/jquery.ui.datepicker.js" type="text/javascript"></script>
<script src="Includes/JavaScript/jquery.ui.widget.js" type="text/javascript"></script>
<script src="Includes/JavaScript/jquery.ui.core.js" type="text/javascript"></script>
<%--Script for the Dropdown Datepicker--%>
<script type="text/javascript">
$(function () {
$("input.datepicker").datepicker({ showOn: 'button', buttonImage: 'Includes/Images/calender.gif', buttonImageOnly: false, onSelect: function () { }
});
});
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" runat="Server">
<h1>
Search
<asp:HyperLink ID="HyperLink1" runat="server" ImageUrl="Includes/Images/action_help.gif"
NavigateUrl="~/user_manual.pdf" Target="_blank" ToolTip="Search Help"></asp:HyperLink></h1>
<table border="0" cellpadding="6" cellspacing="0">
<tr>
<td>
<asp:Button ID="btnAdd" runat="server" Text="Add Control" onclick="btnAdd_Click" />
<asp:Button ID="btnClear" runat="server" Text="Reset" onclick="btnClear_Click" />
<asp:Button ID="btnSearch" runat="server" Text="Search" OnClick="btnSearch_Click" />
</td>
<td>
<asp:TextBox ID="txtTitle" class="searchPage" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
<asp:PlaceHolder ID="myPlaceholder" runat="server"></asp:PlaceHolder>
</td>
Code behind:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Runtime.Serialization;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
public partial class Search : BasePage
{
List<Users> userroles = new List<Users>();
//Panel that contains all our Dynamically added user controls.
List<Panel> persistControls = new List<Panel>();
public int userid = 0;
public byte IsActive = 1;
public int error = 0;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
// Calls three functions responsible for pulling from the Database and binding the Datagrid.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
GetClustersFromDB(userid);
BindGrid();
BindState();
}
else
{
// Where I am recreating my controls.
DynamicQueryRecreateLogic();
}
}
protected void DynamicQueryRecreateLogic()
{
if (Session["persistControls"] != null)
{
// Local Value that contains the members of the current persistControls session, not yet pushed to the page.
persistControls = (List<Panel>)Session["persistControls"];
int count = 0;
foreach (Panel panel in persistControls)
{
//AddQuestionTypeDropDownList(count);
panel.ID = "panel" + "(" + count.ToString() + ")";
foreach (Control control in panel.Controls)
{
if (control.GetType() == typeof(DropDownList))
{
control.ID = "list" + "(" + count.ToString() + ")";
DropDownList list = (DropDownList)panel.FindControl(control.ID);
list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
}
if (control.GetType() == typeof(TextBox))
{
control.ID = "txtBox" + "(" + count.ToString() + ")";
}
}
// Re-Adding our Remove Button
Button btnRemove = new Button();
btnRemove.Click += new EventHandler(btnDelete_Click);
btnRemove.Text = "Remove";
btnRemove.CommandArgument = count.ToString();
// Pushing to Placeholder
myPlaceholder.Controls.Add(panel);
myPlaceholder.Controls.Add(btnRemove);
count++;
}
}
}
private DropDownList AddQuestionTypeDropDownList()
{
DropDownList list = new DropDownList();
list.ID = "list" + "(" + persistControls.Count.ToString() + ")";
list.Items.Add(new ListItem("--Select One--", ""));
list.Items.Add(new ListItem("Title", "1"));
list.Items.Add(new ListItem("Contact", "2"));
list.Items.Add(new ListItem("Date Created", "3"));
list.SelectedIndexChanged += new EventHandler(list_SelectedIndexChanged);
list.AutoPostBack = true;
return list;
}
private TextBox AddFieldTypeTextBox(int count)
{
TextBox box = new TextBox();
box.ID = "txtBox" + "(" + count.ToString() + ")";
return box;
}
protected void btnAdd_Click(object sender, EventArgs e)
{
try
{
Panel panelContainer = new Panel();
panelContainer.ID = "panel" + "(" + persistControls.Count.ToString() + ")";
panelContainer.Controls.Add(AddQuestionTypeDropDownList());
Button btnRemove = new Button();
btnRemove.Click += new EventHandler(btnDelete_Click);
btnRemove.Text = "Remove";
btnRemove.CommandArgument = persistControls.Count.ToString();
persistControls.Add(panelContainer);
myPlaceholder.Controls.Add(panelContainer); // Pushes the Panel to the page.
myPlaceholder.Controls.Add(btnRemove); // Pushes our Button to the page.
Session["persistControls"] = persistControls; // put it in the session
}
catch
{
throw;
}
}
protected static string DecipherCountNumber(string IDHolder)
{
int start = IDHolder.IndexOf("(");
if (start == -1)
{
return IDHolder;
}
else
{
return IDHolder.Substring(start + 1).Replace(")", string.Empty);
}
}
protected void list_SelectedIndexChanged(object sender, EventArgs e)
{
//I need to fix the dynamic Add location. I need to track some type of enumeration or attributes of the panel for recreation.
try
{
DropDownList list = (DropDownList)sender;
string IDHolder = list.ID.ToString();
int count = Convert.ToInt32(DecipherCountNumber(IDHolder));
Panel panelContainer = persistControls.Find(delegate(Panel panel) { return panel.ID == "panel" + "(" + count.ToString() + ")"; });
if (list.SelectedIndex == 1)
{
//panelContainer.Controls.Add(AddFieldTypeTextBox(count));
}
if (list.SelectedIndex == 2)
{
//panelContainer.Controls.Remove(FindControl("txtBox" + "(" + count.ToString() + ")"));
}
if (list.SelectedIndex == 3)
{
//panelContainer.Controls.Remove(FindControl("txtBox" + "(" + count.ToString() + ")"));
}
Session["persistControls"] = persistControls;
}
catch
{
throw;
}
}
protected void btnClear_Click(object sender, EventArgs e)
{
try
{
Session["persistControls"] = null;
Response.Redirect(Request.Url.ToString());
}
catch
{
throw;
}
}
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
int deleteThisOne = int.Parse(((Button)sender).CommandArgument);
persistControls.Remove(persistControls[deleteThisOne]);
Session["persistControls"] = persistControls;
Response.Redirect(Request.Url.ToString(), false);
}
catch
{
throw;
}
}
I modified my DynamicQueryControls to do the recreation OnInit rather than at PageLoad. Quite a few issues arise from creating this at the PageLoad level.

Object and nested datalists

I am having trouble displaying my object in a datalist.
My object loks like this:
public class Course
{
private string courseName;
private DateTime[] courseDates;
public string CourseName
{
get { return courseName; }
set { courseName = value; }
}
public DateTime[] CourseDates
{
get { return courseDates; }
set {
foreach (DateTime dt in courseDates)
{
if (dt < DateTime.Now)
throw new Exception("The date of the course has to be after todays date.");
}
courseDates = value; }
}
public Course(string _courseName, DateTime[] _courseDates)
{
courseName = _courseName;
courseDates = _courseDates;
}
}
When I try to display it in a datalist the name of the course looks ok. But The dates are not shown.
So I was thinking I needed a nested datalist but then I don't know how to fill the second datalist with the dates in the object.
I've show two solutions:
<asp:DataList ID="DataList1" runat="server"
onitemdatabound="DataList1_ItemDataBound">
<ItemTemplate>
<td><%# DataBinder.Eval(Container.DataItem, "CourseName")%></td>
<td><%# RenderDates( DataBinder.Eval(Container.DataItem, "CourseDates"))%></td>
<td>
<asp:DataList ID="DateList" runat="server">
<ItemTemplate>
<td><%# Container.DataItem%></td>
</ItemTemplate>
</asp:DataList>
</td>
</ItemTemplate>
</asp:DataList>
and
public string RenderDates(object dates)
{
DateTime[] ds = dates as DateTime[];
StringBuilder sb = new StringBuilder();
if( ds != null && ds.Length > 0)
{
sb.Append(ds[0]);
for (int i = 1; i < ds.Length; i++)
{
sb.AppendFormat(" - {0}", ds[i]);
}
}
return sb.ToString();
}
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
DataListItem item = e.Item;
if ((item.ItemType == ListItemType.Item) ||
(item.ItemType == ListItemType.AlternatingItem))
{
var innerList= (DataList)item.FindControl("DateList");
innerList.DataSource = ((Course) item.DataItem).CourseDates;
innerList.DataBind();
}
}

Resources