Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Alex Skrypnyk 5908 posts 22603 karma points MVP 4x admin c-trib
    Sep 20, 2016 @ 17:33
    Alex Skrypnyk
    0

    Ajax Umbraco Forms

    Hi Community,

    What is the best way of doing Ajax Umbraco Forms?

    Is it possible out of the box in latest version?

    Thanks,

    Alex

  • Amir Khan 1199 posts 2567 karma points
    Sep 20, 2016 @ 19:32
    Amir Khan
    1

    See the method posted by Thomas here, it works with some simple updates to the main view for the form: https://our.umbraco.org/forum/umbraco-pro/contour/60788-Umbraco-Forms-and-Ajax#comment-233528

  • Alex Skrypnyk 5908 posts 22603 karma points MVP 4x admin c-trib
    Sep 20, 2016 @ 20:10
    Alex Skrypnyk
    0

    Thanks, Amir, nice solution, will try.

    Maybe something easier?

    Thanks

  • Alex Skrypnyk 5908 posts 22603 karma points MVP 4x admin c-trib
    Sep 22, 2016 @ 20:10
    Alex Skrypnyk
    101

    Solved! This code works for me:

    <script type="text/javascript">
            $(document)
                .ready(function() {
                    //Intercept Submit button in order to make ajax call instead of a postback
                    $('#contour_form_@FORMID').preventDoubleSubmission();
                });
    
    // jQuery plugin to prevent double submission of forms
        jQuery.fn.preventDoubleSubmission = function () {
            $(this).on('submit', function (e) {
                e.preventDefault();
    
                var $form = $(this);
    
                if ($form.data('submitted') === true) {
                    // Previously submitted - don't submit again
                } else {
                    if ($form.valid()) {
                        // Mark it so that the next submit can be ignored
                        $form.data('submitted', true);
    
                        // Make ajax call form submission
                        $.ajax({
                            url: $form.attr('action'),
                            type: 'POST',
                            cache: false,
                            data: $form.serialize(),
                            success: function (result) {
                                console.log(result);
    
                                var thankYouMessage = $(result).find('.contourMessageOnSubmit');
                                $('#contour_form_@FORMID').html(thankYouMessage);
    
                            }
                        });
                    }
                }
            });
    
            // Keep chainability
            return this;
        };
        </script>
    

    Thanks,

    Alex

  • Danny Summers 22 posts 82 karma points
    Dec 18, 2018 @ 07:46
    Danny Summers
    3

    2018 now and this solution came in handy. I reworked it slightly to suit the change of class names to "umbraco-forms" and to make it more generic (so this would go in a generic JS file).

    $(document).ready(function() {
        //Intercept Submit button in order to make ajax call instead of a postback
        $('.umbraco-forms-form form').preventDoubleSubmission();
    });
    
    // jQuery plugin to prevent double submission of forms
        jQuery.fn.preventDoubleSubmission = function () {
            $(this).on('submit', function (e) {
                e.preventDefault();
    
                var $form = $(this);
    
                if ($form.data('submitted') === true) {
                    // Previously submitted - don't submit again
                } else {
                    if ($form.valid()) {
                        // Mark it so that the next submit can be ignored
                        $form.data('submitted', true);
    
                        // Make ajax call form submission
                        $.ajax({
                            url: $form.attr('action'),
                            type: 'POST',
                            cache: false,
                            data: $form.serialize(),
                            success: function (result) {
                                var thankYouMessage = $(result).find('.umbraco-forms-submitmessage').first();
                                $form.html(thankYouMessage);
                            }
                        });
                    }
                }
            });
    
            // Keep chainability
            return this;
        };
    
  • Alex Skrypnyk 5908 posts 22603 karma points MVP 4x admin c-trib
    Dec 18, 2018 @ 10:24
    Alex Skrypnyk
    0

    Hi Danny

    Thank you so much for sharing!!!

    Alex

  • Amir Khan 1199 posts 2567 karma points
    Dec 18, 2018 @ 14:31
    Amir Khan
    0

    Do you guys think it would be useful to turn this into a package or Forms theme? I remember the first time implementing this for contour years ago and it was a challenge to even find where to put these scripts.

    Would be nice if it were more plug and play and could be updated in one place as the markup / scripts for Forms evolve.

    I'd be happy to do it if so.

    -Amir

  • Danny Summers 22 posts 82 karma points
    Dec 19, 2018 @ 02:29
    Danny Summers
    0

    I don't think a package would add much value with my tweaked solution above, as it's not a C# solution, but simple JQuery. This is generic and would just be thrown into a JS file (either in the head of end of should work).

    That earlier Contour solution (where it included some Razor), would have needed to be included in a specific razor file to work.

  • Stefano 61 posts 312 karma points c-trib
    Feb 06, 2019 @ 09:37
    Stefano
    0

    I don't think this will work with multi-steps forms and be compatible with thank you pages redirection tho!

  • Alex Skrypnyk 5908 posts 22603 karma points MVP 4x admin c-trib
    Feb 06, 2019 @ 10:28
    Alex Skrypnyk
    0

    Hi Stefano, you are right. It's not a perfect solution.

  • Stefano 61 posts 312 karma points c-trib
    Feb 06, 2019 @ 10:41
    Stefano
    0

    Spent a few hours on this and here are my findings:

    • https://github.com/jeppe-smith/umbraco-ajax-form seems a good place to start if you want ajax. I didn't test it but the code seems to support multi-steps forms
    • ajax protocol can't detect redirects, the browser makes it invisible for it. This can be done with a new API called fetch which has around 85% users support according to canisue
    • Seems a bit of a can of worms. I don't think you'll be able to remove the "redirect to page" functionality from forms itself, so fundamentally you'd be breaking a core functionality of Umbraco Forms. Bad karma.
    • What I thought I could do in my case was to rely on something on the page so that I know that the response is a different URL (e.g. I've been redirected). Canonical meta tags are a good candidate. I could just do
      • Get result html
      • Get canonical meta value
      • Is it the same url ? (handle fragments, query strings and protocols here)
      • If different it was a redirect, redirect to that page.
      • This sounds a bit hacky and would avoid if not necessary
  • Stefano 61 posts 312 karma points c-trib
    Feb 06, 2019 @ 11:09
    Stefano
    1

    I've just tested this solution which as un-sexy as it is is dead simple and works with all Umbraco Forms functionality

    USE CODE FROM MY NEXT ANSWER INSTEAD!

    // Find a submit message that is not wrapped in a form (the message is always present even when not visible
    // as the form has just been loaded.
    let message = $('.umbraco-forms-submitmessage:not(form .umbraco-forms-submitmessage)').first();
    if(message)
    {
      // Scroll page to the submit message. Here 20 is just to add some margin, but you could need to add
      // the height of your sticky navbar too.
      let targetOffset = message.offset().top - 20;
      $('html,body').animate({scrollTop: targetOffset});
    }
    

    This however doesn't scroll down to the 2nd+ step of forms, so I'll have a look at that now

  • Alex Skrypnyk 5908 posts 22603 karma points MVP 4x admin c-trib
    Feb 06, 2019 @ 11:12
    Alex Skrypnyk
    0

    awesome finding Stefano, didn't try umbraco-ajax-form but it looks interesting

  • Stefano 61 posts 312 karma points c-trib
    Feb 06, 2019 @ 15:30
    Stefano
    1

    I'll one up myself by supporting multi pages forms, and I've opened a ticket in regards to previous pages hidden field not being populated:

    $(document).ready(function () {
        function scrollToFormIfInteractedWith() {
          // Find a target to scroll to if the user is interacting with forms. This happens in different ways:
          // - Find a submit message that is not wrapped in a form (the message is always present even when not visible
          // as the form has just been loaded.
          // - If the message wasn't found then try to target a form containing a hidden field that indicates that the form's
          // step/page is not the first(0) one.
          // - If that wasn't found either then try to find a form that has PreviousClicked = true where the user just
          // navigated back. This is CURRENTLY NOT WORKING possibly because of an Umbraco Forms issue for which I've raise
          // a github issue here https://github.com/umbraco/Umbraco-CMS/issues/4443.
          let target = $('.umbraco-forms-submitmessage:not(form .umbraco-forms-submitmessage)')[0]
              || $('input[type="hidden"][name="FormStep"]:not([value="0"]),'
                  + 'input[type="hidden"][name="PreviousClicked"][value="true"]').parent('form')[0];
    
          // If we have found a target to scroll to then smooth scroll there.
          if (target) {
            // Scroll page to the target. Here 20 is just to add some margin, but you could need to add
            // the height of your sticky navbar too.
            let targetOffset = $(target).offset().top - 20;
            $('html,body').animate({scrollTop: targetOffset});
          }
        }
    
        scrollToFormIfInteractedWith();
      });
    
  • Danny Summers 22 posts 82 karma points
    Feb 08, 2019 @ 00:19
    Danny Summers
    0

    Just to expand on the AJAX approach, which still doesn't address the issue with multi step forms & redirections, but thought I should document my tweaks here as this will come up for others also.

    Our original AJAX solution doesn't work with posting files to the server and with handling Recaptcha errors. A long way from perfect, but my basic code tweak is below:

    $(document).ready(function() {
        //Intercept Submit button in order to make ajax call instead of a postback
        $('.umbraco-forms-form form').preventDoubleSubmission();
    });
    
    // jQuery plugin to prevent double submission of forms
    jQuery.fn.preventDoubleSubmission = function () {
        $(this).on('submit', function (e) {
            e.preventDefault();
    
            var $form = $(this);
    
        if ($form.data('submitted') === true) {
            // Previously submitted - don't submit again
        } else {
            if ($form.valid()) {
                // Mark it so that the next submit can be ignored
                $form.data('submitted', true);
    
                // Make ajax call form submission
                $.ajax({
                    url: $form.attr('action'),
                    type: 'POST',
                    cache: false,
                    data: new FormData(this),
                    processData: false,
                    contentType: false,
                    success: function (result) {
                        var thankYouMessage = $(result).find('.umbraco-forms-submitmessage').first();
                        //Handles edge case where Recaptcha wasn't checked
    
                        if (thankYouMessage.length == 0) {
                            $(result).find('.field-validation-error').each(function (i, v) {
                                window.alert($(v).text());
                            });
    
                            $form.data('submitted', false);
                        }
                        else {
                            $form.html(thankYouMessage);
                        }
                    }
                });
            }
        }
    });
    
    // Keep chainability
    return this;
    };
    
  • Matthew 4 posts 74 karma points
    Dec 09, 2020 @ 23:18
    Matthew
    0

    Has anyone tried this solution with the latest version of forms? I'm trying this with 8.6 and the page still reloads on submit. The return message shows first and then the page reloads almost as if it's ignoring preventDefault? I've tried to figure this out all day and have had no lucky. Any suggestions?

  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies