Submitting a form via AJAX
So here's my use case: On our site we usually have several forms that popup in a modal, and also submit in a modal. Ideally, when someone submits a form this way, it would post the form back via AJAX, and then redisplay the results in the modal without causing a full page POST.
Has anyone done this with Sitefinity? I can't find anything in the way of documentation on doing it, but here are my three ideas for how to accomplish it:
1. A modal masterpage that has nothing on it but some embedded Javascript to handle the postback. This has the added benefit of allowing my content authors to easily create the modal content separately, but it would require some discipline on their side to link things right, etc. This also looks like the simplest solution to get back JUST the content I want after a form submit, instead of submitting the whole form.
2. Say screw it and put an iframe in the modal (I don't want to do this at all).
3. Create a new widget that inherits from FormsControl and includes the Javascript logic to submit just the form back, or a new form submit button control that can be dropped onto actual forms that would handle it. The former is probably more ideal, and where I'm heading right now, but I'm a little lost on how to implement it most efficiently.
Again, if someone has done this before, I'd love some insight. Here's where I am on #3.
I have a widget that inherits and does everything the Form widget does. The problem I'm hitting right now is due to the web forms nature of things here. If I have multiple forms on a page, I do NOT want to hook the form submit event since I will hook it for EVERY form on the page then... Instead I need to just hook this one specific form submitting. I can then use something like the jQuery Form plugin to serialize the form and submit it to the server, but then I am also going to get back the whole page again as a result. I could limit my load to the specific ClientId of the success and error messages and pull just those, but it's inefficient. In theory at least, I haven't actually implemented all this yet, but that's my current thought process.
Why not use a jquery call to post the data back to a webservice, it's crazy simple :)
http://www.sitefinitysteve.com/blog/code/2012/03/16/simple-wcf-by-sitefinity
I do this method a lot by using a KendoUI Modal Window to send the data back, and on success method of the $.ajax call I just change the window content (or close it)
Would that work?
Not quite. I need to take the Forms Control and submit it via normal channels, I just need to do it via AJAX. Building a whole service to do this just seems like tremendous overkill. now submitting it to the EXISTING FormsService.svc in some way might have some merit, but I have no idea what that would really look like...
Oh sorry I thought you meant like "Form data" not literally a sitefinity "form"
What if...
Custom forms control (inheriting from the default) is just wrapped in an (ugly old) MsAjax update panel? Then handle the response to do something? http://www.telerik.com/help/aspnet-ajax/ajax-onresponseend.html. The only reason I say custom forms control is that you could then hook into the events and perhaps change the result message (you said you want to show results?)
I have avoided the MS AJAX controls and such like the plague...
<%@ Control Language=
"C#"
%>
<%@ Register TagPrefix=
"sfFields"
Assembly=
"Telerik.Sitefinity"
Namespace=
"Telerik.Sitefinity.Web.UI.Fields"
%>
<%@ Register TagPrefix=
"sf"
Namespace=
"Telerik.Sitefinity.Web.UI"
Assembly=
"Telerik.Sitefinity"
%>
<asp:UpdatePanel ID=
"ModalFormUpdatePanel"
UpdateMode=
"Conditional"
ChildrenAsTriggers=
"True"
runat=
"server"
>
<ContentTemplate>
<sfFields:FormManager id=
"formManager"
runat=
"server"
/>
<asp:Panel ID=
"errorsPanel"
runat=
"server"
CssClass=
"sfErrorSummary"
/>
<sf:SitefinityLabel id=
"successMessage"
runat=
"server"
WrapperTagName=
"div"
HideIfNoText=
"true"
CssClass=
"sfSuccess"
/>
<asp:Panel ID=
"formControls"
runat=
"server"
>
</asp:Panel>
</ContentTemplate>
</asp:UpdatePanel>
I have avoided the MS AJAX controls and such like the plague...
I dont blame you :) Are there any script errors, if you edit your page properties is there a scriptmanager\viewstate enabled on the page (the checkbox)?
There is a ScriptManager on the Master page, but not on the control. Adding a second ScriptManager to the control didn't exactly help anything either.
Well...to be honest...I am stumped! :/ I dont have time to fire up an instance and see if I can get it working for you in some way, sorry :/
No problem. Thanks for the idea. I'm just not sure how to get an UpdatePanel to work inside of a Sitefinity widget. Maybe my support ticket will yield an answer for that, or some other solution.
I have a fancy-schmancy contact-form widget, that I built as part of an assembly. When the user clicks submit, it does some client validation first, if there is an error it displays the error status otherwise it submits via ajax, where further checking is done. If everything is ok, then the 'form' is submitted, and the client is taken to the 'thankyou' page - but if not ok, it updates the error-status elements via Ajax, and allows the user to continue.
I didn't have the time to get my head around the whole restful service thing when I did this, and had never used the jQuery ajax thingy, so I just resorted to my trusty old 'friend' (LOL) the Telerik AjaxManager.
It's big, and inefficient because it's a callback (with the associated full-blown page-cycle) but it works, and I can manage both the Ajax Call-Response at the client and the CallBack-Redirect-Response at the server.
Just a passing comment... may or may not be worth trying in this case.
I'd be interested in seeing your solution using the AjaxManager as an alternative MB...
using
Telerik.Sitefinity.Modules.Forms.Web.UI;
using
Telerik.Sitefinity.Modules.Forms.Web.UI.Designers;
namespace
NSC.Sitefinity.Modules.ModalForm
/// <summary>
/// Email Forms Control.
/// </summary>
[Telerik.Sitefinity.Web.UI.ControlDesign.ControlDesigner(
typeof
(FormsControlDesigner))]
public
class
ModalFormControl : FormsControl
/// <summary>
/// Layout template name.
/// </summary>
private
const
string
_layoutTemplateName =
"NSC.Sitefinity.Modules.ModalForm.Resources.Views.ModalFormControl.ascx"
;
#region Properties
/// <summary>
/// Gets the name of the layout template.
/// </summary>
protected
override
string
LayoutTemplateName
get
return
_layoutTemplateName;
#endregion
Ok, I still haven't given up on the UpdatePanel... So I'm looking to add a trigger to the update panel that will make the update panel trigger... something along the lines of this:
var submitButtons = FieldControls.Where(x => x
is
FormSubmitButton);
foreach
(FormSubmitButton submitButton
in
submitButtons)
UpdatePanel.Triggers.Add(
new
AsyncPostBackTrigger ControlID = submitButton.ID );
Hi Michael,
Just curious To see of you found a solution to this. I running into the exact same issue.
Cheers
Hello Jason,
I would advise to modify the widget template as this seems to be the easiest and tested solution:
<%@ Control Language="C#" %>
<%@ Register TagPrefix="sfFields" Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" %>
<%@ Register TagPrefix="sf" Namespace="Telerik.Sitefinity.Web.UI" Assembly="Telerik.Sitefinity" %>
<
sfFields:FormManager
id
=
"formManager"
runat
=
"server"
/>
<
asp:UpdatePanel
ID
=
"UpdatePanel1"
runat
=
"server"
>
<
ContentTemplate
>
<
asp:Panel
ID
=
"errorsPanel"
runat
=
"server"
CssClass
=
"sfErrorSummary"
Visible
=
"false"
/>
<
sf:SitefinityLabel
id
=
"successMessage"
runat
=
"server"
WrapperTagName
=
"div"
HideIfNoText
=
"true"
CssClass
=
"sfSuccess"
/>
<
asp:Panel
ID
=
"formControls"
runat
=
"server"
>
</
asp:Panel
>
</
ContentTemplate
>
</
asp:UpdatePanel
>
You need to map this template in your widget or even for entire Sitefinity from Administration > Settings > Advanced > Controls > ViewMap.
HostType: Telerik.Sitefinity.Modules.Forms.Web.UI.FormsControl
LayoutTemplatePath: ~/yourTemplate.ascx
Regards,