How Can I Retrieve SelectedID of Telerik RadGrid On Client-Side Without Using OnRowSelected event?
so lets to see my scenarion:
my grid properties are like this :
<telerik:RadGrid ID="RadGrid1" runat="server" GridLines="None" DataSourceID="SqlDataSource1" AllowPaging="True" AutoGenerateColumns="False" CellSpacing="0"
Width="660px" onitemdatabound="RadGrid1_ItemDataBound">
<ClientSettings Selecting-AllowRowSelect="true">
<Selecting AllowRowSelect="True"></Selecting>
<ClientEvents OnRowSelected="OnRowSelected" />
</ClientSettings>
...
and goal Column :
<telerik:GridTemplateColumn FilterControlAltText="Filter TemplateColumn_Q column"
HeaderText="Q" UniqueName="TemplateColumn_Q">
<ItemTemplate>
<asp:Label ID="lblQInsideGrd" runat="server" Font-Size="11px" Text='<%# GetQ(Eval("Q")) %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
i fill this column in code behind like this :
protected string GetQ(object Q)
{
if (Q.ToString().Length < 10)
{
return Q.ToString();
}
else
{
string Q_str = Q.ToString();
Q_str = Q_str.Substring(0, 10) + "<span style='font-size:9px;color:red;'><a href='#' class='QClick'> (Full View...)</a></span>";
return Q_str;
}
as you see there is an anchor in every column that i want to retrieve related ID filed of that anchor in client side and show that id in an alert.
for server-side we can use CommandName property for that anchor.
also for client-side when we click on every row we can use OnRowSelected event to retrieve that id.
but in my situation, clicking on those anchors will not couse to select the entire row for firing OnRowSelected.
so what can i do about that?
thanks in advance
var radGrid = $find('<%= RadGrid1.ClientID %>');
var selectedItems = radGrid.get_masterTableView().get_selectedItems()
...
Here you are :)
Related
I have an ASP TemplateField inside a data populated GridView as follows:
<asp:GridView ID="gvReport" runat="server" AutoGenerateColumns="False" ShowHeaderWhenEmpty="true" OnRowDataBound="gvReport_RowDataBound" CssClass="table table-bordered">
<Columns>
<asp:BoundField DataField="Delete" HeaderText="Delete" SortExpression="Delete" />
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:HyperLink runat="server" NavigateUrl='<%# "Edit?from=Delete&ID=" + Eval("ID") %>' ImageUrl="Assets/SmallDelete.png" SortExpression="PathToFile" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
In other words, at the end of each row, there is a delete 'button'. I can tell whether a particular row/record has been deleted by checking the true/false value of the BoundField Delete in my code behind as follows:
if (e.Row.RowType == DataControlRowType.DataRow)
{
TableCell statusCell = e.Row.Cells[0];
if (statusCell.Text == "True")
{
//change ImageUrl of Hyperlink for this row
}
}
Right now, my icon is red for delete, but in the case that a record has already been deleted,
I would like to change the image to a different icon (a blue one).
How can I change this ImageUrl if statusCell evaluates to true?
ok, so we will need two parts here:
We need (want) to persist the data table that drives the grid).
The REASON for this?
We kill about 3 birds with one stone.
We use the data table store/save/know the deleted state
We use that delete information to toggle our image
(and thus don't have to store the state in the grid view).
We ALSO then case use that table state to update the database in ONE shot, and thus don't have to code out a bunch of database operations (delete rows). We just send the table back to the database.
In fact in this example, I can add about 7 lines of code, and if you tab around, edit the data? It ALSO will be sent back to the database. And this means no messy edit templates and all that jazz (which is panful anyway).
Ok, so, here is our grid - just some hotels - and our delete button with image:
markup:
<div style="width:40%;margin-left:20px">
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False"
DataKeyNames="ID" CssClass="table table-hover borderhide" >
<Columns>
<asp:TemplateField HeaderText="HotelName" >
<ItemTemplate><asp:TextBox id="HotelName" runat="server" Text='<%# Eval("HotelName") %>' /></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="FirstName" SortExpression="ORDER BY FirstName" >
<ItemTemplate><asp:TextBox id="FirstName" runat="server" Text='<%# Eval("FirstName") %>' /></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="LastName" >
<ItemTemplate><asp:TextBox id="LastName" runat="server" Text='<%# Eval("LastName") %>' /></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="City" >
<ItemTemplate><asp:TextBox id="City" runat="server" Text='<%# Eval("City") %>' /></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete">
<ItemTemplate>
<asp:ImageButton ID="cmdDelete" runat="server" Height="20px" Style="margin-left:10px"
ImageUrl="~/Content/cknosel.png"
Width="24px" OnClick="cmdDelete_Click"></asp:ImageButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<asp:Button ID="cmdDeleteAll" runat="server" Text="Delete selected" Width="122px"
OnClientClick="return confirm('Delete all selected?')" />
</div>
Ok, and the code to load up the grid - NOTE WE persist the data table!!!!!
Code:
DataTable rstTable = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
LoadGrid();
else
rstTable = (DataTable)ViewState["rstTable"];
}
void LoadGrid()
{
// load up our grid
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from tblHotels ORDER BY HotelName ",
new SqlConnection(Properties.Settings.Default.TEST4)))
{
cmdSQL.Connection.Open();
rstTable.Clear();
rstTable.Load(cmdSQL.ExecuteReader());
GridView1.DataSource = rstTable;
GridView1.DataBind();
}
ViewState["rstTable"] = rstTable;
}
Ok, so far, real plain jane. The result is this:
Ok, so now all we need is to add the delete button click event.
That code looks like this:
protected void cmdDelete_Click(object sender, ImageClickEventArgs e)
{
ImageButton btn = (ImageButton)sender;
GridViewRow rRow = (GridViewRow)btn.Parent.Parent;
DataRow OneRow = rstTable.Rows[rRow.DataItemIndex];
// toggle data
if (OneRow.RowState == DataRowState.Deleted)
{
// undelete
OneRow.RejectChanges();
btn.ImageUrl = "/Content/cknosel.png";
}
else
{
// delete
OneRow.Delete();
btn.ImageUrl = "/Content/ckdelete.png";
}
}
Again, really simple. But NOTE how we use the data table row state (deleted or not).
And this ALSO toggles the image for the delete button.
So, we don't have to care, worry, or store/save the sate in the grid.
So, if I click on a few rows to delete, I now get this:
So far - very little code!!!
Ok, so now the last part. the overall delete selected button. Well, since that is dangerous - note how I tossed in a OnClientClick event to "confirm the delete. if you hit cancel, then of course the server side event does not run.
But, as noted since we persisted the table? Then we can send the table deletes right back to the server without a loop. The delete code thus looks like this:
protected void cmdDeleteAll_Click(object sender, EventArgs e)
{
// send updates (deletes) back to database.
using (SqlCommand cmdSQL = new SqlCommand("SELECT * from tblHotels WHERE ID = 0",
new SqlConnection(Properties.Settings.Default.TEST4)))
{
cmdSQL.Connection.Open();
SqlDataAdapter daUpdate = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daUpdateBuild = new SqlCommandBuilder(daUpdate);
daUpdate.Update(rstTable);
}
LoadGrid(); // refesh display
}
So, note how easy it is to update (delete) from the database. If you look close, I used text boxes for that grid - not labels. The reason of course is that if the user tabs around in the grid (and edits - very much like excel), then I can with a few extra lines of code send those changes back to the database. In fact the above delete button code will be 100% identical here (it will send table changes back with the above code. So, if we add rows, edit rows then the above is NOT really a delete command, but is in fact our save edits/deletes/adds command!
I insert three template columns in my gridview. In every column I insert a user control. For example in first column there is a user control containing an image and three labels.
In my page load, I need to get list of images in a folder and create a row for each of them. Then I need to update those user controls' images in gridview columns.
Here is the sample code which gets the list of images and will be the data source of GridView:
string[] filePaths = Directory.GetFiles(Server.MapPath("~/Resources/Pictures"));
GridView1.DataSource = filePaths;
GridView1.DataBind();
In this step I can see 4 rows which have filled with RAW user controls (Empty images in image control,default text for labels etc.) Now I need to update each of them with my own properties.
Here is a picture Of my output:
As you can see in first column there are some controls (Image and Labels) which is for user control that I used them in column template of my gridview. But they are RAW and I need to update them. For example I need to update the image with the link you see in the third column.
and Here is a part of my GridView Code:
<asp:GridView ID="GridView1" runat="server" BackColor="LightGoldenrodYellow" BorderColor="Tan" BorderWidth="1px" Caption="Image List" CellPadding="2" ForeColor="Black" GridLines="None" Height="222px" Width="409px">
<AlternatingRowStyle BackColor="PaleGoldenrod" />
<Columns>
<asp:TemplateField HeaderText="Old Picture">
<ItemTemplate>
<uc1:ImageColumn ID="ImageColumn1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="New Picture">
<ItemTemplate>
<uc2:ReplaceColumn ID="ReplaceColumn1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Allow Access">
<ItemTemplate>
<asp:Image ID="Image1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
Hope it is clear enough. can any one help please?
You have to add public properties to your user controls which you then set using "normal" data-binding expressions. E.g:
user control:
public class MyUserControl : UserControl
{
public string ImageName {get; set;}
}
grid's template column:
<asp:TemplateField ...>
<ItemTemplate>
<uc1:MyUserControl runat="server" ImageName='<%# Eval("ImageUrl")%>' ... />
code-behind:
public class ImageVM { // view-model for data-binding
public string ImageUrl { get; set; }
}
...
var images = LoadImages(); // returns a list of ImageVM instances
grid.DataSource = images;
grid.DataBind();
Check / Select only one single Radio Button in Rad Grid or Grid View with Paging and any PageSize at Server Side Code behind in C#
My Aim is to maintain user selected asp:RadioButton inside telerik:RadGrid to be selected / checked even with the paging of the grid and with any PageSize accordingly.
The Challenges i'm facing are unable to maintain Unique GroupName for each RadioButton present for each row in Grid. Due to this i have to handle this functionality in code behind.
How ever i tried searching internet for solution which i found some javascript answers with lot of work around which i'm not satisfied with them.
<telerik:RadGrid ID="rgWithPaging" AllowPaging="True" CellSpacing="0" GridLines="None"
AllowSorting="True" runat="server" AutoGenerateColumns="False"
AllowFilteringByColumn="true" EnableLinqExpressions="false"
PagerStyle-PageSizeControlType="RadDropDownList" PagerStyle-AlwaysVisible="true" Visible="true"
OnNeedDataSource="rgWithPaging_NeedDataSource">
...........
<telerik:GridTemplateColumn HeaderText="Check One" HeaderStyle-CssClass="gradient" AllowFiltering="false" HeaderStyle-Width="10%">
<ItemTemplate>
<asp:RadioButton ID="rbWPFileName" runat="server"/>
</ItemTemplate>
</telerik:GridTemplateColumn>
...........
</telerik:RadGrid>
The Answer i came up with server side code behind is as given below:
<telerik:RadGrid ID="rgWithPaging" AllowPaging="True" CellSpacing="0" GridLines="None"
AllowSorting="True" runat="server" AutoGenerateColumns="False"
AllowFilteringByColumn="true" EnableLinqExpressions="false"
PagerStyle-PageSizeControlType="RadDropDownList" PagerStyle-AlwaysVisible="true" Visible="true"
OnNeedDataSource="rgWithPaging_NeedDataSource" OnDataBound="rgWithPaging_OnDataBound">
...........
<telerik:GridTemplateColumn HeaderText="Check One" HeaderStyle-CssClass="gradient" AllowFiltering="false" HeaderStyle-Width="10%">
<ItemTemplate>
<asp:RadioButton ID="rbWPFileName" runat="server" AutoPostBack="true" OnCheckedChanged="rbWPFileName_OnCheckedChanged"/>
</ItemTemplate>
</telerik:GridTemplateColumn>
...........
</telerik:RadGrid>
now in code behind to achieve this we need only two events
OnCheckedChanged="rbWPFileName_OnCheckedChanged" and
OnDataBound="rgWithPaging_OnDataBound"
In code behind:
protected void rbWPFileName_OnCheckedChanged(object sender, EventArgs e)
{
var rbtnSelected = sender as RadioButton;
if (rbtnSelected == null) return;
foreach (GridDataItem item in rgWithPaging.Items)
{
var radFileName = (RadioButton)item.FindControl("rbWPFileName");
if (radFileName == null) return;
radFileName.Checked = rbtnSelected.ClientID == radFileName.ClientID;
if (radFileName.Checked)
{
var position = (rgWithPaging.PageSize*rgWithPaging.CurrentPageIndex) + item.ItemIndex;
Session["Position"] = position;
}
}
}
protected void rgWithPaging_OnDataBound(object sender, EventArgs e)
{
if (Session["Position"] == null) return;
var position = (int)Session["Position"];
var pageIndex = position / rgWithPaging.PageSize;
var itemIndex = position%rgWithPaging.PageSize;
if (pageIndex == rgWithPaging.CurrentPageIndex)
{
foreach (GridDataItem item in rgWithPaging.Items)
{
var radFileName = (RadioButton)item.FindControl("rbWPFileName");
if (radFileName == null) return;
radFileName.Checked = itemIndex == item.ItemIndex;
}
}
}
that's it task done!!! enjoy..:-)
How do I pass a GridView column value to the code behind with out making it visible? In the following code, I would like to capture the ContactID with out making it visible in the GridView.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="SqlDataSource1"
OnRowCommand="_OnRowCommand"
>
<Columns>
<asp:BoundField DataField="ContactID" HeaderText="ContactID"
SortExpression="ContactID" InsertVisible="False" ReadOnly="True" />
.....other columns in the grid....
<asp:ButtonField ButtonType=Button CommandName="Remove" Text="Remove" />
</Columns>
</asp:GridView>
I would like to capture ContactID as follows. I can not do so with out making it visible = true in the GridView.
if (e.CommandName.Equals("Remove"))
{
int index = Convert.ToInt32(e.CommandArgument);
int ContactID = Convert.ToInt32(GridView1.Rows[index].Cells[0].Text.Trim());
}
Please help.
Thanks..
What you want and what your code is doing are two different things.
I think what you are looking for is this:
String ContactID = e.Row.Cells(0).Text;
However, I propose a different way:
You can use a CommandArgument on your Button. That means that you are passing the argument through the Button itself. You won't need to get the argument from any other control. To do that, you would do this :
<asp:ButtonField ButtonType=Button CommandName="Remove" Text="Remove" CommandArgument='<%# Eval("ContactID") %>' />
And then your code looks like this:
if (e.CommandName.Equals("Remove"))
{
int ContactID = Convert.ToInt32(e.CommandArgument);
}
Here's a good example of GridView with CommandArguments.
T have used checkbox column in gridview. On click of a linkbutton, it should be checked that checkboxes in gridview are checked or not. If none check box is checked then it should display alert("Check at leat one check box").
You will have to add some custom Javascript to your page for the client-side alert to show. Here's a method that I've written that works with a GridView called 'GridView1' (this should be the default name if you've just dragged the control onto your ASPX page):
<script type="text/javascript">
function ClientCheck() {
var valid = false;
var gv = document.getElementById("GridView1");
for (var i = 0; i < gv.all.length; i++) {
var node = gv.all[i];
if (node != null && node.type == "checkbox" && node.checked) {
valid = true;
break;
}
}
if (!valid) {
alert("Invalid. Please select a checkbox to continue.");
}
return valid;
}
</script>
You can see that it sets a variable to the GridView control to start with, then iterates through all the children in a for loop. If the child is a checkbox and it is checked, then we set the valid variable to true. If we get to the end of the iteration and no checked checkboxes are found, then valid remains false and we execute the alert.
To link this into your GridView on your ASPX page, first make the button column a TemplateField and surround the LinkButton with your client-side code. If you've used the designer to set up your columns, you can use the "Convert this field into a TemplateField" link in the column editor). Here's an example of the source you'll end up with:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1">
<Columns>
<asp:TemplateField HeaderText="Button Field" ShowHeader="False">
<ItemTemplate>
<span onclick="return ClientCheck();">
<asp:LinkButton ID="LinkButton1" runat="server" CommandName="IDClick" Text='<%# Eval("YourDataSourceItem") %>'></asp:LinkButton>
</span>
</ItemTemplate>
</asp:TemplateField>
// ...your remaining columns...
Using the TemplateField lets us add any client-side code we like. Here we're adding a span and using onclick to call our ClientCheck method.
If you aren't bothered about the alert, you could achieve your aims by using a CustomValidator control, which executes on the server-side.
I hope this helps.
I found the answer. and its working...
function checkBoxselectedornot()
{
var frm=document.forms['aspnetForm'];
var flag=false;
for(var i=0;i<document.forms[0].length;i++)
{
if(document.forms[0].elements[i].id.indexOf('chkDownloadSelectedEvent')!=-1)
{
if(document.forms[0].elements[i].checked)
{
flag=true
}
}
}
if (flag==true)
{
return true
}else
{
alert('Please select at least one Event.')
return false
}
}
and girdview code is...
<asp:BoundField ItemStyle-Width ="100px" DataField ="EventStartDate" DataFormatString ="{0:g}" HeaderText ="<%$ Resources:stringsRes, ctl_EventList_StartDate %>" SortExpression ="EventStartDate" HtmlEncode ="true" ItemStyle-Wrap ="false" />
<asp:BoundField ItemStyle-Width="100px" DataField="EventDate" DataFormatString="{0:g}" HeaderText="<%$ Resources:stringsRes, ctl_EventList_Date %>" SortExpression="EventDate" HtmlEncode="true" ItemStyle-Wrap="false" />
<asp:ButtonField ItemStyle-Width="150px" ButtonType="Link" DataTextField="EventName" HeaderText="<%$ Resources:stringsRes, ctl_EventList_Event %>" SortExpression="EventName" CommandName="show_details" CausesValidation="false" />
<asp:BoundField DataField="EventLocation" HeaderText="<%$ Resources:stringsRes, ctl_EventList_Location %>" SortExpression="EventLocation" />
<asp:TemplateField HeaderText ="Select">
<ItemTemplate >
<asp:CheckBox ID="chkDownloadSelectedEvent" runat ="server" AutoPostBack ="false" Onclick="eachCheck();"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<RowStyle Height="25px" />
<HeaderStyle Height="30px"/>
</asp:GridView>
and there is a link button ....
I havnt used the checkbox in grid view but would you not do a for loop around the columns in gridview and check the state? Myabe add a count and if 0 then alert.
var grid = document.getElementById("gridId"); //Retrieve the grid
var inputs = grid.getElementsByTagName("input"); //Retrieve all the input elements from the grid
var isValid = false;
for (var i=0; i < inputs.length; i += 1) { //Iterate over every input element retrieved
if (inputs[i].type === "checkbox") { //If the current element's type is checkbox, then it is wat we need
if(inputs[i].checked === true) { //If the current checkbox is true, then atleast one checkbox is ticked, so break the loop
isValid = true;
break;
}
}
}
if(!isValid) {
alert('Check at least one checkbox');
}