I have spent all day trying to achieve this but have failed spectacularly.
I have an ASP.Net repeater on my page and have added a LinkButton which pops open a beautiful Bootstrap 3 confirmation modal window (for deletion of a record).
I have tried to cobble together solutions but my Java knowledge is failing me.
This is my Repeater:
<asp:Repeater OnItemCommand="rptImages_ItemCommand" ID="rptImages" OnItemCreated="rptImages_ItemCreated" OnItemDataBound="rptImages_ItemDataBound" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
<asp:Image ID="imgThumb" CssClass="product-image" runat="server" ImageUrl='<%# string.Format("~/{0}", Eval("ImageUrl")) %>' />
<asp:LinkButton ID="lbDelete" runat="server" CommandArgument='<%#Eval("ProductImageId")%>' CommandName="delete" data-toggle="tooltip" data-placement="top" title="Delete this record" OnClientClick="return ConfirmDelete()"><i class="image-button fa fa-trash"></i></asp:LinkButton>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
This is my Java Script at the top of the page:
<script>
function ConfirmDelete() {
$('#DeleteModal').modal(); // initialized with defaults
// $('#DeleteModal').modal({ keyboard: false }) // initialized with no keyboard
// $('#DeleteModal').modal('show')
return false;
}
</script>
This is the code of my Bootstrap Pop-up:
<div class="modal fade" id="DeleteModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="H3">Delete this record?</h4>
</div>
<asp:UpdatePanel ID="upDel" runat="server">
<ContentTemplate>
<div class="modal-body">
Are you sure you want to delete this image?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<asp:Button ID="btnDeleteImage" runat="server" OnClick="btnDeleteImage_Click" CssClass="btn btn-danger" Text="Delete" />
</div>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnDeleteImage" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</div>
</div>
</div>
When I click the delete button, the bootstrap modal appears. On the "Cancel" button, the modal closes. On the "Delete" button, the modal also closes but my gridview item command never fires.
I would be eternally grateful for any help.
Thank you very much in advance!
First, I see some markup for an UpdatePanel
which I don't believe is necessary. Generally speaking, when it comes to UpdatePanels
it's better to get things working first and then implement them later if truly needed.
So, in looking at this more closely I want to make sure you understand the difference between a synchronous call versus an asynchronous call.
If you took advantage of the built in js confirm()
modal things would work as expected:
OnClientClick="return window.confirm('Are you sure you want to delete this image')"
This works because the built-in confirm()
function is synchronous, meaning it waits for a user response before returning.
However, Bootstrap modals are asynchronous which means this:
OnClientClick="return ConfirmDelete()"
calls this:
function ConfirmDelete()
{
$('#DeleteModal').modal(); // initialized with defaults
return false;
}
which, because the call to .modal()
is asynchronous causes it to return immediately and so ConfirmDelete()
exits and returns false, which is good because it prevents the postback and allows the modal to be displayed. Otherwise the page would postback and you'd never see the modal.
Now, at this point, because ConfirmDelete()
has already returned, you are now outside the world of the repeater. So the one thing you have to do is pass to the modal the unique key data associated with the repeater row that activated the modal such that on confirmation you delete the appropriate record.
Once you click btnDeleteImage
it's going to cause a postback to btnDeleteImage_Click
in your code behind. This is where you add the code to delete the appropriate record.
How do you pass along that key data?
One possibility is to fill one or more HiddenField
that are referenced on postback. Hidden fields are a good way to pass data between Client side and Server side code.
so let's say you add this to your .aspx page:
<asp:HiddenField ID="hfDeleteParameter1" runat="server" ClientIDMode="Static" />
NB:
ClientIDMode="Static"
prevents the id from getting name mangled so it can be referenced as expected in client side js code.
So then in the ItemDataBound event you can build the OnClientClick
function call programmatically where you pass key data as a parameter:
This is VB, if you use C# it should be similar.
Private Sub rptImages_ItemDataBound(sender As Object, e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rptImages.ItemDataBound
If e.Item.ItemType = ListItemType.Item Or
e.Item.ItemType = ListItemType.AlternatingItem Then
Dim lb As LinkButton = e.Item.FindControl("lbDelete")
lb.OnClientClick = String.Format("return ConfirmDelete('{0}');",
row_specific_key_data)
End If
End Sub
and in the js:
function ConfirmDelete(rowData) {
$('#hfDeleteParameter1').val( rowData );
$('#DeleteModal').modal(); // initialized with defaults
return false;
}
Then when the user confirms delete by clicking btnDeleteImage
this will cause a postback and calls the buttons Click event btnDeleteImage_Click
where you can access the hidden field:
Private Sub btnDeleteImage_Click(sender As Object, e As EventArgs) Handles btnCustomLookback.Click
dim keydata as string = hfDeleteParameter1.value
// do delete
End Sub
This is one option of many.
For the record you could make a call to the repeaters DataSource Delete operation, but you would need to fill the parameters and then call DataSource.delete()
but that's not really how this is suppose to work.
Delete/Update/Insert operations defined in a server control datasource are intended for use by that control, it automatically manages the parameters. To call delete() operations like this, where you have to override those managed parameters, is a bad habit to get into.
So you need to write a custom delete function which acts on the correct key information.