Select All CheckBoxes in GridView ASP.NET using JQuery - asp.net

I have checkBoxes in my Gridview templete columns called "Category A" and "Category B".
I want Select-All functionality, i.e. when the user checks the Select-All check Box in category A column, all the checkboxes must get checked under that column. Same for Category B.
I am trying with the code below. The problem with my code is, it selects all the check boxes in the entire gridview, "Category A" as well as "Category B"s checkboxes.
But, I want only checkboxes selected under the same column.
function SelectAllCheckboxesA(chk) {
$('#<%=gvSurveys.ClientID %>').find("input:checkbox").each(function() {
if (this != chk) {
if ($(this).hasClass('CatA') != false) {
this.checked = chk.checked;
}
}
else {
alert($(this));
}
});
}
<asp:GridView ID="gvSurveys" runat="server" AutoGenerateColumns="false" AllowSorting="True" Width="1500px">
<Columns>
<asp:TemplateField>
<HeaderTemplate>Category A
<asp:CheckBox ID="chkSelectAllCatA" runat="server" Visible="false" onclick="javascript:SelectAllCheckboxesA(this);" CssClass="SACatA" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkCatA" runat="server" Enabled="false" CssClass="CatA" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<HeaderTemplate>
Category B
<asp:CheckBox ID="chkSelectAllCatB" runat="server" Visible="false" CssClass="CatB" onclick="javascript:SelectAllCheckboxesB(this);" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkCatB" runat="server" Enabled="false" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

This is based on solution proposed by Ashish Patil with some modifications to clear checkbox in the header row when any of the checkboxes in grid rows is unchecked.
In GridView create a template column:
<asp:templatefield>
<headertemplate>
<asp:CheckBox ID="chkSelectAll" cssclass="chkHeader" runat="server" />
</headertemplate>
<itemtemplate>
<asp:CheckBox ID="chkSelect" cssclass="chkItem" runat="server"/>
</itemtemplate>
</asp:templatefield>
jquery script, put it in $(document).ready for example:
var headerChk = $(".chkHeader input");
var itemChk = $(".chkItem input");
headerChk.click(function () {
itemChk.each(function () {
this.checked = headerChk[0].checked; })
});
itemChk.each(function () {
$(this).click(function () {
if (this.checked == false) { headerChk[0].checked = false; }
})
});

Why don't you select only the Checkboxes of CategoryA:
$('#<%=gvSurveys.ClientID %>').find("input:checkbox[Id*=chkCatA]")
Would that work?

Change the selectAll checkboxes to have the same class. Then extract the class from the checkbox and use it as part of the selector, filtering out the select. This will simplify things a lot since you know that all the matched inputs will simply need to get the checked value from the parameter.
function SelectAllCheckboxesA(chk) {
var $chk = $(chk);
var myClass = $chk.attr('class');
$('#<%=gvSurveys.ClientID %>')
.find("input." + myClass + ":checkbox" )
.not($chk)
.attr('checked', $chk.attr('checked') );
}

$('#<%=gvSurveys.ClientID %>').find('input[Id*="chkCatA"]:checkbox').each(function() {
if (this != chk) {
this.checked = chk.checked;
}
});

Create the row with a checkbox in the header:
<asp:TemplateField HeaderText="Merged Client">
<HeaderTemplate>
<asp:CheckBox ID="chkboxSelectAll" runat="server" AutoPostBack="true" OnCheckedChanged="chkboxSelectAll_CheckedChanged" ></asp:CheckBox> Merged Client
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckMergedClient" **runat="server"** **onclick="CheckChanged()" OnCheckedChanged="CheckMergedClient_CheckedChanged"** **AutoPostBack="true"** value='<%# Eval("ClientId") %>'/> </ItemTemplate>
</asp:TemplateField>
In code behind add the OnCheckChanged event handler to select or deselect all :
protected void chkboxSelectAll_CheckedChanged(object sender, EventArgs e)
{
CheckBox ChkBoxHeader = (CheckBox)ClientMatchGridView.HeaderRow.FindControl("chkboxSelectAll");
foreach (GridViewRow row in ClientMatchGridView.Rows)
{
CheckBox ChkBoxRows = (CheckBox)row.FindControl("CheckMergedClient");
if (ChkBoxHeader.Checked == true)
{
ChkBoxRows.Checked = true;
}
else
{
ChkBoxRows.Checked = false;
}
}
}

Related

Gridview taking more time to bind

I am fetching data from stored procedure and showing in the grid view.
My sql query takes max 1 sec to execute but while binding to gridview it takes more time .
In my page only one gridview is present. and the load time of my page is 10 sec :(
so how to increase my loading time.(i searched on google and didn't find any good solution :( )
My Gridview
<asp:GridView ID="gvStatusStatistics" runat="server" AutoGenerateColumns="False"
CssClass="grid" OnRowCreated="gvStatusStatistics_RowCreated">
<Columns>
<asp:TemplateField HeaderText="PNSC_Leads_LeadStatus">
<ItemTemplate>
<asp:HyperLink ID="hlLeadStatus" ForeColor="#000000" runat="server" Text='<%#Eval("TranslatedStatus") %>'
NavigateUrl='<%# string.Concat("~/ViewLeads.aspx?LeadStatusDefinition=", Eval("Status")) %>'
ToolTip="" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="PNSC_Leads_NumberOfLeads">
<ItemTemplate>
<asp:HyperLink ID="hlLeadsCount" ForeColor="#000000" runat="server" Text='<%#Eval("Value") %>'
NavigateUrl='<%# string.Concat("~/ViewLeads.aspx?LeadStatusDefinition=", Eval("Status")) %>'
ToolTip="" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
protected void gvStatusStatistics_RowCreated(object sender, GridViewRowEventArgs e)
{
Trace.Write("gvStatusStatistics_RowCreated", "Start");
if (e.Row.RowType == DataControlRowType.DataRow)
{
int CellCounter = 0;
foreach (TableCell cell in e.Row.Cells)
{
CellCounter++;
// track which row this is
if (CellCounter % 2 == 0)
{
// change the alternating one background color
cell.CssClass = GridCellAlternating1Css;
}
else
{
// change the alternating zero background color
cell.CssClass = GridCellAlternating0Css;
}
}
}
}
Please help to solve this.
Thanks
below line taking more time
using (IDataReader dataReader = db.ExecuteReader(dbCommand))
{
}

How can I select 1 Radio button at a time which is used inside the Gridview

I am binding the data to gridview like below. here I need to select 1 radion button at a time for each group. how to achive this in gridview
try using name property of the radio button
Or you can set the GroupName="group" property of the radio button
Reference
how to use radio buttons in grid view in asp.net
More Tutorial
http://www.c-sharpcorner.com/uploadfile/krishnasarala/select-single-radio-button-in-gridview-in-Asp-Net/
Edit 1
As the above tutorial suggested
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="AuthId">
<Columns>
<asp:TemplateField ShowHeader="false">
<ItemTemplate>
<asp:RadioButton ID="rdbauthid" runat="server"
onclick="javascript:CheckOtherIsCheckedByGVID(this);" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="AUTHOR NAME" DataField="AuthName" />
<asp:BoundField HeaderText="AUTHOR LOCATION" DataField="AuthLocation" />
</Columns>
</asp:GridView>
And create a java-script function as below
<script type="text/javascript">
function CheckOtherIsCheckedByGVID(spanChk) {
var IsChecked = spanChk.checked;
if (IsChecked) {
spanChk.parentElement.parentElement.style.backgroundColor = '#228b22';
spanChk.parentElement.parentElement.style.color = 'white';
}
var CurrentRdbID = spanChk.id;
var Chk = spanChk;
Parent = document.getElementById("<%=GridView1.ClientID%>");
var items = Parent.getElementsByTagName('input');
for (i = 0; i < items.length; i++) {
if (items[i].id != CurrentRdbID && items[i].type == "radio") {
if (items[i].checked) {
items[i].checked = false;
items[i].parentElement.parentElement.style.backgroundColor = 'white'
items[i].parentElement.parentElement.style.color = 'black';
}
}
}
}
</script>

Hide button in gridview when field is Null

I have a grid view where some of the rows have attached pictures. when I press Button2 I pull information from the sql record, about which folder on the server that has the pictures.
This works already, but I can not get the button to only be visible in the rows that have image folder attached.
I've googled a long time and found different solutions similar to the following, but I can not get it to work.
What am I doing wrong?
<asp:SqlDataSource ID="SqlDSodinRSSfeb" runat="server"
ConnectionString="<%$ ConnectionStrings:herning_brand_dk_dbConnectionString %>"
SelectCommand="SELECT PubDateTime, Melding, Station, PhotoFolder FROM OdinRSS ">
</asp:SqlDataSource>
<asp:GridView ID="GridView14" runat="server" DataSourceID="SqlDSodinRSSfeb"
AutoGenerateColumns="False" Width="500px" OnRowCommand="Button_RowCommand" >
<Columns>
<asp:BoundField DataField="PubDateTime" HeaderText="Tidspunkt" />
<asp:BoundField DataField="Melding" HeaderText="Melding for udkaldet" />
<asp:BoundField DataField="Station" HeaderText="Station" />
<asp:TemplateField HeaderText="Foto" >
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("PhotoFolder") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Button ID="Button2" runat="server" Text="Foto" Visible='<%# Eval("PhotoFolder") != "Null" %>'
CommandName="ButtonClick" CommandArgument='<%# Eval("PhotoFolder") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
My .cs
protected void Button_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandArgument != null)
{
switch (e.CommandName)
{
case "ButtonClick":
{
int Folder = Convert.ToInt32(e.CommandArgument);
PhotoList(Folder);
}
break;
}
}
}
void PhotoList(int FolderNumber)
{
var imagePaths = Directory.GetFiles(Server.MapPath("PhotoFolder\\" + FolderNumber));
var imageNames = new string[imagePaths.Length];
for (int i = 0; i < imagePaths.Length; i++)
{
imageNames[i] = imagePaths[i].Substring(imagePaths[i].LastIndexOf("\\") + 1);
}
var dt = new DataTable();
dt.Columns.Add("ImageName", typeof(string));
dt.Columns.Add("ImagePath", typeof(string));
foreach (var imgName in imageNames)
{
DataRow dr = dt.NewRow();
dr["ImageName"] = RemoveExtension(imgName);
dr["ImagePath"] = "PhotoFolder/" + FolderNumber + "/" + imgName;
dt.Rows.Add(dr);
}
DataList1.DataSource = dt;
DataList1.DataBind();
}
string RemoveExtension(string imgName)
{
return imgName
.Replace(".jpg", "")
.Replace(".png", "");
}
The sql field "PhotoFolder" is a nvarchar(50). If there is photos for the record, the field has a number from 100 and up, that refares to the folder containing photos. If there are no photo for the record, the field contains "Null"
I have also tried:
<asp:Button ID="Button2" runat="server" Text="Foto" Visible='<%# Eval("PhotoFolder").ToString() != "Null" %>'
But the button is shown in all rows, not just the ones that has a string(number) in "PhotoFolder"
It can be achieved simple in Inline code
<asp:ImageButton ID="ibtnBranchType1" runat="server" ImageUrl='<%# "~/images/" + Eval("branchtype1")+".png" %>' Visible='<%# Convert.ToString(Eval("branchtype1"))=="" ? false : true %>' Height="20px"/>
Here Eval("branchtype1") we are getting value of id from data table like 1, 2, 3 etc. and our image folder consists images like 1.png, 2.png, 3.png etc.,
Visible='<%# Convert.ToString(Eval("branchtype1"))=="" ? false : true %>'
if value doesn't contain any id it will get null. we will compare it with empty string using ternary operator.
Try this.
Markup
Visible='<%# HideEmptyPhotoFolder(Eval("PhotoFolder")) %>'
Code-Behind
protected bool HideEmptyPhotoFolder(object photoFolder)
{
return photoFolder != null && !String.IsNullOrEmpty(photoFolder.ToString());
}
You can simply do that in GridView RowDataBound event.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowdatabound.aspx
As per your question you should write the code for checking the rows containing the image,
you can write the code in RowDatabound event,and set visible property of button to false on that row which doesn't contain image.

Javascript function on submit button to validate if cells are emply for a particular column of gridview

I have binded a custom datatable to gridview. Now I want to validate if the value of cells of the column "DocumentsAttached" is Yes or No. If it is yes, then an alert message displaying " Documents are Attached". If No, a pop up box with message would you like to continue" Yes/No...If yes, is chosen my submit button should go through otherwise no.
Hope i made sense until now. Below is my aspx
<asp:GridView ID="UploadDocs" AutoGenerateColumns="False" runat="server"
EnableViewState="true" onrowdatabound="dgdUpload_RowDataBound" style="margin-top: 0px">
<Columns>
<asp:HyperLinkField DataTextField="DocName" HeaderText="Invoice File Name" DataNavigateUrlFields="FilePath" DataNavigateUrlFormatString="{0}">
</asp:HyperLinkField>
<asp:BoundField HeaderText="Document Included" DataField="DocumentsAttached" ReadOnly="true" />
<asp:BoundField HeaderText="Identifier" DataField="Identifier" Visible="false"/>
<asp:CommandField ButtonType="Button" HeaderText="Delete" ShowDeleteButton="true"/>
</Columns>
</asp:GridView>
<asp:Button ID="btnSubmit" runat="server" Text="Save to MassUploadList" />
Can anyone help me to achieve this please.
Replace <asp:BoundField HeaderText="Document Included" DataField="DocumentsAttached" ReadOnly="true" /> with this:
<asp:TemplateField HeaderText="Document Included" HeaderStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Label ID="lblDocumentsAttached" runat="server" Text='<%# Eval("DocumentsAttached")%>' CssClass="DocumentsAttached"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
and use this javascript to validate:
function validateAttachment() {
$(".DocumentsAttached").each(){
if($(this).val().toLowerCase()=="no") {
return false;
}
}
return true;
}
But validation this way is not a good idea since I can easily bypass it by just changing the column values in the DOM using firebug.
I would assume you're uploading something, or otherwise generating the datatable from codebehind. So why not do server side validation? If at least one row has DocumentAttached equal to "NO", disable submit button and add a custom validator to the page with relevant message.
The function that I used to serve my purpose is below
<script language="javascript" type="text/javascript">
function Validate() {
var cntrlname = document.getElementById('<%= gridview1.ClientID %>');
var gridcell;
var retVal = 1;
var result = 1;
for (i = 1; i < cntrlname.rows.length; i++) {
if (cntrlname.rows[i].cells[2].innerText == "No") {
retVal = 0;
}
if (retVal == 0) {
return window.confirm("One of the Attachments is missing, would you like to proceed")
}
else{
return true;
}
}
}
function window.confirm(str) {
execScript('n = msgbox("' + str + '","4132")', "vbscript");
return (n == 6);
}
The column documents attached is readonly, the user will not be able to make any changes to it.So , this displays a confirmation box if there any attachments missing, if the user is ok ...it will execute the server side code otherwise will not.

Add an additional label control to an <ItemTemplate> dynamically in certain cases

How can I add an extra label control dynamically (should be added only on certain conditions).
I am trying to do something like this:
<asp:DataGrid id="dg" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:TemplateColumn SortExpression="Column1">
<HeaderTemplate>
<asp:LinkButton Runat="server" text="Column1 Hdr" ID="col1Hdr">
</asp:LinkButton>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="col1Label" runat="server" Text='<%# Method1(DataBinder.Eval(Container.DataItem, "Column1").ToString(), DataBinder.Eval(Container.DataItem, "Column2").ToString()) %>' >
<asp:PlaceHolder ID="col2Holder" runat="server"></asp:PlaceHolder>
</asp:Label>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</asp:DataGrid>
Alternatively, I tried putting the placeholder in a seperate template:
<EditItemTemplate>
<asp:PlaceHolder ID="col2Holder" runat="server"></asp:PlaceHolder>
</EditItemTemplate>
but to no avail.
Any tips on how I can create the Placeholder only in some cases (like for some values of Column1/Column2), rather than opt for a repeater approach...
I get a null reference exception but that was solved when I had to explicitly mention:
protected PlaceHolder col2Holder = new Placeholder();
instead of
protected PlaceHolder col2Holder;
But though method1 is able to set the 'Column1's text value correctly, it does nothing for the Column2's value...
Is there something I'm missing or is there a different way to do this?
Here's method1's defn:
public string Method1(string col1, string col2)
{
col1 += "Called method1";
Label col2label= new Label();
col2label.Visible = true;
col2label.Text = col2;
col2Holder.Controls.Add(col2label);
col2Holder.DataBind();
return col1;
}
Where and when do you need the extra control to be inserted?
You should most likely hookup a method to the OnItemDataBound event and in there decide whether to add a control or not. The event gives you a reference to the item being bound so you can say e.Item.Controls.Add(your_control)
Update
Ah, now i get it what you're asking for. You need to add another argument to your Method1 that takes a DataGridItem. When you call Method1 you add it like this Method1(Container) where Container refers to the DataGridItem in question. Then you can say in the Method1
public string Method1(DataGridItem item)
{
string col1 = DataBinder.Eval(item.DataItem, "Column1").ToString();
string col2 = DataBinder.Eval(item.DataItem, "Column2").ToString();
var col2label = new Label() { Visible = true, Text = col2 };
var col2Holder = item.FindControl("col2Holder");
col2Holder.Controls.Add(col2label);
return col1 + "Called method1";
}
Btw, you can't add any controls to a Label, your ItemTemplate should look like this
<ItemTemplate>
<asp:Label ID="col1Label" runat="server" Text="<%# Method1(Container) %>" />
<asp:PlaceHolder ID="col2Holder" runat="server" />
</ItemTemplate>
If you want the new Label to be nested inside the first label, you should do that explicit in the method, and leave out the placeholder:
<ItemTemplate>
<asp:Label ID="label" runat="server" Text="<%# Method1(Container) %>" />
</ItemTemplate>
public string Method1(DataGridItem item)
{
string col1 = DataBinder.Eval(item.DataItem, "Column1").ToString();
string col2 = DataBinder.Eval(item.DataItem, "Column2").ToString();
var label = item.FindControl("label");
var col2label = new Label() { Visible = true, Text = col2 };
col1Holder.Controls.Add(col2label);
return col1 + "Called method1";
}

Resources