Default selection of header and item checkboxes in gridview in asp.net - asp.net

I have gridview with header and item checkboxes.when i select header checkbox my code able to select all item checkboxes.when i un select header checkbox my code able to un select all item checkboxes.
Here my issue is when my page is loading(means when grid is loading first time) by default the header and item checkboxes should be selected.how can we do this.

Use RowDataBound Event in Gridview
protected void GridViewName_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row .RowType == DataControlRowType .DataRow )
{
//Your Code
}
}

In grid view columns write like this
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkhead" runat="server" onclick="SelectAllCheckboxes(this)" ClientIDMode="Static" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chksub" runat="server" ClientIDMode="Static" />
</ItemTemplate>
</asp:TemplateField>
After that write the Java script function SelectAllCheckboxes
// select all check boxes
function SelectAllCheckboxes(spanChk) {
// Added as ASPX uses SPAN for checkbox
var oItem = spanChk.children;
var theBox = (spanChk.type == "checkbox") ?
spanChk : spanChk.children.item[0];
xState = theBox.checked;
elm = theBox.form.elements;
for (i = 0; i < elm.length; i++)
if (elm[i].type == "checkbox" && elm[i].id != theBox.id) {
//elm[i].click();
if (!elm[i].disabled) {
if (elm[i].checked != xState)
elm[i].click();
}
//elm[i].checked=xState;
}
}
After write the .cs page load event first bind the grid view and chheader.checked=true;

Related

How to disable first checkbox after other one clicked in repeater

I have a repeater and there is a checkbox. When I click first one in checkedchanged event row information appear down below. But after first click I have a trouble. Sometimes informations are same. Because foreach always see the first click. For instance, I checked second one and I saw the informations. Then I click second one ok again I saw the informations, but this time I clicked again first one. Foreach can take first checkbox and the last one still checked before postback it's again doing second one's operation.
Is there any way to fix this?
Here is my sample code.
<asp:Repeater ID="rptInformations" runat="server">
<ItemTemplate>
<asp:CheckBox ID="ckChoose" runat="server" OnCheckedChanged="ckChoose_CheckedChanged" AutoPostBack="true" />
<div id="foo" runat="server"> ... some basic titles ...</div>
</ItemTemplate>
<asp:Repeater>
<div id="info" runat="server"> ... informations in here (textboxes, labels ..etc)</div>
CodeBehind:
foreach (RepeaterItem item in rptInformations.Items)
{
//CheckBox ckChoose= (CheckBox)sender;
CheckBox ckChoose= item.FindControl("ckChoose") as CheckBox;
if (cBoxChoose.Checked)
{
... database process ...
}
}
As for what I understand you are trying to trigger an event everytime you check the checkbox and it will show certain info according to the row of the repeater it belongs to, for this I have made this example on a page called Repeater.aspx, using an event that will only fire for one checkbox and not for all:
Repeater.aspx:
<asp:Repeater runat="server" ID="repeater">
<ItemTemplate>
<asp:CheckBox ID="ckChoose" runat="server" AutoPostBack="true" OnCheckedChanged="ckChoose_CheckedChanged"/>
<div id="foo" runat="server"> <%# Eval("Field2")%></div>
</ItemTemplate>
</asp:Repeater>
<div id="info" runat="server"> ... informations in here (textboxes, labels ..etc)</div>
Repeater.aspx.cs (Codebehind):
partial class Repeater1 : System.Web.UI.Page
{
private System.Collections.Generic.List<Item> Elements()
{
Generic.List<Item> itemList = new Generic.List<Item>();
itemList.Add(new Item("1", "One"));
itemList.Add(new Item("2", "Two"));
return itemList;
}
protected void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack) {
this.repeater.DataSource = this.Elements();
this.repeater.DataBind();
}
}
protected void ckChoose_CheckedChanged(object sender, System.EventArgs e)
{
CheckBox chk = (CheckBox)sender;
this.info.InnerHtml = "checkbox:" + chk.ID + " foo:" + ((HtmlGenericControl)chk.Parent.FindControl("foo")).InnerText;
}
}
Hope this helps.
I guess I fix it with namingcontainer. It works perfect.
foreach (RepeaterItem item in Repeater1.Items)
{
CheckBox cBoxx = item.FindControl("ckChoose") as CheckBox;
current_cbId = cBoxx.NamingContainer.UniqueID.ToString();
if (cBoxx.Checked)
{
... some operations ...
}
if (cBoxChoose.NamingContainer.UniqueID.ToString() != current_cbId)
cBoxChoose.Checked = false;
}

Why do I have to click a button twice in an ASP.NET repeater to get the command to fire?

I have an ASP.NET page with the following 3 main areas:
1 - list of checkboxes on the left for fitlering results
2 - Repeater that displays the matching results in the middle (with a button for each item)
3 - Repeater that displays the selected items on the right
On initial page load the page will show the data bound checkboxes and will show all results (since nothing has been checked in the filters). As the user checks or unchecks the checkboxes, the page will reload and the matching results will change. So far this part works great.
In the Results Repeater, each item has a Button. When the user clicks the button for an item in the Results the idea is that the item will get added to the Selected Repeater on the right. What is happening is that after I check or uncheck filter checkboxes - the first time that I then try and click on the buttons in the Results repeater, nothing happens. The page just reloads. Then if I click the button a second time, the Repeater Command will fire and the item will get added to the Repeater on the right hand side. Then, as long as I don't change any of the checkboxes I can click on one of the command buttons and it will work right away. But if I check one of the checkboxes in the filters area (which causes the Results to get re-bound) then I have to click one of the buttons twice to get it to fire.
I have a sense that this has something to do with ViewState but I have no idea. Does anyone know why this would be happening?
Below is my code for both the ASPX page and the code behind.
ASPX Code:
<h3>Filters</h3>
<asp:Repeater ID="rptTechnologies" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Technology</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptVerticals" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Vertical</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptIndustries" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Industry</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<asp:Repeater ID="rptSolutions" runat="server" OnItemDataBound="rptFacet_ItemDataBound">
<HeaderTemplate><h4>Solution</h4></HeaderTemplate>
<ItemTemplate><asp:CheckBox ID="chkFacet" runat="server" AutoPostBack="true" OnCheckedChanged="chkFacet_Changed" /><br /></ItemTemplate>
</asp:Repeater>
<h3>Results</h3>
<asp:Repeater ID="rptMatchingSlides" runat="server" OnItemDataBound="rptMatchingSlides_ItemDataBound" OnItemCommand="rptMatchingSlides_Command">
<ItemTemplate>
<h4><asp:Literal ID="litName" runat="server"></asp:Literal></h4>
<asp:Button ID="btnSelect" runat="server" Text="Select" CommandName="Select" />
</ItemTemplate>
<SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
<h3>Selected</h3>
<asp:Repeater ID="rptSelectedSlides" runat="server" OnItemDataBound="rptSelectedSlides_ItemDataBound">
<ItemTemplate>
<h4><asp:Literal ID="litName" runat="server"></asp:Literal></h4>
</ItemTemplate>
<SeparatorTemplate><hr /></SeparatorTemplate>
</asp:Repeater>
Here is the code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
this.BindData();
}
}
public List<string> SelectedSlides
{
get
{
if (Session["SelectedIDs"] != null)
{
string[] _ids = Session["SelectedIDs"].ToString().Split(new char[] { '|' });
List<String> _retVal = new List<string>();
foreach (string _id in _ids)
{
_retVal.Add(_id);
}
return _retVal;
}
else
{
return new List<string>();
}
}
set
{
//Set the session value
string _val = "";
foreach (string _id in value)
{
if (_val == "")
{
_val = _id;
}
else
{
_val += "|" + _id;
}
}
Session["SelectedIDs"] = _val;
}
}
protected void BindData()
{
//Filters
rptTechnologies.DataSource = Repository.GetTaxonomyItems();
rptTechnologies.DataBind();
rptVerticals.DataSource = Repository.GetTaxonomyItems();
rptVerticals.DataBind();
rptIndustries.DataSource = Repository.GetTaxonomyItems();
rptIndustries.DataBind();
rptSolutions.DataSource = Repository.GetTaxonomyItems();
rptSolutions.DataBind();
this.BindMatchingSlides();
}
protected void BindMatchingSlides()
{
...build list of ids from checkboxes...
rptMatchingSlides.DataSource = Repository.GetMatchingSlides(_selectedIDs);
rptMatchingSlides.DataBind();
}
protected void BindSelectedSlides()
{
if (this.SelectedSlides.Count > 0)
{
rptSelectedSlides.DataSource = this.SelectedSlides;
rptSelectedSlides.DataBind();
}
else
{
divSelectedSlides.Visible = false;
}
}
protected void rptMatchingSlides_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Literal _litName = (Literal)e.Item.FindControl("litName");
Button _btnSelect = (Button)e.Item.FindControl("btnSelect");
_litName.Text = ...set name here...
_btnSelect.CommandArgument = ...use unique ID of item from database...
_btnSelect.ID = "btnSelect_" + e.Item.ItemIndex;
}
}
protected void rptMatchingSlides_Command(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandName == "Select")
{
Item _slide = ...get data from database based on Command Argument...
if (_slide != null)
{
List<string> _selectedSlides = this.SelectedSlides;
_selectedSlides.Add(_slide.ID.ToString());
this.SelectedSlides = _selectedSlides;
}
this.BindSelectedSlides();
}
}
Thanks to Jeremy - removing the line of code where I was setting the ID fixed it. Doh! Somewhere else I had read that you needed to set a unique value for the IDs of the buttons in a repeater. So that must have been the culprit. Thanks to Jeremy.

How bind Checklistbox inside repeater control having datasource as LINQ

i my website i am using Repeater control which further contain checkboxlist control.
Now my problem is that i have successfully bind "Parameter Type" in repeater control but when i am binding checkbox values, it does't appears in display
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<h4>
<%#Container.DataItem%></h4>
<asp:CheckBoxList ID="chkParList" runat="server" RepeatDirection="Horizontal"
DataTextField = >
</asp:CheckBoxList>
<br /><br />
</ItemTemplate>
<SeparatorTemplate>
<hr />
</SeparatorTemplate>
</asp:Repeater>
In *.cs file following are my code
IMonitoringDataInfo objMonitoringDataInfo = new ChannelFactory<IMonitoringDataInfo>("MonitoringDataInfo").CreateChannel();
Collection<ParameterDetailDTO> clParameterDetailDTO = objMonitoringDataInfo.GetAllParameters(idList, out errorCode);
var parameters = (from resx in clParameterDetailDTO
select resx.ParameterType).Distinct();
Repeater1.DataSource = parameters.ToList();
Repeater1.DataBind();
counter = Repeater1.Items.Count;
while (i < counter - 1)
{
foreach (var parType in parameters)
{
var items = from resx in clParameterDetailDTO
where resx.ParameterType.ToLower().Contains(parType.ToLower())
select new { resx.ParameterName, resx.ParameterID };
((CheckBoxList)(Repeater1.Items[i].FindControl("chkParList"))).DataSource = items;
((CheckBoxList)(Repeater1.Items[i].FindControl("chkParList"))).DataTextField = "ParameterName";
((CheckBoxList)(Repeater1.Items[i].FindControl("chkParList"))).DataValueField = "ParameterID";
((CheckBoxList)(Repeater1.Items[i].FindControl("chkParList"))).DataBind();
}
i++;
}
I am using LINQ as datasource
Please help?
add OnItemDataBound event to Repeater :
<asp:Repeater ID="Repeater1" OnItemDataBound="Repeater1_ItemDataBound" runat="server">
then in code behind do something like this :
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var parameters = (from resx in clParameterDetailDTO
select resx.ParameterType).Distinct();
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
CheckBoxList chkParList = (e.Item.FindControl("chkParList") as CheckBoxList);
chkParList.DataSource = parameters.ToList();
chkParList.DataTextField = "ParameterName";
chkParList.DataValueField = "ParameterID";
chkParList.DataBind();
}
}
Try putting your CheckBoxList binding inside the ItemDataBound event of the repeater.
See:
Repeater.ItemDataBound Event
Using OnItemDataBound with Repeater in ASP.NET and C#

GridView FindControl returns null when HeaderText is set

I have a GridView...
<asp:GridView EnableViewState="true"
ID="grdResults"
runat="server"
CssClass="resultsGrid"
OnRowDataBound="grdResults_OnRowDataBound"
AutoGenerateColumns="false"
HeaderStyle-CssClass="header"
OnRowCommand="grdResults_OnRowCommand">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblView"
runat="server"
Visible="false"
Text="View">
</asp:Label>
<asp:HyperLink ID="hypEdit"
runat="server"
Visible="false"
Text="(Edit)"
CssClass="edit">
</asp:HyperLink>
<asp:LinkButton ID="btnDelete"
runat="server"
Visible="false"
Text="(Delete)"
CssClass="delete"
CommandName="DeleteItem"
OnClientClick="return confirm('Are you sure you want to delete?')">
</asp:LinkButton>
<asp:HyperLink ID="hypSelect"
runat="server"
Visible="false"
Text="(Select)"
CssClass="select">
</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
This has one static column containing a label two hyperlinks and a link button and also has a number of dynamically generated columns...
private void SetupColumnStructure(IEnumerable<string> columnNames)
{
var columnNumber = 0;
foreach (var columnName in columnNames)
{
var templateColumn = new TemplateField
{
ItemTemplate = new CellTemplate(columnName)
};
grdResults.Columns.Insert(columnNumber, templateColumn);
columnNumber++;
}
}
As part of the OnRowDataBound handler I retrieve one of the controls in the statically column and set some attributes on it...
protected void grdResults_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
.
.
.
var row = e.Row;
var rowData = row.DataItem as Dictionary<string, object>;
if (rowData != null)
{
if ((bool)rowData[displayEditLink])
{
var hypEdit = (HyperLink)row.FindControl("hypEdit");
hypEdit.NavigateUrl = "~/Pages/Edit.aspx?action=Edit&objectType=" + rowData[objectTypeLiteral] + "&id=" + rowData[objectIdLiteral];
hypEdit.Visible = true;
}
}
.
.
.
}
This all works fine but no column names are displayed. So I then modify the SetupColumnStructure method so that the HeaderText is set on the template field like this...
private void SetupColumnStructure(IEnumerable<string> columnNames)
{
var columnNumber = 0;
foreach (var columnName in columnNames)
{
var templateColumn = new TemplateField
{
ItemTemplate = new CellTemplate(columnName),
HeaderText = columnName
};
grdResults.Columns.Insert(columnNumber, templateColumn);
columnNumber++;
}
}
For some reason this one extra line change causes the row.FindControl("hypEdit"); call in the OnRowDataBound handler to return null.Can anyone see something im missing here or has anyone experienced a similar issue?
UPDATE
I've made sure that I'm not referring to a header or footer row here. Also, if I step over the object reference exception this occurs for every item that is in the DataSource.
Not sure if this helps, but as I expected, when I stepped through the code the table has generated all the columns expected but all cells (DataControlFieldCells) contain no controls when the HeaderText is set, yet all expected controls when it isnt set.
All very strange. Let me know if you can spot anything else.
When you added the HeaderText, a new RowType was added to the gridview. You'll need to check what type of row raised the OnRowDataBound event and take the appropriate action. In your case, just checking if the e.Row.RowType is a DataRow should solve your problem:
protected void grdResults_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
if ((bool)rowData[displayEditLink])
{
var hypEdit = (HyperLink)row.FindControl("hypEdit");
hypEdit.NavigateUrl = "~/Pages/Edit.aspx?action=Edit&objectType=" + rowData[objectTypeLiteral] + "&id=" + rowData[objectIdLiteral];
hypEdit.Visible = true;
}
}
}
Its because the control you are searching for is contained within another control. FindControl() does not look inside control collections of controls. You will need to write a recursiveFindControl() method.
Hope this helps a little!

Get GridView selected row DataKey in Javascript

I have GridView which I can select a row. I then have a button above the grid called Edit which the user can click to popup a window and edit the selected row. So the button will have Javascript code behind it along the lines of
function editRecord()
{
var gridView = document.getElementById("<%= GridView.ClientID %>");
var id = // somehow get the id here ???
window.open("edit.aspx?id=" + id);
}
The question is how do I retrieve the selected records ID in javascript?
I worked it out based on JasonS response. What I did was create a hidden field in the Grid View like this:
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:HiddenField ID="hdID" runat="server" Value='<%# Eval("JobID") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField Visible="False">
<ItemTemplate>
<asp:LinkButton ID="lnkSelect" runat="server" CommandName="select" Text="Select" />
</ItemTemplate>
</asp:TemplateField>
Then on the OnRowDataBind have code to set the selected row
protected virtual void Grid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Click to highlight row
Control lnkSelect = e.Row.FindControl("lnkSelect");
if (lnkSelect != null)
{
StringBuilder click = new StringBuilder();
click.AppendLine(m_View.Page.ClientScript.GetPostBackClientHyperlink(lnkSelect, String.Empty));
click.AppendLine(String.Format("onGridViewRowSelected('{0}')", e.Row.RowIndex));
e.Row.Attributes.Add("onclick", click.ToString());
}
}
}
And then in the Javascript I have code like this
<script type="text/javascript">
var selectedRowIndex = null;
function onGridViewRowSelected(rowIndex)
{
selectedRowIndex = rowIndex;
}
function editItem()
{
if (selectedRowIndex == null) return;
var gridView = document.getElementById('<%= GridView1.ClientID %>');
var cell = gridView.rows[parseInt(selectedRowIndex)+1].cells[0];
var hidID = cell.childNodes[0];
window.open('JobTypeEdit.aspx?id=' + hidID.value);
}
</script>
Works a treat :-)
1) change your javascript function to use a parameter
function editRecord(clientId)
{ ....
2) output the call in your editRecord button... if you want to avoid dealing with the .net generated ids, just use a simple
<input type="button" onclick="editRecord(your-rows-client-id-goes-here)" />
Based off of your comments to #DaveK's response, in javascript you can set the id of a hidden field to the clientId of the selected row when the user selects it. Then have your editRecord function use the value set on the hidden form field.
one could avoid javascript altogether, by setting anchor tags pre-populated with the query string for each row (although this will effect your table layout, it will need only one click rather than 2 from the user)
insert in the gridview template:
<asp:HyperLink runat="server" ID="editLink" Target="_blank"
NavigateURL='<%# Eval("JobID","edit.aspx?id={0}") %>'>
Edit..
</asp:HyperLink>

Resources