I have a gridview that contains a list of products. What i am trying to do is using the ItemTemplate is pass the ProductID of the selected item using an Onclick event to a session so i can then lookup that session on another page to avoid having the ProductID shown in the URL.
<asp:GridView ID="GVProducts" runat="server"
onselectedindexchanged="GVProducts_SelectedIndexChanged">
<Columns>
<asp:ImageField DataImageUrlField="FileName"
DataImageUrlFormatString="Images/{0}" HeaderText="Image">
<ControlStyle Height="80px" Width="80px" />
</asp:ImageField>
<asp:TemplateField HeaderText="Title" SortExpression="ProductID" >
<ItemTemplate>
<a onclick="javascript:function setSessionVariable(<%#Eval("ProductID")%>)" href="ProductDetail.aspx"><%#Eval("Title")%></a>
</ItemTemplate></asp:TemplateField>
</Columns>
<FooterStyle BackColor="#99CCCC" ForeColor="#003399" />
<HeaderStyle BackColor="#003399" Font-Bold="True" ForeColor="#CCCCFF" />
<PagerStyle BackColor="#99CCCC" ForeColor="#003399" HorizontalAlign="Left" />
<RowStyle BackColor="White" ForeColor="#003399" />
<SelectedRowStyle BackColor="#009999" Font-Bold="True" ForeColor="#CCFF99" />
<SortedAscendingCellStyle BackColor="#EDF6F6" />
<SortedAscendingHeaderStyle BackColor="#0D4AC4" />
<SortedDescendingCellStyle BackColor="#D6DFDF" />
<SortedDescendingHeaderStyle BackColor="#002876" />
</asp:GridView>
Hopefully it is something simple as i am just starting out with javascript but i cant seem to get it to pass to the session.
Thanks
If you have jQuery library in your project, you may use jQuery ajax to send data to server pages.
function setSessionVariable(selectedval)
{
$.post("yourserverpage.aspx", { productId : selectedval },function(data){
alert("set to session!");
});
}
and create an aspx page called youserverpage.aspx and read the querystring value in the page load and set to session.
Call a web method from your javascript (using jQuery) and set the session on the web method:
public partial class _Default : Page
{
[WebMethod]
public static void SetVar(string myVar)
{
Session["var"] = myVar;
}
}
jQuery:
$.ajax({
type: "POST",
url: "Default.aspx/SetVar",
data: "{'myVar':'SessionVarValueSetOnJavascript'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
// Do something interesting here.
}
});
See this page for a nice example
Setting Session should be done in ServerSide. Try this
Markup
<asp:TemplateField HeaderText="Title" SortExpression="ProductID" >
<ItemTemplate>
<asp:LinkButton ID="MyLink" runat="server"
CommandName="SendID"
CommandArgument='<%#Eval("ProductID")%>'>
<%#Eval("Title")%>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Code-Behind
protected void GVProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked.
if (e.CommandName == "SendID")
{
// Get the ProductID stored in the CommandArgument
// property to an String.
string clickedProductID = e.CommandArgument.ToString();
// Set that ProductID to Session
Session["ProductID"] = clickedProductID;
// Redirect to the newpage.
Response.Redirect("ProductDetails.aspx");
}
}
Please dont forget to add OnRowCommand="GVProducts_RowCommand" to the GridView markup.
Update:
<asp:GridView ID="GVProducts" runat="server"
OnRowCommand="GVProducts_RowCommand">
Related
I currently have a JavaScript confirm prompt for my delete command in my GridView like so:
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server"
CommandName="Delete"
CausesValidation="False"
CssClass="adminLinks"
NavigateUrl="#"
Text="delete"
OnClientClick="return confirm('Are you sure you want to DELETE this record?');"/>
</ItemTemplate>
</asp:TemplateField>
Then for my delete command, I'm running this update code:
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:sqlConnection2 %>"
DeleteCommand="UPDATE [jeakins].[tbl_submit] SET recycle_bin=1 WHERE [ID] = #ID">
</asp:SqlDataSource>
How can I change this from a confirm box to a prompt box that asks "Reason for Deletion?" and then use that variable in the DeleteCommand to update a delete_reason field?
You can define a confirmDelete Javascript function which displays the prompt box and stores the reason in a HiddenField if the user clicks OK but cancels the deletion if he clicks Cancel.
function confirmDelete() {
var reason = prompt('Why do you want to delete?', '');
if (reason !== null) {
document.getElementById('hfDeleteReason').value = reason;
return true;
}
else {
return false;
}
}
The HiddenField is added to the markup (outside of the GridView) and confirmDelete is called by the LinkButton:
<asp:HiddenField ID="hfDeleteReason" runat="server" ClientIDMode="Static" />
<asp:LinkButton runat="server" OnClientClick="return confirmDelete();" ... />
If the user confirms the deletion, you can retrieve the reason from the HiddenField in code-behind:
string reason = hfDeleteReason.Value;
You then have to adapt the DeleteCommand to include the reason entered by the user. It could update the delete_reason field with the use of an additional parameter:
DeleteCommand="UPDATE [jeakins].[tbl_submit] SET recycle_bin=1, delete_reason = #Reason WHERE [ID] = #ID">
...
<DeleteParameters>
<asp:Parameter Name="Reason" Type="String" DefaultValue="" />
</DeleteParameters>
which would be set in code-behind:
SqlDataSource1.DeleteParameters["Reason"].DefaultValue = hfDeleteReason.Value;
I have <telerik:RadGrid/>
inside this grid i have the following column contains button
<telerik:GridTemplateColumn >
<ItemTemplate>
<asp:Button ID="btnDelete" runat="server" Text="Delete"
CommandArgument='<%#Container.ItemIndex%>' OnCommand="btnDelete_Command">
protected void btnDelete_Command(object sender, CommandEventArgs e)
{
Telerik.Web.UI.GridDataItem item = gvAllDocuments.Items[int.Parse(e.CommandArgument.ToString())];
string FileName = item["documentFileName"].Text;
}
how I can add confirmation message before function btnDelete_Command executing ..
Do not use ItemIndex. It is just a row index of the grid. Instead, you want to set unique id inside DataKeyNames.
Ideally, you do not want to implement your own delete button, because telerik already has delete button which calls OnDeleteCommand automatically.
It is a prefer way of doing it for RadGrid.
<telerik:RadGrid ... OnDeleteCommand="RadGrid_DeleteCommand">
<MasterTableView DataKeyNames="xxxId" ...>
<Columns>
<telerik:GridButtonColumn
ButtonType="ImageButton"
ConfirmText="Are you sure you want to delete?"
CommandName="Delete"
ImageUrl="~/Images/Delete.png"
Text="Click to delete" UniqueName="Delete">
</telerik:GridButtonColumn>
</Columns>
...
</MasterTableView>
</telerik:RadGrid>
protected void RadGrid_DeleteCommand(object source, GridCommandEventArgs e)
{
int id = Convert.ToInt32(
e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["xxxId"]);
// Delete logic here.
}
I have two GridViews. The user can select a row from the first GridView and a list based on the GridView ID selected will display.
First Grid:
Second Grid:
Code for first GridView:
<asp:GridView style="width:75%"
ID="gvCVRT"
ShowHeaderWhenEmpty="true"
CssClass="tblResults"
runat="server"
OnSelectedIndexChanged="gridviewParent_SelectedIndexChanged"
OnRowDataBound="gvCVRT_RowDataBound"
DataKeyField="ID"
DataKeyNames="ChecklistID"
AutoGenerateColumns="false"
allowpaging="false"
AlternatingRowStyle-BackColor="#EEEEEE">
<HeaderStyle CssClass="tblResultsHeader" />
<Columns>
<asp:BoundField DataField="ChecklistID" HeaderText="ID" ></asp:BoundField>
<asp:CommandField ShowSelectButton="True" HeaderText="Select" />
<asp:BoundField DataField="ChecklistDate" HeaderText="Checklist Date" dataformatstring="{0:dd/MM/yyyy}"></asp:BoundField>
<asp:BoundField DataField="User" HeaderText="User" ></asp:BoundField>
<asp:BoundField DataField="Note" HeaderText="Note" ></asp:BoundField>
<asp:TemplateField HeaderText="Delete" ItemStyle-CssClass="tblRowDelete">
<ItemTemplate>
<asp:LinkButton ID="btnDelete"
runat="server" OnClientClick="event.stopPropagation()" OnClick="btnDeleteCVRT_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code behind:
protected void gvCVRT_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
lookupCVRT work = (lookupCVRT)e.Row.DataItem;
GridView gv = sender as GridView;
string checklistid = work.ChecklistID.ToString();
e.Row.Attributes.Add("ID", "gvCVRT_" + work.ID);
LinkButton btnDelete = (LinkButton)e.Row.FindControl("btnDelete");
btnDelete.CommandArgument = checklistid;
if (work.ID != null)
{
int index = gv.Columns.HeaderIndex("Select");
if (index > -1)
{
e.Row.Cells[index].Attributes.Add("class", "gvCVRTRow");
e.Row.Cells[index].ToolTip = "Click here to Edit Checklist";
e.Row.Cells[index].Attributes.Add("style", "color:blue;cursor:pointer;cursor:hand");
}
}
}
}
Code for gridviewParent_SelectedIndexChanged:
protected void gridviewParent_SelectedIndexChanged(object sender, EventArgs e)
{
List<lookupCVRT> workDetails = lookupCVRT.GetChecklistItemsByChecklistID(Company.Current.CompanyID, ParentID.ToString(), gvCVRT.SelectedDataKey.Value.ToString());
gvCVRTDetails.DataSource = workDetails;
gvCVRTDetails.DataBind();
FireJavascriptCallback("setArgAndPostBack ();");
}
Javascript:
$(".gvCVRTRow").off();
$(".gvCVRTRow").click(function (e) {
ShowAddEditCVRT(this, "Edit");
});
function ShowAddEditCVRT(sender, AddEdit) {
$("#divCVRTDetails").fadeIn(300);
}
Sorry its a lot of code but I wanted to show exactly what is happening. When I set the code to int index = gv.Columns.HeaderIndex("Select"); it goes into the javascript function ShowAddEditCVRT first, which tries to display the second grid divCVRTDetails. But I need to run the method gridviewParent_SelectedIndexChanged first because this binds the second grid with the ID selected from the first grid.
The only way I can get the second grid to bind first is to change the code to this: int index = gv.Columns.HeaderIndex("Checklist Date");.
So the user has to click on select first (to bind the grid) then click on the date cell to display the grid.
so my question is, is there anyway to run the gridviewParent_SelectedIndexChanged method before the javascript function gets called?
See the link below for more detail where I found this information.
http://www.codeproject.com/Questions/246366/run-javascript-from-side-server-in-asp-net-and-csh
You can add your javascript from the server side after you bind your gridview.
protected void Page_Load(object sender, EventArgs e) {
String script = #"<script language=""Javascript"">
$(".gvCVRTRow").off();
$(".gvCVRTRow").click(function (e) {
ShowAddEditCVRT(this, "Edit");
});
function ShowAddEditCVRT(sender, AddEdit) {
$("#divCVRTDetails").fadeIn(300);
}
</script>";
Page.RegisterClientScriptBlock("experiment", script);
gvCVRT.Attributes.Add("DataBound", "TestJScript()");
I believe this replaces your FireJavascriptCallback("setArgAndPostBack ();");
EDIT
I changed the code to better match what you provided and also where to put the code. I think it should go under page load. I also changed the gvCVRT.Attributes.Add to make it so the javascript runs when the gvCVRT is databound.
Answer to this is I called the javascript by using FireJavascriptCallback("myFunction();"); then just put the javascript code I needed into this function.
FireJavascriptCallback is a function:
protected void FireJavascriptCallback(string JSFunctionName)
{
System.Web.UI.ScriptManager.RegisterClientScriptBlock(this.Page, this.Page.GetType(), "Callback", JSFunctionName, true);
}
I would like to modify the text values after the data has been returned from the database, I need to modify the MBS1270 and the MBS1263 to look like the others when displayed in the datagrid.
SelectCommand="SELECT PartNumber as 'Part Number', OnhandStockLevel as 'In Stock', DueIn as 'In Production' FROM vw_Rb_FreeStock WHERE PartNumber = 'UFP-0390B' OR PartNumber = 'UFP-0690B' OR PartNumber = 'MBS1270' OR PartNumber = 'MBS1263'">
Now, I have used the javascript to replace the values in body load, however, this messes up the sorting of the datagrid and makes the new replaced values appear on top still, because 'M' comes before 'U', and it still sorts based on the old value.
Javascript:
<script type="text/javascript">
function modText(original, replace) {
alert("Hello");
var find = original;
var repl = replace;
var page = document.body.innerHTML;
while (page.indexOf(find) >= 0) {
var i = page.indexOf(find);
var j = find.length;
page = page.substr(0, i) + repl + page.substr(i + j);
document.body.innerHTML = page;
}
</script>
I want to replace the MBS values with values 'UFP-1690B' and 'UFP-1290B'.
Is there any way to sort based on the replaced values? Or is there another approach I could take?
I tried to do something similar as to how you replace the column header using the 'AS' sql function but that failed, something like that would be perfect.
And no, I can't change the raw database value.
Gridview code:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
BackColor="White" BorderColor="#999999" BorderStyle="None" BorderWidth="1px"
CellPadding="3" CssClass="style1" DataKeyNames="Part Number"
DataSourceID="SqlDataSource1" GridLines="Vertical">
<RowStyle BackColor="#EEEEEE" ForeColor="Black" />
<Columns>
<asp:BoundField DataField="Part Number" HeaderText="Part Number"
ReadOnly="True" SortExpression="Part Number" />
<asp:BoundField DataField="In Stock" DataFormatString="{0:0}"
HeaderText="In Stock" SortExpression="In Stock" />
<asp:BoundField DataField="In Production" DataFormatString="{0:0}"
HeaderText="In Production" ReadOnly="True" SortExpression="In Production" />
</Columns>
<FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="#DCDCDC" />
</asp:GridView>
A month has been since this, but thought I'd add a final answer for anyone else with a similar problem.
I used the SQL REPLACE function, see: http://msdn.microsoft.com/en-us/library/ms186862.aspx
After that I combined the original data with the replaced data using UNION.
Final code:
SELECT REPLACE(REPLACE(PartNumber, 'MBS1269', 'UFP-1290S'), 'MBS1262', 'UFP-1690S') AS PartNumber... (and so on)
Output was absolutely perfect.
You can try with RowDataBound event
void GridView_RowDataBound(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
e.Row.Cells[1].Text = e.Row.Cells[1].Text.Replace("MBS","UFP");
}
}
You can add this to your Grid
<asp:gridview onrowdatabound="GridView_RowDataBound" />
i am stuck with this error since last few hours.. i dont know what am i doing wrong here..
<script type="text/javascript">
function viewProfile(index)
{
var GridID = document.getElementById("PersonGridView");
var row=GridID.rows[parseInt(index)+1];
window.open('detailsid.aspx?'+row);
}
</script>
<Columns>
<asp:BoundField HeaderText="First Name" DataField="FirstName" />
<asp:BoundField HeaderText="Last Name" DataField = "LastName" />
<asp:BoundField HeaderText="HomePhoneNumber" DataField="HomePhoneNumber" />
<asp:TemplateField HeaderText="ViewDetails">
<ItemTemplate>
<asp:Button ID="Deatils" runat="server" Text="Details" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:Button ID="Modify" runat="server" Text="Modify" />
<asp:Button ID="Delete" runat="server" Text="Delete" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#CCCC99" />
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
<SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
</div>
</form>
<p> Code Behind :
protected void PersonGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();
Button btnDetails = (Button)FindControl("Details");
Button btnModify = (Button)FindControl("Modify");
Button btnDelete = (Button)FindControl("Delete");
btnModify.CommandName = "Modify";
btnDelete.CommandName = "Delete";
btnDetails.CommandName = "Details";
btnDelete.CommandArgument = btnModify.CommandArgument = string.Format("{0}", ID);
btnDetails.Attributes["onclick"] = string.Format("viewProfile({0}); return false;", ID);
}
}
Change
var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();
if (e.Row.RowType == DataControlRowType.DataRow)
{
to
if (e.Row.RowType == DataControlRowType.DataRow)
{
var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();
i.e. extract the DataKeys only when the row is of DataRow and not for Header/Footer etc.
Is this the line that's throwing the error?:
var ID = PersonGridView.DataKeys[e.Row.RowIndex]["ID"].ToString();
This line is referencing an array item by index in two different places, so you'll need to do a little debugging to determine which one is the problem. Basically, either PersonGridView.DataKeys[] doesn't have an index which matches e.Row.RowIndex or that item doesn't have an index which matches "ID". You'll need to either step through a debugger to examine those values at runtime or toss in some debugging code (Response.Write statements and such to examine values) to see what's going on.
One common error is that the DataGridView is running this code on non-data rows. Header, footer, etc. You can expand the scope of the if statement to address that. Reference the indexes within the conditional rather than outside of it.
Edit: (In response to your comment below)
Is btnDetails set to an instance of an object? I'm guessing it isn't. You'll need to continue the debugging and see if the control you're trying to find is actually there. I notice that it's in a separate ItemTemplate and TemplateField from the other buttons. Is that causing an issue perhaps? I'm not entirely familiar with these server controls so I'm not sure off-hand.
I should take a moment to point out that your code here is very fragile. The problems you've been experiencing are the result of this. You're referencing arrays by indexes manually, including the use of a "magic string" to reference them. You might want to toss in some error checking for that. You're also casting and later using objects without checking if they exist first. FindControl can very easily return a null reference, such as when the control isn't found.
Throwing in tons of error checking is kind of part of the reality of using these web forms controls and their old data binding methods. A lot of extra code, but that's how it goes with these controls and directly binding to weakly-typed DataSets and such.