I'm trying to make a jQuery confirm dialog call a web method. The dialog is called when the delete button in a GridView in an UpdatePanel is clicked.
However, when I click on the button, an error "Invalid postback or callback argument." I searched through some of the questions/answers here and tried overriding the Render event to register the UpdatePanel.
Here's my aspx page:
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="DoPostBack._Default" %>
<asp:Content ID="conStyles" runat="server" ContentPlaceHolderID="cphStyles">
</asp:Content>
<asp:Content ID="conMain" runat="server" ContentPlaceHolderID="cphMain">
<asp:UpdatePanel ID="upMovies" runat="server" UpdateMode="Conditional" onload="upMovies_Load">
<ContentTemplate>
<asp:GridView ID="gvItems" runat="server" CssClass="tbl-movies" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" HeaderStyle-CssClass="col-title-header" ItemStyle-CssClass="col-title"/>
<asp:BoundField DataField="Director" HeaderText="Director" HeaderStyle-CssClass="col-director-header" ItemStyle-CssClass="col-director" />
<asp:BoundField DataField="Year" HeaderText="Year" HeaderStyle-CssClass="col-year-header" ItemStyle-CssClass="col-year" />
<asp:TemplateField ItemStyle-HorizontalAlign="Left" ItemStyle-CssClass="table-actions">
<ItemTemplate>
<asp:ImageButton ID="btnEdit" ImageUrl="Images/edit.png" runat="server"
Text="Edit" UseSubmitBehavior="False" />
<asp:ImageButton ID="btnDelete" ImageUrl="Images/delete.png" runat="server"
Text="Delete" UseSubmitBehavior="False" CssClass="btn-delete-movie" />
<asp:HiddenField ID="hfMovieId" runat="server" Value='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
<div id="confirmDelete" class="popup popup-confirm">
<div class="popup-title">
<h4>Delete Movie</h4>
</div>
<div class="popup-content">
<div class="confirm-message">
</div>
<div class="buttons center">
<input id="btnDeleteConfirm" type="button" value="OK" class="button btn-confirm" />
<input id="btnDeleteCancel" type="button" value="Cancel" class="button btn-delete-cancel btn-close-popup" />
</div>
</div>
</div>
</asp:Content>
<asp:Content ID="conScripts" runat="server" ContentPlaceHolderID="cphScripts">
<script src="Scripts/site.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
var btnDelete = $('.btn-delete-movie');
btnDelete.on('click', function (e) {
e.preventDefault();
var row = $(this).closest('tr'),
title = row.find('.col-title').text(),
movieId = parseInt(row.find('input[type=hidden]').val());
showConfirmPopUp('confirmDelete',
'Are you sure you want to delete the movie "' + title + '"?',
function () { deleteMovie(movieId); }, //call the DeleteMovie web method
function () { }); //do nothing else
});
});
function deleteMovie(id) {
$.ajax({
type: 'POST',
contentType: 'application/json',
data: '{"id":' + id + '}',
url: 'Default.aspx/DeleteMovie',
dataType: 'json',
success: function (data) {
__doPostBack('<%= upMovies.ClientID %>', '');
closePopUp('confirmDelete');
},
error: function (jqXHR, textStatus, errorThrown) {
showError(jqXHR, textStatus, errorThrown);
}
});
}
</script>
</asp:Content>
Code-behind:
public partial class _Default : System.Web.UI.Page
{
#region Events
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
PopulateMovies();
}
}
protected override void Render(HtmlTextWriter writer)
{
ClientScript.RegisterForEventValidation(upMovies.UniqueID);
foreach (GridViewRow row in gvItems.Rows)
{
var btnDelete = row.FindControl("btnDelete");
var btnEdit = row.FindControl("btnEdit");
ClientScript.RegisterForEventValidation(btnDelete.UniqueID);
ClientScript.RegisterForEventValidation(btnEdit.UniqueID);
}
base.Render(writer);
}
protected void upMovies_Load(object sender, EventArgs e)
{
PopulateMovies();
}
#endregion
#region Private Methods
private void PopulateMovies()
{
var data = from m in Movie.GetAll()
orderby m.Year descending, m.Title ascending
select m;
gvItems.DataSource = data;
gvItems.DataBind();
}
#endregion
#region Web Methods
[WebMethod]
public static object DeleteMovie(int id)
{
Movie.Delete(id);
return UpdateItems();
}
#endregion
}
I'm using the jQuery approach because I don't want to use the ModalPopupExtender. I don't want to set EnableEventValidation to false either.
Also, why is the upMovies_Load called when I click on the delete button? Shouldn't it only be called when the ok button of the confirm dialog is clicked?
I'm kind of a beginner, help would be greatly appreciated.
Thank you :)
Okay, you have to rebind the JavaScript again via