Problem and Description:
I have a GridView with programmatically added DropDownLists on RowDataBound to every cell.
The DropDownLists all have Data Sources.
When I press a 'Save' button, it is meant to read all the selecteditems in the DropDownLists and save them to a database.
However, when I click on the button, it causes postback and deletes all of the controls in the GridView and therefore, none of them can be found in my button_click event.
After asking questions before and trying different techniques to try store the dropdownlists in Cache/Session state etc, I simply can't seem to be able to keep the dropdownlists or the data when I click the button.
Therefore, I am now trying to add an UpdatePanel and use AJAX to try stop the refresh of the GridView.
My attempt was as such:
<asp:GridView ID="gv_Rota" runat="server" AutoGenerateColumns="false" OnRowDataBound="gv_Rota_RowDataBound">
<HeaderStyle BackColor="#6a3d98" ForeColor="White" Height="20" />
<RowStyle HorizontalAlign="Center" Height="20px" Width="100px" />
<AlternatingRowStyle Height="20px" />
</asp:GridView>
</div>
<asp:Label ID="lbl_NameOfRota" runat="server" Text="New rota name:"></asp:Label>
<input runat="server" id="txt_RotaName" />
<asp:UpdatePanel runat="server" ID="RotaUpdatePanel">
<ContentTemplate>
<asp:Button ID="btn_AddRota" runat="server" Text="Add" OnClick="btn_AddRota_Click" CssClass="ButtonAdminPage" />
</ContentTemplate>
</asp:UpdatePanel>
As you can see, I placed the UpdatePanel around my button only, however, it still seemed to refresh the GridView and delete all the controls.
Questions:
Firstly, why did my attempt not work?
Secondly, how can I get around this problem using AJAX and Update Panels, or is there another method to get me what I need? (Baring in mind, if something else is suggested, I've probably already tried it).
EDIT 2:
Supplied Code:
This is when I bind the DropDownLists:
protected void gv_Rota_RowDataBound(object sender, GridViewRowEventArgs e)
{
for (int i = 1; i <= ColumnCount; i++)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int day = e.Row.RowIndex;
day += 1;
ddlShift = new DropDownList();
ddlShift.ID = "ddlShift" + "WK" + i.ToString() + "DAY" + day.ToString();
ddlShift.DataSource = DCListOfShifts;
ddlShift.DataValueField = "SHIFT_ID";
ddlShift.DataTextField = "SHIFT_NAME";
ddlShift.Attributes.Add("Place", i.ToString());
ddlShift.DataBind();
ddlShift.Items.Insert(0, new ListItem("Shift..."));
ddlShift.CssClass = "ddl_rotamanager";
e.Row.Cells[i].Controls.Add(ddlShift);
}
}
}
This is when I create the GridView dependant on the amount of columns passed:
private void BindGrid(int Amount)
{
gv_Rota.DataSource = null;
gv_Rota.Columns.Clear();
BoundField bfield = new BoundField();
bfield.HeaderText = "Days";
bfield.DataField = "Days";
gv_Rota.Columns.Add(bfield);
for (int i = 0; i < Amount; i++)
{
int week = i + 1;
string sWeek = "Week " + week.ToString();
TemplateField tfield = new TemplateField();
tfield.HeaderText = sWeek;
gv_Rota.Columns.Add(tfield);
}
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Days", typeof(string)));
dt.Rows.Add("M");
dt.Rows.Add("T");
dt.Rows.Add("W");
dt.Rows.Add("T");
dt.Rows.Add("F");
dt.Rows.Add("S");
dt.Rows.Add("S");
gv_Rota.DataSource = dt;
gv_Rota.DataBind();
}
This is where I get the selected amount of columns and call the method to create the GridView, I also store the amount in Cache:
protected void ddl_RotaAmountOfWeeks_SelectedIndexChanged(object sender, EventArgs e)
{
if (IsPostBack)
{
int Amount;
int.TryParse(ddl_RotaAmountOfWeeks.SelectedItem.ToString(), out Amount);
ColumnCount = Amount;
Cache.Add("columnCount", ColumnCount, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 60, 0), CacheItemPriority.Default, null);
BindGrid(Amount);
}
}
Button code:
protected void btn_AddRota_Click(object sender, EventArgs e)
{
//My first attempt at trying to save the GridView, realising I Cache'd the GridView before selecting items.
//gv_Rota = (GridView)Cache["cacheGridView"];
//Set of the size of the array to the amount of rows * colums
//this will be the maximum amount of events added
int arraysize = gv_Rota.Rows.Count * (int)Cache["columnCount"];
//the current array item being added
int arrayitem = 0;
//Finally an array of ROTA_EVENTS to pass to WCF
wsPersonnel.DC_WFM_ROTA_EVENTS[] arrayofRotaEvents = new wsPersonnel.DC_WFM_ROTA_EVENTS[arraysize];
foreach (GridViewRow row in gv_Rota.Rows)
{
for (int i = 1; i <= (int)Cache["columnCount"]; i++)
{
int day = row.RowIndex;
day += 1;
DropDownList DDL1 = (DropDownList)gv_Rota.Rows[row.RowIndex].Cells[i].FindControl("ddlShiftWK" + i.ToString() + "DAY" + day.ToString());
wsPersonnel.DC_WFM_ROTA_EVENTS dcEvent = new wsPersonnel.DC_WFM_ROTA_EVENTS
{
SHIFT_ID = DDL1.SelectedItem.Value,
WEEK = i,
WEEKSpecified = true,
DAY = day,
DAYSpecified = true,
};
arrayofRotaEvents[arrayitem++] = dcEvent;
}
}
wsP.AddRota(new wsPersonnel.DC_WFM_ROTA
{
ROTA_NAME = txt_RotaName.Value,
PERIOD_TYPE = 1,
PERIOD_TYPESpecified = true,
PERIOD_AMOUNT = ColumnCount,
PERIOD_AMOUNTSpecified = true,
ROTA_EVENTS = arrayofRotaEvents
});
}
Example of what the GridView looks like:
If you want to stop postback on button click inside the update panel then you can try this
<asp:UpdatePanel runat="server" ID="RotaUpdatePanel" UpdateMode="Conditional">
<ContentTemplate>
<asp:Button ID="btn_AddRota" runat="server" Text="Add" OnClick="btn_AddRota_Click" CssClass="ButtonAdminPage" ClientIDMode="AutoID"/>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btn_AddRota" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
Related
We have a table on aspx page as -
<asp:Table ID="tblContainer" runat="server" Visible="false">
<asp:TableHeaderRow>
<asp:TableCell> Alplabates </asp:TableCell>
</asp:TableHeaderRow>
</asp:Table>
and we are adding control in this table as -
protected void Page_Load(object sender, EventArgs e)
{
int rowcount = tblContainer.Rows.Count;
// rowcount is one always
GenerateDynamicControls();
}
private void GenerateDynamicControls()
{
int rowcount = tblContainer.Rows.Count;
tblContainer.Visible = true;
for (int i = 0; i < 2; i++)
{
TableRow tr = new TableRow();
TableCell td = new TableCell();
TextBox textBox = new TextBox();
textBox.ID = i + "abc";
td.Controls.Add(textBox);
tr.Cells.Add(td);
tblContainer.Rows.Add(tr);
}
}
Table row count appears as one always. We tried by setting EnableViewState=true but no luck.
Can you please guide how can we get its value?
Thank you!
protected void Gridproducts_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hp = new HyperLink();
hp = (HyperLink)e.Row.FindControl("linkSelectprd");
var Pid = DataBinder.Eval(e.Row.DataItem, "product_id").ToString();
var Catid = Request.QueryString["Cid"].ToString();
hp.NavigateUrl = "Sales.aspx?Cid="+Catid+"&"+"Pid="+Pid;
if (!IsPostBack && Request.QueryString["Pid"] != null)
{
this is the variable in which the value of quantity increments
int i=0;
lbltotalquantity.Text = i.ToString() + 1;
}
}
}
}
I use LinkButtons inside a Grid template. I want to be able to raise events when clicking the LinkButtons the value of lable is incremented on + link and decrementd on - link button as lable contains the quantity of Products added to invoice. How can I accomplish this?
I believe this is what you want....
You don't do the increment in RowDataBound because RowDataBound trigger when you are binding the GridView
.aspx
<asp:ScriptManager ID="sm" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="up" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gv" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateField HeaderText="Product">
<ItemTemplate>
<asp:Label ID="lblProduct" runat="server" Text='<%# Eval("Product") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Quantity">
<ItemTemplate>
<asp:Label ID="lblQuantity" runat="server" Text="0"></asp:Label>
<asp:LinkButton ID="lbtnPlus" runat="server" Text="+" OnClick="lbtnPlus_Click"></asp:LinkButton>
<asp:LinkButton ID="lbtnMinus" runat="server" Text="-" OnClick="lbtnMinus_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="gv" />
</Triggers>
</asp:UpdatePanel>
.cs
protected void Page_Load(object sender, EventArgs e)
{
// Check
if (!IsPostBack)
{
// Variable
string[] product = { "Dell", "Asus", "Acer", "Toshiba", "Fujishu", "VAIO" };
DataTable dt = new DataTable();
dt.Columns.Add("Product");
for (int i = 0; i < product.Length; i++)
dt.Rows.Add(product[i]);
gv.DataSource = dt;
gv.DataBind();
// Dispose
dt.Dispose();
}
}
private void DoTheMath(GridViewRow row, bool isAdd)
{
// Variable
bool isNumber = false;
int currentValue = 0;
// Find Control
Label lblQuantity = row.FindControl("lblQuantity") as Label;
// Check
if (lblQuantity != null)
{
// Check
if (lblQuantity.Text.Trim() != string.Empty)
{
isNumber = int.TryParse(lblQuantity.Text.Trim(), out currentValue);
// Check
if (isNumber)
{
// Is Add
if (isAdd)
currentValue++;
else
{
// Check cannot be less than 0
if (currentValue > 0)
currentValue--;
}
}
// Set to TextBox
lblQuantity.Text = currentValue.ToString();
}
}
}
protected void lbtnPlus_Click(object sender, EventArgs e)
{
// Get
LinkButton lbtn = sender as LinkButton;
GridViewRow row = lbtn.NamingContainer as GridViewRow;
DoTheMath(row, true);
}
protected void lbtnMinus_Click(object sender, EventArgs e)
{
// Get
LinkButton lbtn = sender as LinkButton;
GridViewRow row = lbtn.NamingContainer as GridViewRow;
DoTheMath(row, false);
}
I have a grid, which is filled with data after a button is pressed.
It has columns for every day of a certain month:
When the user presses the Edit button, I want the labels (showing text dayLabelText) to be replaced by controls for entering data of a particular value for that day of the month.
But when I press the Edit button, all the controls disappear:
When I press the Cancel button, nothing changes.
How should I modify the code shown below in order to fix this bug (when I press Edit, the dropdown lists should be shown, when I press Cancel - the text fields) ?
*.aspx file:
<%# Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="plan.aspx.cs" Inherits="plan"
EnableViewState="true" ViewStateMode="Enabled" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" Runat="Server" EnableViewState="true" ViewStateMode="Enabled">
[...]
<asp:GridView
ID="dailyPlanGrid"
runat="server"
OnRowCancelingEdit="dailyPlanGrid_RowCancelingEdit"
OnRowEditing="dailyPlanGrid_RowEditing"
AutoGenerateColumns="False" OnRowDataBound="dailyPlanGrid_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Edit" ShowHeader="False" HeaderStyle-HorizontalAlign="Left">
<EditItemTemplate>
<asp:LinkButton ID="lbkUpdate" runat="server" CausesValidation="True" CommandName="Update" Text="Update"></asp:LinkButton>
<asp:LinkButton ID="lnkCancel" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="lnkEdit" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="">
<EditItemTemplate>
<asp:Label ID="titleLabelEdit" runat="server" Text='<%# Bind("Title") %>' />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="titleLabelItem" runat="server" Text='<%# Bind("Title") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Content>
.aspx.cs file:
public partial class plan : System.Web.UI.Page
{
[...]
private void UpdateGrid(int year, int month, string userName, bool updateTableCall = false)
{
[...]
DisplaySelectedPlan(year, month, userName, updateTableCall);
}
private void DisplaySelectedPlan(int year, int month, string userName, bool updateTableCall = false)
{
DataTable data = new DataTable();
DataColumn titleColumn = new DataColumn();
titleColumn.ColumnName = "Title";
titleColumn.Caption = "";
data.Columns.Add(titleColumn);
INumberOfDaysInMonthCalculator numberOfDaysInMonthCalculator = new NumberOfDaysInMonthCalculator();
int daysInMonth = numberOfDaysInMonthCalculator.GetNumberOfDays(year, month);
if (updateTableCall)
{
AddDayColumns(daysInMonth);
}
var row = data.NewRow();
row["Title"] = "Вид";
data.Rows.Add(row);
Database.Instance.Open();
IDailyWorkingTimesReader dailyWorkingTimesReader = new DailyWorkingTimesReader(Database.Instance.SqlCommandFactory);
dailyWorkingTimesReader.ReadData(year, month, userName);
IDictionary<int, DateTime> startTimesByDay = dailyWorkingTimesReader.GetStartTimes();
IDictionary<int, DateTime> endTimesByDay = dailyWorkingTimesReader.GetEndTimes();
AddStartRow(data, daysInMonth, startTimesByDay);
AddEndRow(data, daysInMonth, endTimesByDay);
var holidayRow = data.NewRow();
holidayRow["Title"] = "Госудаственный праздник";
data.Rows.Add(holidayRow);
var preHolidayRow = data.NewRow();
preHolidayRow["Title"] = "Предпраздничный день";
data.Rows.Add(preHolidayRow);
dailyPlanGrid.ShowHeaderWhenEmpty = true;
dailyPlanGrid.DataSource = data;
dailyPlanGrid.DataBind();
}
private void AddDayColumns(int daysInMonth)
{
for (int i = 1; i <= daysInMonth; i++)
{
TemplateField dayColumn = new TemplateField();
dayColumn.HeaderText = "" + i;
dayColumn.EditItemTemplate = new DayEditItemTemplate(i);
dayColumn.ItemTemplate = new DayItemTemplate(i);
dailyPlanGrid.Columns.Add(dayColumn);
}
}
private static void AddEndRow(DataTable data, int daysInMonth, IDictionary<int, DateTime> endTimesByDay)
{
var endRow = data.NewRow();
endRow["Title"] = "Конец";
FillTimeColumns(daysInMonth, endRow, endTimesByDay);
data.Rows.Add(endRow);
}
private static void AddStartRow(DataTable data, int daysInMonth, IDictionary<int, DateTime> startTimesByDay)
{
var startRow = data.NewRow();
startRow["Title"] = "Начало";
FillTimeColumns(daysInMonth, startRow, startTimesByDay);
data.Rows.Add(startRow);
}
private static void FillTimeColumns(int daysInMonth, DataRow row, IDictionary<int, DateTime> timesByDay)
{
for (int i = 1; i <= daysInMonth; i++)
{
if (timesByDay.ContainsKey(i))
{
row["Day" + i] = timesByDay[i];
}
}
}
private void CreatePlanForSelectedEmployeeAndMonth(int year, int month, string userName)
{
IDailyPlanCreator dailyPlanCreator = new DailyPlanCreator(Database.Instance.SqlCommandFactory,
new NumberOfDaysInMonthCalculator());
Database.Instance.Open();
dailyPlanCreator.CreateDailyPlan(year, month, userName);
}
protected void updateTableButton_Click(object sender, EventArgs e)
{
// Here the grid is initialized (after the user presses some button)
DataTable dataTable = monthList.DataSource as DataTable;
DataRow row = dataTable.Rows[monthList.SelectedIndex] as DataRow;
IUserNameExtractor userNameExtractor = new UserNameExtractor();
UpdateGrid((int)row["year"], (int)row["month"], userNameExtractor.ExtractUserNameWithoutDomain(Request.LogonUserIdentity.Name), true);
}
protected void dailyPlanGrid_RowEditing(object sender, GridViewEditEventArgs e)
{
dailyPlanGrid.EditIndex = e.NewEditIndex;
DataTable dataTable = monthList.DataSource as DataTable;
DataRow row = dataTable.Rows[monthList.SelectedIndex] as DataRow;
IUserNameExtractor userNameExtractor = new UserNameExtractor();
UpdateGrid((int)row["year"], (int)row["month"], userNameExtractor.ExtractUserNameWithoutDomain(Request.LogonUserIdentity.Name));
}
protected void dailyPlanGrid_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
dailyPlanGrid.EditIndex = -1;
DataTable dataTable = monthList.DataSource as DataTable;
DataRow row = dataTable.Rows[monthList.SelectedIndex] as DataRow;
IUserNameExtractor userNameExtractor = new UserNameExtractor();
UpdateGrid((int)row["year"], (int)row["month"], userNameExtractor.ExtractUserNameWithoutDomain(Request.LogonUserIdentity.Name));
}
protected void dailyPlanGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if ((e.Row.RowType == DataControlRowType.DataRow) && (dailyPlanGrid.EditIndex > -1))
{
DataTable dataTable = monthList.DataSource as DataTable;
DataRow row = dataTable.Rows[monthList.SelectedIndex] as DataRow;
int year = (int)row["year"];
int month = (int)row["month"];
INumberOfDaysInMonthCalculator numberOfDaysInMonthCalculator = new NumberOfDaysInMonthCalculator();
int daysInMonth = numberOfDaysInMonthCalculator.GetNumberOfDays(year, month);
if (e.Row.RowIndex == 0)
{
// Type
for (int i=1; i <= daysInMonth; i++)
{
DropDownList dropDownList = (DropDownList) e.Row.FindControl("dayDropDownList" + i);
if (dropDownList != null)
{
dropDownList.Items.Clear();
dropDownList.Items.Add("item1");
dropDownList.Items.Add("item2");
}
}
}
else if (e.Row.RowIndex == 1)
{
// Start time of the business day
}
else if (e.Row.RowIndex == 2)
{
// End time of the business day
}
else if (e.Row.RowIndex == 3)
{
// Holiday
}
else if (e.Row.RowIndex == 4)
{
// Pre-holiday
}
}
}
}
Note that the columns for all days are added programmatically. It must be done in this way because
the customer wants the days to be in displayed in columns (one column per day, not one row per day) and
the number of days in a particular month is different.
Therefore, in I add columns with 2 types of templates - one for displaying and one for editing day-related data.
private void AddDayColumns(int daysInMonth)
{
for (int i = 1; i <= daysInMonth; i++)
{
TemplateField dayColumn = new TemplateField();
dayColumn.HeaderText = "" + i;
dayColumn.EditItemTemplate = new DayEditItemTemplate(i);
dayColumn.ItemTemplate = new DayItemTemplate(i);
dailyPlanGrid.Columns.Add(dayColumn);
}
}
DayEditItemTemplate.cs:
public class DayEditItemTemplate : ITemplate
{
private readonly int day;
public DayEditItemTemplate(int aDay)
{
day = aDay;
}
public void InstantiateIn(Control container)
{
DropDownList dropDownList = new DropDownList();
dropDownList.ID = "dayDropDownList"+day;
dropDownList.Items.Add("item1");
dropDownList.Items.Add("item2");
dropDownList.Items.Add("item3");
container.Controls.Add(dropDownList);
}
}
DayItemTemplate.cs:
public class DayItemTemplate : ITemplate
{
private readonly int day;
public DayItemTemplate(int aDay)
{
day = aDay;
}
public void InstantiateIn(Control container)
{
Label dayLabel = new Label();
dayLabel.ID = "dayLabelText"+day;
dayLabel.Text = "dayLabelText";
container.Controls.Add(dayLabel);
}
}
Update 1: The error has something to do with the fact that I add the day-oriented controls programmatically.
Justification: When I a column in the **.aspx* file, the problem does not occur (with that particular column).
<asp:TemplateField HeaderText="DayX">
<EditItemTemplate>
<asp:DropDownList ID="dayXdropDownList" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="dayXLabel" Text="dayXLabel" runat="server" />
</ItemTemplate>
</asp:TemplateField>
You need to add EditItemTemplate for each column and bind it as following,
<EditItemTemplate>
<asp:Label ID="titleLabelEdit" runat="server" Text='<%# Bind("Title") %>' />
</EditItemTemplate>
Please help me with following, just something weird is going on.
I have a gridview with paging where the first column is filled with checkboxes.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="..." DataKeyNames="EventID" EnableViewState="false"
GridLines="None" AllowSorting="True"
AllowPaging="True" Width="100%"
onpageindexchanging="GridView1_PageIndexChanging"
onprerender="GridView1_PreRender">
<HeaderStyle Wrap="false" />
<Columns>
<asp:TemplateField HeaderStyle-HorizontalAlign="Left">
<HeaderTemplate>
<asp:CheckBox ID="SelectAllEvs" runat="server" EnableViewState="false" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="EventSelector" runat="server" EnableViewState="false" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField ... >
<ItemStyle Wrap="False" />
</asp:BoundField>
<asp:BoundField ... >
</asp:BoundField>
<asp:BoundField ... >
</asp:BoundField>
</Columns>
</asp:GridView>
CodeBehind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Session["PageIndex"] != null)
{
GridView1.PageIndex = Convert.ToInt32(Session["PageIndex"]);
}
}
}
protected void GridView1_PreRender(object sender, EventArgs e)
{
// loading checkbox values from the session collection
GridView gv = (GridView)sender;
LoadCheckboxState(gv);
Session["PageIndex"] = gv.PageIndex;
}
private void LoadCheckboxState(GridView gv)
{
for (int i = 0; i < gv.Rows.Count; i++)
{
var chkBox = GridView1.Rows[i].FindControl("EventSelector") as CheckBox;
int id = gv.PageIndex * gv.PageSize + i;
if (SelectedIndexes.Contains(id))
{
chkBox.Checked = true;
}
else
{
chkBox.Checked = false;
}
}
}
private List<int> SelectedIndexes
{
get
{
if(Session["selectedRows"] == null)
{
Session["selectedRows"] = new List<int>();
}
return (List<int>)Session["selectedRows"];
}
}
private void SaveCheckboxState(GridView gv)
{
for (int i = 0; i < GridView1.Rows.Count; i++)
{
var chkBox = GridView1.Rows[i].FindControl("EventSelector") as CheckBox;
int id = gv.PageIndex * gv.PageSize + i;
if (chkBox.Checked)
{
//see if we have an id added already
if (!SelectedIndexes.Contains(id))
{
SelectedIndexes.Add(id);
}
}
else
{
if (SelectedIndexes.Contains(id))
{
SelectedIndexes.Remove(id);
}
}
}
}
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
// saving current page checkbox values to the session collection
GridView gv = (GridView)sender;
SaveCheckboxState(gv);
GridView1.PageIndex = e.NewPageIndex;
}
When I first get to my page I check some checkboxes and then press F5. Apparently after pressing it I dont have any values in SelectediIndexes and all unselected checkboxes must be checked = false on the PreRender stage but they appear checked after all this. And the problem of the same nature: I checked some on the first page; went to the second page (currently having 2 indexes in the SelectedValues) and after pressing F5 the same I have checked the same checkboxes as on the first page, though they mustn't. I'm absolutely confused with this. How can I fix this? Thanx for any help.
I've found the reason to that strange behavior. I'm using Firrefox. And one of the features of this browser is saving state of some fields when refreshing the page. If you want to refresh a page fully you should refresh it with pressed shift button. Tested in Google Chrome - works just fine.
i am working with dynamic TextBoxes and then Getting their Values in code behind file. I am creating these boxes using Javascript. my asp.net page code is
<script type="text/javascript">
$(document).ready(function () {
var counter = 1;
$("#addButton").click(function () {
if (counter > 10) {
alert("Only 10 textboxes allow");
return false;
}
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
newTextBoxDiv.html('<input type="text" name="textbox' + counter +
'" id="textbox' + counter + '" value="" >');
newTextBoxDiv.appendTo("#TextBoxesGroup");
counter++;
return false;
});
});
</script>
</head>
<body>
<form id="form2" runat="server">
<h1>jQuery add / remove textbox example</h1>
<asp:TextBox runat="server" ID="txt1" type='text' name="textname" />
<asp:Panel runat="server" ID='TextBoxesGroup'>
</asp:Panel>
<asp:LinkButton ID="addButton" runat="server">Add TextBox</asp:LinkButton>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</form>
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
</body>
i have one Textbox shown on the page, which should shows only one values when no dynamic Textbox is created. My C# code is
protected void Button1_Click(object sender, EventArgs e)
{
string name = txt1.Text + ",";
if (TextBoxesGroup.Controls.Count > 0)
{
for (int i = 1; i <= TextBoxesGroup.Controls.Count; i++)
{
name += Request.Form["textbox" + i] + ",";
}
}
Label1.Text = name;
}
on asp:button click it should display all the values separated by (,). but it is only showing top 2 values, one of which is asp:Textbox and second is dynamic Textbox,, i want the values of all the Textboxes created dynamically, and when no dynamic textbox is added it should only show the value from asp:textBox... Thanks in Advance
Html input elements created through javascript on the client, are not going to be in TextBoxesGroup.Controls on the server.
Changes in the client DOM structure have no effect on the Page's Control tree. The only thing affected will be the content of HttpRequest during postback. One way to know how many dynamically created input elements contributed to Request.Form data is to pass this information as part of the request. This is why you will have to go with the hidden field suggestion. The hidden field value will bring back the count of client-side inputs. You have to set it in javascript every time you create a new input, read it in server-side code, convert to integer and use in your for loop.
Add
<asp:HiddenField runat="server" ID="txtDynamicCount" value="0" />
to the the markup inside form tag.
In javascript click event after counter++; line add
$("#txtDynamicCount").val(counter);
In Button1_Click:
int count;
if (!int.TryParse(txtDynamicCount.Value, out count))
count = 0;
for (int i = 1; i <= count; i++)
{
...
}
The important difference from the other answer is that textboxes (input elements) will not persist between form submits.
You cannot populate server controls in client side. Instead, you want to populate them from server. Here is the sample -
<asp:PlaceHolder runat="server" ID="PlaceHolder1"></asp:PlaceHolder>
<asp:LinkButton ID="addButton" runat="server" OnClick="btnAdd_Click">Add TextBox</asp:LinkButton>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /><br/>
Posted Results: <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
private List<int> _controlIds;
private List<int> ControlIds
{
get
{
if (_controlIds == null)
{
if (ViewState["ControlIds"] != null)
_controlIds = (List<int>)ViewState["ControlIds"];
else
_controlIds = new List<int>();
}
return _controlIds;
}
set { ViewState["ControlIds"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
foreach (int id in ControlIds)
{
var textbox = new TextBox();
textbox.ID = id.ToString();
PlaceHolder1.Controls.Add(textbox);
}
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
var reqs = ControlIds;
int id = ControlIds.Count + 1;
reqs.Add(id);
ControlIds = reqs;
var textbox = new TextBox();
textbox.ID = id.ToString();
PlaceHolder1.Controls.Add(textbox);
}
protected void Button1_Click(object sender, EventArgs e)
{
var ids = ControlIds;
foreach (var id in ids)
{
var textbox = (TextBox)PlaceHolder1.FindControl(id.ToString());
Label1.Text += textbox.Text + ", ";
}
}