check/uncheckbox in gridview tracking - asp.net

i have a below gridview control with a checkbox on it, so my question is when i hit on save button i able to find the checkbox which have been checked and till here no problem, but the problem started when the user tries to uncheck the checkedbox so how would i track the changes and save it into the db that has been checked. anyhelp?
List<Employee> result = new List<Employee>();
long Id = (long)Session["Id"];
result = Employee.GetEmployeeById(Id);
foreach (GridViewRow row in gv.Rows)
{
CheckBox chkBox = row.FindControl("chkSelected") as CheckBox;
if (c != null)
{
if (result.Count > 0)
{
foreach (Employee item in result)
{
Label Id = row.FindControl("lblId") as Label;
if (Id.Text == item.Id.ToString())
{
chkBox.Checked = true;
}
else
{
chkBox.Checked = false;
}
}
}
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="chkSelected" runat="server" Checked="false"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateField>

<script language="javascript" type="text/javascript">
function SelectAll(cb)
{
var gvVar = document.getElementById("<%= gv.ClientID %>");
var cell;
if (gvVar.rows.length > 0)
{
for (i=1; i<gvVar.rows.length; i++)
{
cell = gvVar.rows[i].cells[0];
for (j=0; j<cell.childNodes.length; j++)
{
if (cell.childNodes[j].type =="checkbox")
{
cell.childNodes[j].checked = document.getElementById(cb).checked;
}
}
}
}
}
//--------------------------------------------------------------------------------------------.
function Select(cb)
{
var total = parseInt('<%= this.gv.Rows.Count %>');
var counter=0;
var cbSelectAll=document.getElementById(cb);
var gvVar = document.getElementById("<%= gv.ClientID %>");
var cell;
if (gvVar.rows.length > 0)
{
for (i=1; i<gvVar.rows.length; i++)
{
cell = gvVar.rows[i].cells[0];
for (j=0; j<cell.childNodes.length; j++)
{
if (cell.childNodes[j].type =="checkbox")
{
if(cell.childNodes[j].checked)
counter++;
else
counter--;
}
}
}
}
if(counter==total)
cbSelectAll.checked=true;
else if(counter<total)
cbSelectAll.checked=false;
}
</script>
//----------------------------------------------------------------------------------------
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && (e.Row.RowState == DataControlRowState.Normal || e.Row.RowState == DataControlRowState.Alternate))
{
CheckBox cbSelect = (CheckBox)e.Row.Cells[0].FindControl("cbSelect");
CheckBox cbSelectAll = (CheckBox)this.gv.HeaderRow.FindControl("cbSelectAll");
cbSelect.Attributes.Add("onclick", "javascript:Select('" + cbSelectAll.ClientID + "')");
cbSelectAll.Attributes.Add("onclick", "javascript:SelectAll('" + cbSelectAll.ClientID + "')");
}
}

Yes, store the original value in a hidden field. If always starting with false, you could use JavaScript to set the hidden value to true when the user clicked the checkbox. Using JQuery, you could do:
<asp:TemplateField HeaderText="Select" ItemStyle-CssClass="Checked">
<ItemTemplate>
<asp:CheckBox ID="chkSelected" runat="server" Checked="false"></asp:CheckBox>
<asp:HiddenField iD="dh" runat="server" />
</ItemTemplate>
</asp:TemplateField>
$("#<%= Grid.ClientID %>").find(".Checked > :checkbox").each(function() {
$(this).siblings("input[type='hidden']").attr("value", "True");
});
Something like that. On Server side, parse the value and if true, then you know it changed.
HTH.

It may not be the brightest idea, but you can query the database for the current state, and the compare with what you have got from the web page during a postback button click, or something like that. Or you can go with Brians answer.
It is possible to persist a list of objects into the Viewstate and access it in a consequent postback. The only thing is that the object you are trying to persist must be defined as serializable.
Update:
The ViewState approach
I feel this may be suitable for your need, and it requires a bit of linq. You'd need to create a class as follows:
[Serializable()]
public class OptionState
{
//the id of the item
int ID {get;set;}
//state of the checkbox
bool Checked {get;set;}
}
Note the Serializable attribute. This is required for the instance to persist to the viewstate.
Add the list of options to the viewstate:
var lstOptions = (from x in <your_option_store>
select new OptionState{ID = x.ID, Checked = x.Checked}).ToList();
ViewState.Add("options", lstOptions);
Here is a bit of code that should go into your button click:
foreach(GridViewRow row in gvOptions.Rows)
{
//not writing the bit of code
//which gets the ID and the
//state of checkbox of
//the gridview row being processed
OptionState currentState = GetOptionStateObjectFromRow(row);
List<OptionState> lstStates = (List<OptionState>) ViewState["options"];
OptionState originalState = lstStates.FirstOrDefault(x => x.ID == currentState.ID);
if(currentState.Checked != originalState.Checked)
{
//the appropriate db call needs to be done here.
}
}

Related

How to disable some checkboxes of checkboxlist based on database value in asp.net?

I have a checkboxlist which has 26 values getting filled from database.
<asp:CheckBoxList ID="chkList1" runat="server" RepeatColumns="3" RepeatDirection="Horizontal" Width="100%" DataTextField="Name" DataValueField="ID" AutoPostBack="True" Visible="false" OnSelectedIndexChanged="chkList1_SelectedIndexChanged">
</asp:CheckBoxList>
public QueSet()
{
SqlConnection conn = new SqlConnection(Settings.DatabaseConnectionString);
try
{
conn.Open();
SqlCommand com = new SqlCommand("sp_SelectQueSet",conn);
com.CommandType = CommandType.StoredProcedure;
SqlDataAdapter sa = new SqlDataAdapter(com);
DataSet ds = new DataSet();
sa.Fill(ds);
if(ds.Tables.Count > 0)
{this.Data = ds.Tables[0];}
}
catch(Exception ex)
{
throw new ApplicationException(ex.Message);
}
finally
{conn.Close();}
}
QueSet q = new QueSet();
chkList1.DataSource = q.Data;
chkList1.DataBind();
Based on above code, the checkboxlist gets data from database. One of the values from the database is "Nothing" with ID 51.
I want to disable all the other checkboxes if user selects "Nothing" value.
protected void chkList1_SelectedIndexChanged(object sender, EventArgs e)
{
//what should I do here?
}
This can be easly achived by Client Script, Server SelectedIndexChanged is not required. do the steps as follows
Remove AutoPostback = "true" and OnSelectedIndexChanged="..." from
your CheckboxList control and Add the property CssClass ="CHKList"
Attach jQuery.js , say jQuery-1.7 or latest version
Add the following code in ASPX Page. This will disable all checkboxes when anyone of check box is clicked and Enable back if unchecked
<script>
$(document).ready(function () {
$(".CHKList input:checkbox").click(function () {
if ($(this).prop("checked") == true) {
$(".CHKList input:checkbox").prop("disabled", true);//older version of jQuery prop will not work , use attr("disabled","disabled");
$(this).prop("disabled", false);
}
else {
$(".CHKList input:checkbox").prop("disabled", false);
}
});
});
</script>
First set data source to checkboxlist as your are doing
Then try this (Not tested, sorry for that)
for (int i = 0; i < chkList.Items.Count; i++)
{
if (Chkboxlist.Items[i].Value == "SomeValue")
{
Chkboxlist.Items[i].Enabled = false;
}
}

How to get the status of massive controls created dynamicly in asp.net

I am a greener in asp.net and trying to implement a use case which describes the process of user's choosing and booking a seat in Online Movie Booking System recently.
Now I have created massive seat controls, web user controls which is defined on the basis of the ImageButton, and a 'Submit' button.
These seat controls, seem to work well. The status of seats reflected by the picture within them can change as you clicked them. In the click event of 'Submit' button, I attempt to gather their states with their IDs but those states all are the same as those in the database, which means the status of these controls did not changed.
So, what should I do to get the current status of those controls when I click the 'Submit' button? Any idea would appreciate!
Seat.ascx
public partial class Seat : System.Web.UI.UserControl
{
private string[] Images = { "~/picture/SeatStatus/Default.png", "~/picture/SeatStatus/Chosen.png", "~/picture/SeatStatus/Unavailable.png" };
public string ImageLoc
{
get
{
return this.SeatControl.ImageUrl;
}
set
{
this.SeatControl.ImageUrl = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
if (ImageLoc == Images[0])
{
ImageLoc = Images[1];//switch to chosen state
}
else if (ImageLoc == Images[1] )
{
ImageLoc = Images[0]; //switch to available state
}
else
{
//Can not be chosen
}
}
}
ChooseSeat.aspx
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Table ID="SeatTable" runat="server">
</asp:Table>
</ContentTemplate>
</asp:UpdatePanel>
</div>
<div>
<asp:Button ID="Button1" runat="server" text="Submit" OnClick="Unnamed_Click" />
</div>
CreateControl
TableRow Row = new TableRow();
Row.ID = "Row" + RowNum.ToString();
for (int i = 0; i < str.Length; i++)
{
TableCell Cell;
//'0' represent available, '1' means the seat has been choosen , '2' //stands for unavailable
if (str[i] == '0' || str[i] == '1' || str[i] == '2')
{
Cell = new TableCell();
ColNum++;
Cell.ID = "Row" + RowNum.ToString() + "Cell" + ColNum.ToString();
Seat seat = (Seat)LoadControl("~/Seat.ascx");
seat.ID = "Seat" + Cell.ID;
seat.ID = string.Format("{0}", i);
seat.ImageLoc = Images[str[i] - '0'];
Cell.Controls.Add(seat);
Row.Cells.Add(Cell);
}
else if (str[i] == '3')//3 means passageway
{
Cell = new TableCell();
Cell.ID = "Label" + "Row" + RowNum.ToString() + "Cell" + ColNum.ToString();
Label label = new Label();
label.ID = "Ocup" + Cell.ID;
Cell.Controls.Add(label);
Row.Cells.Add(Cell);
}
else if (str[i] == '-')//'-' means next row
{
SeatTable.Rows.Add(Row);
Row = new TableRow();
RowNum++;
Row.ID = "Row" + RowNum.ToString();
}
else
{
SeatTable.Rows.Add(Row);
break;
}
}

Radio button is not functioning

I'm having problem with my radio button in my gridview. I want to select any row one by one so that I can perform UPDATE, DELETE, and DISPLAY the row. When I select the button, the page will be refreshed and the button I selected before is not selected anymore. So I can't click any menu to update, delete or display the row. I noticed this is happening when I set the Autopostback = "True".
How can I solve it? Any idea? Below are my codes:
Page:
<script language="javascript" type="text/javascript">
function radiobtn(id) {
var rdBtn = document.getElementById(id);
var List = document.getElementsByTagName("input");
for (i = 0; i < List.length; i++) {
if (List[i].type == "radio" && List[i].id != rdBtn.id) {
List[i].checked = false;
}
}
}
</script>
<asp:RadioButton ID="CheckDel" runat="server" onclick="javascript:radiobtn(this.id)" OnCheckedChanged="CheckDel_CheckedChanged"
AutoPostBack="True" />
server end:
protected void CheckDel_CheckedChanged(object sender, EventArgs e)
{
CheckBox chkStatus = (CheckBox)sender;
GridViewRow row = (GridViewRow)chkStatus.NamingContainer;
Session["datestart"] = row.Cells[1].Text;
Session["empid"] = row.Cells[2].Text;
Session["empname"] = row.Cells[3].Text;
Session["days"] = row.Cells[4].Text;
Session["leavetype"] = row.Cells[5].Text;
Session["leavestatus"] = row.Cells[6].Text;
bool status = chkStatus.Checked;
}
Do look at the following url http://www.asp.net/web-forms/tutorials/data-access/enhancing-the-gridview/adding-a-gridview-column-of-radio-buttons-cs
Look at section "Using a Literal Control to Inject Radio Button Markup" for more info

Dynamically dropping grid columns - effect on postbacks

I have read a number of threads here on the subject of posting back data from dynamically added datagrid columns. Everything I've read says that since the columns were added after the Init phase, they are not available in the control collection upon Postback and therefore any data posted back by these dynamically added columns is not available and cannot be restored from ViewState unless they are re-created in Page_Init. I have read that as long as the controls are re-added with identical IDS ( i.e IDS should match match posted back control ids), they will be restored from ViewState.
What if I'm not dynamically adding grid columns but rather dropping some grid columns in the code behind. So the ID's of the columns that remmin should match what was in the control collection to begin with so any data posted back should be resotored right but this is not what I'm seeing. SUppos the following is the list of columns in my ASPX page. If in my code behind I drop the "Test" column but check the checkbox in the first column. Upon postback, the checkbox selection is not maintained. I would have expected it to based on what I've read. Can someone correct my understanding on this?
<Columns>
<asp:TemplateColumn headertext="" headerstyle-width="1%" itemstyle-horizontalalign="center" FooterStyle-CssClass="DataGridFooter" FooterStyle-HorizontalAlign="Center" FooterStyle-VerticalAlign="Top">
<HeaderTemplate>
<input id="checkAll" type="checkbox" onclick="CheckAllDataGridCheckBoxes('checkboxIsSelected',this.checked)"/>
</HeaderTemplate>
<itemtemplate>
<asp:CheckBox runat="server" id="checkboxIsSelected" checked='false' />
</itemtemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Subject" HeaderStyle-Width="10%" Visible="TRUE" ItemStyle-HorizontalAlign="Center" FooterStyle-CssClass="DataGridFooter" FooterStyle-HorizontalAlign="Center" FooterStyle-VerticalAlign="Top" >
<ItemTemplate>
<asp:Label id="labelSubjectID" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "SubjectID") %>' />
</ItemTemplate>
</asp:TemplateColumn>
<asp:TemplateColumn HeaderText="Test" HeaderStyle-Width="5%" Visible="TRUE" ItemStyle-HorizontalAlign="Center" FooterStyle-CssClass="DataGridFooter" FooterStyle-HorizontalAlign="Center" FooterStyle-VerticalAlign="Top" >
<ItemTemplate>
<asp:Label id="labelTestCode" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "TestCode") %>' />
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
Added BindGrid() and the event handler buttonApprove_click. The method SetGridColumns is the one that drops grid columns. Have included that too.
private void BindGrid()
{
try
{
SetMasterDetailControlStates(IsPageInDetailsMode());
if (!ValidateArgs())
{
gridBias.Visible = false;
return;
}
foreach (ListItem displayOption in chkboxDisplay.Items)
{
if (displayOption.Selected)
{
if (displayOption.Value == "Highlight") { _showHighlighting = true; }
}
}
/*
<Snipped>...Make procedure call to get dataset
*/
DataSet ds = sp.GetDataSet();
if (sp.RC != (int)ReturnCode.SUCCESS)
{
if ((sp.RC == (int)ReturnCode.NO_RECORDS_RETURNED))
{
labelMessage.Text = "No data found for the specified filter";
}
else if ((sp.RC == (int)ReturnCode.UNHANDLED_EXCEPTION) || (ds == null))
{
labelMessage.Text = sp.ErrorMessage;
}
ds = null;
gridBias.DataSource = ds;
EnableControls(false);
SetGridColumns();
}
else
{
gridBias.TitleText = BuildGridTitleString();
gridBias.FilterText = BuildGridFilterString();
gridBias.EnableRowsPerPageEdit = true;
SetGridColumns();
//Since grid columns are dynamically added and can change between postbacks
//make sure sort column is valid, if not unset
if (gridBias.SortColumn != null && gridBias.SortColumn.Length > 0)
{
bool foundCol = false;
foreach (DataGridColumn dg in gridBias.Columns)
{
if (gridBias.SortColumn == dg.SortExpression)
{
foundCol = true;
break;
}
}
if (!foundCol)
{
gridBias.SortColumn = "";
gridBias.SortOrder = "";
}
}
if (gridBias.SortColumn.Length == 0) gridBias.SortColumn = "TestCode";
if (gridBias.SortOrder.Length == 0) gridBias.SortOrder = "ASC";
if (gridBias.PageIndex.Length != 0 &&
!gridBias.GridViewMode.Equals(CustomDataGrid.GridViewType.SHOWALL.ToString()))
gridBias.CurrentPageIndex = Convert.ToInt32(gridBias.PageIndex);
ds.Tables[0].DefaultView.Sort = gridBias.SortColumn + " " + gridBias.SortOrder;
gridBias.DataSource = ds.Tables[0].DefaultView;
EnableControls(true);
}
gridBias.HideEmptyColumns = true;
ArrayList cols = new ArrayList();
cols.AddRange(_alRecheckColumns);
gridBias.HideEmptyColumnsList = cols;
gridBias.DataBind();
}
catch (Exception ex)
{
CodeLibrary.ErrorHandling.SetLabel("Error(" + CodeLibrary.ErrorHandling.GetMethodName() + ")", ex.Message, labelMessage, true, "ErrorMsg");
}
}
private void SetGridColumns()
{
ArrayList alCols = new ArrayList();
alCols.Add(""); //Checkbox column
alCols.Add("Subject");
ArrayList alColumnsToBeDeleted = new ArrayList();
Boolean boolColExists = false;
foreach (ListItem chart in chkboxChartType.Items)
{
if (chart.Value == "%Bias")
{
if (rblBiasOptions.SelectedValue == "Subject")
{
foreach (DataGridColumn dg in gridBias.Columns)
{
boolColExists = false;
foreach (string gridColumn in alCols)
{
if (dg.HeaderText == gridColumn)
{
boolColExists = true;
break;
}
}
if (!boolColExists)
{
alColumnsToBeDeleted.Add(gridBias.Columns.IndexOf(dg));
}
}
}
}
// Loop thru the array list and delete columns from the grid.
int count = 0;
foreach (int i in alColumnsToBeDeleted)
{
gridBias.Columns.RemoveAt(i - count); //Subtract index by columns already deleted.
count++;
}
}
protected void buttonApprove_Click(object sender, EventArgs e)
{
try
{
CheckPermission(this.ModuleId, this.GetType().BaseType.ToString(), "buttonApprove_Click");
foreach (DataGridItem i in gridBias.Items)
{
//Loop thru each row and determien values to be saved to DB
if (i.ItemType == ListItemType.Item || i.ItemType == ListItemType.AlternatingItem)
{
bool cbSelected = ((CheckBox)i.FindControl("checkboxIsSelected")).Checked;
if (cbSelected)
{
bool IsApproved = true;
string strSubjectID = ((System.Web.UI.WebControls.Label)i.FindControl("labelSubjectID")).Text;
string strTestCode = ((System.Web.UI.WebControls.Label)i.FindControl("labelTestCode")).Text;
string strSampleType = ((System.Web.UI.WebControls.Label)i.FindControl("labelSampleType")).Text;
string strTestCodeAndType = ((System.Web.UI.WebControls.Label)i.FindControl("labelTestCodeAndType")).Text;
if (((System.Web.UI.WebControls.Label)i.FindControl("labelRecheckNeedsApproval")).Text == "1")
IsApproved = true;
else
IsApproved = false;
SaveToDB(strSubjectID, strTestCode, strSampleType, strTestCodeAndType,IsApproved);
}
}
}
BindGrid();
}
catch (Exception exceptionObject)
{
string strExceptionMessage = exceptionObject.Message + "-" + exceptionObject.InnerException.Message;
CodeLibrary.ErrorHandling.SetLabel("", strExceptionMessage, labelMessage, false, "ErrorMsg"); //--- Set label text
}
}

How do i maintain the state of my Html Controls on postback with JQuery and JSON?

I have a form with a collection of Html and ASP Server Controls. Im using JSON to preload some drop-down lists.
I want to maintain the states of these drop-down lists on postback. Im quite new to JSON, can anyone help?
If you can use HTML select element instead. Thus, you can get the selected value of select element on the server and register an hidden field to maintain the value. While you are loading the items so you can check the registered hidden field to retrieve the previous selected value.
<select id="DropDownList1" name="DropDownList1" />
<asp:Button ID="Button1" runat="server" Text="Button" />
<script type="text/javascript">
var sv = document.getElementById("SelectedValue");
var v = (sv != null && sv.value != "" ? sv.value : null);
var o = document.getElementById("DropDownList1");
for (var i = 0; i < 10; i++) {
var item = document.createElement("option");
item.innerHTML = "item" + i;
item.setAttribute("value", "item" + i);
if (("item" + i) == v)
item.setAttribute("selected", "selected");
o.appendChild(item);
}
</script>
protected void Page_Load(object sender, EventArgs e)
{
string selectedValue = Request["DropDownList1"];
if (!string.IsNullOrEmpty(selectedValue))
Page.ClientScript.RegisterHiddenField("SelectedValue", selectedValue);
}
firstly, you should create an HTTPHandler to generate the JSON and get it using getJSON method from jQuery. Lastly, you have to get the selected value on the Load event of the page and maintain the value to a HiddenField for the next time. The following code demonstares it.
public class JsonGenerator : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
JavaScriptSerializer ser = new JavaScriptSerializer();
context.Response.Write(ser.Serialize(new object[]
{
new { Text = "Item1", Value = 1 },
new { Text = "Item2", Value = 2 } ,
new { Text = "Item3", Value = 3 }
}));
}
public bool IsReusable
{
get
{
return false;
}
}
}
<select id="DropDownList1" name="DropDownList1" />
<asp:Button ID="Button1" runat="server" Text="Button" />
<script src="jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
$.getJSON("JsonGenerator.ashx",
null,
function(r) {
var ddl = $("#DropDownList1"), hf = $("#SelectedValue");
$.each(r, function(k, v) {
ddl.append("<option value='" + v.Value + "'>" + v.Text + "</option>");
});
if (hf.length > 0)
ddl.children("[value='" + hf.val() + "']").attr("selected", "selected");
});
});
</script>
protected void Page_Load(object sender, EventArgs e)
{
string selectedValue = Request["DropDownList1"];
if (!string.IsNullOrEmpty(selectedValue))
Page.ClientScript.RegisterHiddenField("SelectedValue", selectedValue);
}
Don't let the browser do the post, do it yourself with jQuery. On the callback replace a results div with the returned html.
Assuming you've marked your form with class="ajaxform" and your results div with id="results" then something like this (not fully tested)...
// Submit form.ajaxform
// Get the returned html, and get the contents of #results and
// put it into this page into #results
var submit = function() {
$.ajax({
type: "POST",
data: $("form.ajaxform").serialize(),
success: function(data, textStatus) {
$("#results").replaceWith($("#results", $(data)));
}
});
};
$("form.ajaxform input[type=submit]").click(submit);
// I think you'll need this as well to make sure the form doesn't submit via the browser
$("form.ajaxform").submit(function () { return false; });

Resources