For developers: Delete form binder items
Deleting an item
Similarly to the For developers: RadGrid binder, FormBinder provides two ways of deleting the item: automatic and manual way. Since FormBinder, by its definition, always works with one single item - the delete functionality provided by it will delete only the currently bound item.
If you need simply to delete the item, you can use the automatic deletion approach - if, on the other hand, you need to implement some logic before the actual deletion occurs or you want to handle the deletion manually, you can use the manual deletion approach. In this article we are going to demonstrate both approaches.
Automatically deleting items
In case you are unfamiliar with the basics of the FormBinder, we suggest you read For developers: Form binder before. In this article we are going to solely concentrate on the task of deleting the item.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="StoresAutomaticDeletion.aspx.cs" Inherits="StoresAutomaticDeletion" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<%@ Register TagPrefix="sitefinity" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>
<
head
runat
=
"server"
>
<
title
>Automatic deletion of stores with Generic Collection client binder</
title
>
</
head
>
<
body
xmlns:sys
=
"javascript:Sys"
xmlns:dataview
=
"javascript:Sys.UI.DataView"
sys:activate
=
"*"
xmlns:code
=
"http://schemas.microsoft.com/aspnet/code"
>
<
form
id
=
"form1"
runat
=
"server"
>
<
asp:ScriptManager
ID
=
"scriptManager1"
runat
=
"server"
>
<
Scripts
>
<
asp:ScriptReference
Name
=
"MicrosoftAjax.js"
Path
=
"~/Sitefinity/Scripts/MicrosoftAjax.js"
/>
<
asp:ScriptReference
ScriptMode
=
"Inherit"
Path
=
"~/Sitefinity/Scripts/MicrosoftAjaxTemplates.js"
/>
<
asp:ScriptReference
ScriptMode
=
"Inherit"
Path
=
"~/Sitefinity/Scripts/MicrosoftAjaxAdoNet.js"
/>
</
Scripts
>
</
asp:ScriptManager
>
<
select
id
=
"storesDropDown"
runat
=
"server"
>
</
select
>
<
input
type
=
"button"
onclick
=
"OpenStore();"
value
=
"Open"
/>
<
sitefinity:GenericCollectionBinder
id
=
"storesBinder"
runat
=
"server"
TargetId
=
"storesDropDown"
ServiceUrl
=
"~/Sitefinity/Services/Commerce/Stores.svc"
BindOnLoad
=
"true"
DataKeyNames
=
"Id"
DataMembers
=
"Name, Id"
>
<
Containers
>
<
sitefinity:BinderContainer
ID
=
"BinderContainer1"
runat
=
"server"
RenderContainer
=
"false"
TemplateHolderTag
=
"SELECT"
>
<
option
value
=
"{{Id}}"
>{{Name}}</
option
>
</
sitefinity:BinderContainer
>
</
Containers
>
</
sitefinity:GenericCollectionBinder
>
<
div
id
=
"storeForm"
runat
=
"server"
>
</
div
>
<
sitefinity:FormBinder
ID
=
"storeFormBinder"
runat
=
"server"
TargetId
=
"storeForm"
ServiceUrl
=
"~/Sitefinity/Services/Commerce/Stores.svc"
BindOnLoad
=
"false"
AllowAutomaticDelete
=
"true"
OnClientDeleted
=
"StoreDeleted"
DataKeyNames
=
"Id"
DataMembers
=
"Id, Name, Description"
>
<
Containers
>
<
sitefinity:BinderContainer
ID
=
"BinderContainer2"
runat
=
"server"
>
<
fieldset
>
<
legend
>Store info:</
legend
>
<
ul
>
<
li
>
Store name: {{Name}}
</
li
>
<
li
>
Store description: {{Description}}
</
li
>
</
ul
>
</
fieldset
>
<
input
type
=
"button"
value
=
"Delete"
class
=
"deleteCommand"
/>
</
sitefinity:BinderContainer
>
</
Containers
>
</
sitefinity:FormBinder
>
<
script
type
=
"text/javascript"
>
function OpenStore() {
var storeId = $('#' + '<%= storesDropDown.ClientID %>').val();
var storeFormBinder = $find('<%= storeFormBinder.ClientID %>');
storeFormBinder.get_globalDataKeys()["Id"] = storeId;
storeFormBinder.DataBind();
}
function StoreDeleted(sender, args) {
var storesBinder = $find('<%= storesBinder.ClientID %>');
var storeFormBinder = $find('<%= storeFormBinder.ClientID %>');
storeFormBinder.ClearTarget();
storesBinder.DataBind();
}
</
script
>
</
body
>
</
html
>
The sample above was implemented as a standard stand-alone ASP.NET page.
The only thing we need to do in order to enable automatic deletion is to place an HTML element with a class of "deleteCommand" inside of the binder and set theAllowAutomaticDelete property to true. Once this element is clicked, binder will automatically delete currently bound item.
Binder setup: If you are developing inside of the Sitefinity CMS admin area, it is not necessary to declare ScriptManager control or add anything to the body element, since all this has been implemented on the base Sitefinity CMS admin page.
<
input
type
=
"button"
value
=
"Delete"
class
=
"deleteCommand"
/>
While this alone is enough to delete an item, we have also demonstrated how to take advantage of the OnClientDeleted event, which is fired after the binder has deleted the item. If you examine the declaration of the FormBinder you will notice that we have instructed the binder to call StoreDeleted javascript function after the item has been deleted:
<
sitefinity:FormBinder
ID
=
"storeFormBinder"
runat
=
"server"
TargetId
=
"storeForm"
ServiceUrl
=
"~/Sitefinity/Services/Commerce/Stores.svc"
BindOnLoad
=
"false"
AllowAutomaticDelete
=
"true"
OnClientDeleted
=
"StoreDeleted"
DataKeyNames
=
"Id"
DataMembers
=
"Id, Name, Description"
>
<
Containers
>
<
sitefinity:BinderContainer
ID
=
"BinderContainer2"
runat
=
"server"
>
<
fieldset
>
<
legend
>Store info:</
legend
>
<
ul
>
<
li
>
Store name: {{Name}}
</
li
>
<
li
>
Store description: {{Description}}
</
li
>
</
ul
>
</
fieldset
>
<
input
type
=
"button"
value
=
"Delete"
class
=
"deleteCommand"
/>
</
sitefinity:BinderContainer
>
</
Containers
>
</
sitefinity:FormBinder
>
Then, we have implemented the StoreDeleted function as follows:
function
StoreDeleted(sender, args) {
var
storesBinder = $find(
'<%= storesBinder.ClientID %>'
);
var
storeFormBinder = $find(
'<%= storeFormBinder.ClientID %>'
);
storeFormBinder.ClearTarget();
storesBinder.DataBind();
}
The implementation of this function is rather trivial. First we are getting the references to the client components of both binders. Then we clear the target (target control) of the FormBinder, because we have deleted the item that was displayed in it. Alternatively, we could have loaded the first item after the deleted item or something along these lines. Finally, we are rebinding the CollectionBinder which we use as a store selector, in order to reflect the changes that have occurred after we have deleted the store (namely, deleted store should not exist as an option in selector anymore).
Manually deleting items
If we wish to perform some additional logic before the deleting or we want to completely handle the process of deleting an item, we can take the second approach: deleting an item manually. The approach is almost identical to the one For developers: Delete RadGrid binder items.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="StoresManualDeletion.aspx.cs" Inherits="StoresManualDeletion" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI" %>
<%@ Register TagPrefix="sitefinity" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>
<
head
id
=
"Head1"
runat
=
"server"
>
<
title
>Manual deleting of stores with Generic Collection client binder</
title
>
</
head
>
<
body
xmlns:sys
=
"javascript:Sys"
xmlns:dataview
=
"javascript:Sys.UI.DataView"
sys:activate
=
"*"
xmlns:code
=
"http://schemas.microsoft.com/aspnet/code"
>
<
form
id
=
"form1"
runat
=
"server"
>
<
asp:ScriptManager
ID
=
"scriptManager1"
runat
=
"server"
>
<
Scripts
>
<
asp:ScriptReference
Name
=
"MicrosoftAjax.js"
Path
=
"~/Sitefinity/Scripts/MicrosoftAjax.js"
/>
<
asp:ScriptReference
ScriptMode
=
"Inherit"
Path
=
"~/Sitefinity/Scripts/MicrosoftAjaxTemplates.js"
/>
<
asp:ScriptReference
ScriptMode
=
"Inherit"
Path
=
"~/Sitefinity/Scripts/MicrosoftAjaxAdoNet.js"
/>
</
Scripts
>
</
asp:ScriptManager
>
<
select
id
=
"storesDropDown"
runat
=
"server"
>
</
select
>
<
input
type
=
"button"
onclick
=
"OpenStore();"
value
=
"Open"
/>
<
sitefinity:GenericCollectionBinder
id
=
"storesBinder"
runat
=
"server"
TargetId
=
"storesDropDown"
ServiceUrl
=
"~/Sitefinity/Services/Commerce/Stores.svc"
BindOnLoad
=
"true"
DataKeyNames
=
"Id"
DataMembers
=
"Name, Id"
>
<
Containers
>
<
sitefinity:BinderContainer
ID
=
"BinderContainer1"
runat
=
"server"
RenderContainer
=
"false"
TemplateHolderTag
=
"SELECT"
>
<
option
value
=
"{{Id}}"
>{{Name}}</
option
>
</
sitefinity:BinderContainer
>
</
Containers
>
</
sitefinity:GenericCollectionBinder
>
<
div
id
=
"storeForm"
runat
=
"server"
>
</
div
>
<
sitefinity:FormBinder
ID
=
"storeFormBinder"
runat
=
"server"
TargetId
=
"storeForm"
ServiceUrl
=
"~/Sitefinity/Services/Commerce/Stores.svc"
BindOnLoad
=
"false"
OnClientItemDeleteCommand
=
"StoreDeleteCommand"
DataKeyNames
=
"Id"
DataMembers
=
"Id, Name, Description"
>
<
Containers
>
<
sitefinity:BinderContainer
ID
=
"BinderContainer2"
runat
=
"server"
>
<
fieldset
>
<
legend
>Store info:</
legend
>
<
ul
>
<
li
>
Store name: {{Name}}
</
li
>
<
li
>
Store description: {{Description}}
</
li
>
</
ul
>
</
fieldset
>
<
input
type
=
"button"
value
=
"Delete"
class
=
"deleteCommand"
/>
</
sitefinity:BinderContainer
>
</
Containers
>
</
sitefinity:FormBinder
>
<
script
type
=
"text/javascript"
>
function OpenStore() {
var storeId = $('#' + '<%= storesDropDown.ClientID %>').val();
var storeFormBinder = $find('<%= storeFormBinder.ClientID %>');
storeFormBinder.get_globalDataKeys()["Id"] = storeId;
storeFormBinder.DataBind();
}
function StoreDeleteCommand(sender, args) {
if (confirm('Are you sure you want to delete this store?') == true) {
var key = args.get_key();
sender.DeleteItem(key);
sender.ClearTarget();
var storesBinder = $find('<%= storesBinder.ClientID %>');
storesBinder.DataBind();
}
}
</
script
>
</
body
>
</
html
>
Namely, we subscribe to the OnClientItemDeleteCommand event of the FormBinder and instruct the FormBinder to call StoreDeleting javascript function just before it deletes the item.
Binder setup: If you are developing inside of the Sitefinity CMS admin area, it is not necessary to declare ScriptManager control or add anything to the body element, since all this has been implemented on the base Sitefinity CMS admin page.
<
sitefinity:FormBinder
ID
=
"storeFormBinder"
runat
=
"server"
TargetId
=
"storeForm"
ServiceUrl
=
"~/Sitefinity/Services/Commerce/Stores.svc"
BindOnLoad
=
"false"
OnClientItemDeleteCommand
=
"StoreDeleteCommand"
DataKeyNames
=
"Id"
DataMembers
=
"Id, Name, Description"
>
<
Containers
>
<
sitefinity:BinderContainer
ID
=
"BinderContainer2"
runat
=
"server"
>
<
fieldset
>
<
legend
>Store info:</
legend
>
<
ul
>
<
li
>
Store name: {{Name}}
</
li
>
<
li
>
Store description: {{Description}}
</
li
>
</
ul
>
</
fieldset
>
<
input
type
=
"button"
value
=
"Delete"
class
=
"deleteCommand"
/>
</
sitefinity:BinderContainer
>
</
Containers
>
</
sitefinity:FormBinder
>
Then we implement the StoreDeleteCommand function in following manner:
function
StoreDeleteCommand(sender, args) {
if
(confirm(
'Are you sure you want to delete this store?'
) ==
true
) {
var
key = args.get_key();
sender.DeleteItem(key);
sender.ClearTarget();
var
storesBinder = $find(
'<%= storesBinder.ClientID %>'
);
storesBinder.DataBind();
}
}
In the implementation of this function we prompt the user for confirmation of the given action. If user confirms the action, we get the key of the item, then delete it through the binder and clear the binder's target (since the displayed item has just been deleted).
After that, we get the reference to our selector binder and rebind it in order to reflect the changes that have just happened (namely, one store has been deleted).