Search code examples
javascriptjqueryfueluxformvalidation.io

Fuelux wizard and formvalidation.io - an ajax


I am currently having some troubles getting an ajax submit work with this two plugins, does anyone know how it should be looking? Since for now it submits without the ajax part to self - the same address as execution. I got really no idea where the ajax part should be and what will trigger the formvalidation.io submit handler - since I guess it should be called from on('success.form.fv')

Formvalidation.io part

$('#orderForm').find('input[name="radioclient"]')
                .on('ifChanged', function(e) {
                 // some conditionall validation
                })
                .end()
            .formValidation({
                ... options ...
            }).on('success.form.fv', function(e) {
                // Prevent form submission
                e.preventDefault();

                var $form = $(e.target),
                    fv    = $form.data('formValidation');
            console.log('called');


            });

Fuelux part

$('#orderWizard')
        // Call the wizard plugin
        .wizard()

        // Triggered when clicking the Next/Prev buttons
        .on('actionclicked.fu.wizard', function(e, data) {
            var fv         = $('#orderForm').data('formValidation'), // FormValidation instance
                step       = data.step,                              // Current step
                // The current step container
                $container = $('#orderForm').find('.step-pane[data-step="' + step +'"]');

            // Validate the container
            fv.validateContainer($container);

            var isValidStep = fv.isValidContainer($container);
            if (isValidStep === false || isValidStep === null) {
                // Do not jump to the target panel
                console.log(isValidStep);
                console.log(data);
                e.preventDefault();
            }
        })

        // Triggered when clicking the Complete button
        .on('finished.fu.wizard', function(e) {
            var fv         = $('#orderForm').data('formValidation'),
                step       = $('#orderWizard').wizard('selectedItem').step,
                $container = $('#orderForm').find('.step-pane[data-step="' + step +'"]');

            // Validate the last step container
            fv.validateContainer($container);

            var isValidStep = fv.isValidContainer($container);
            if (isValidStep === true) {
                // Uncomment the following line to submit the form using the defaultSubmit() method
                fv.defaultSubmit();
       // Use Ajax to submit form data
          // $("#loadersp").html('<center><img src="<?PHP echo base_url();?>assets/images/load.gif" alt="Czekaj" /></center>');
    // $.ajax({
           // type: "POST",
            // url: "<?php echo site_url('Zlecenia/dodaj_zgloszenie'); ?>",
            // data:  new FormData(this), 
            // dataType: 'json',
            // cache: false,
         // }).success(function(response) {
                // If there is error returned from server
                // if (response.result === 'error') {
                     // $("#ajax_r").html('<div class="col-md-12"><div class="note note-danger"><h4 class="box-heading">Niepowodzenie</h4><p>'+response.msg+'</p></div></div>');
                     // $("html, body").animate({ scrollTop: 0 }, "slow");
                // } else {

                     // $("#ajax_r").html('<div class="col-md-12"><div class="note note-success"><h4 class="box-heading">Powodzenie</h4><p>'+response+'</p></div></div>');
                     // $("html, body").animate({ scrollTop: 0 }, "slow");
                     // $('#nowyKlient').formValidation('resetForm', true);
                     // $("#nowyKlient").trigger('reset');
                // }
                // });

            e.preventDefault();
                // For testing purpose
                // $('#thankModal').modal();
            }
        });

Solution

  • Your question was Dwarf Fortress-level of FUN. And despite that (or because of it?), it was a pleasure to play with.

    To answer your question, I used these parts of documentation:

    http://getfuelux.com/javascript.html#wizard-usage-methods - I used .wizard('next') from here

    http://formvalidation.io/examples/ajax-submit/ - I see that you found that page too. I examined proposed ways of making Ajax work for FormValidation and why it tickles

    http://formvalidation.io/api/#default-submit - after many hours of FUN, I found this thing in documentation. Basically - what is says - .defaultSubmit is a no-no for Ajax - it is used for submitting data in conventional way.

    http://formvalidation.io/examples/fuel-ux-wizard/ - I see that you found that page too. I used this code base to produce a testable environment. HTML markup is usable as it is given in that example, but sending data as Ajax differs from sending data as normal HTTP-request: we'll need to change the script.

    Why did the code you used not work properly? Fuel UX's concern - is about moving between steps. It doesn't know about forms it doesn't change the form's behavior, it doesn't add form events or events. Only thing it cares about - are the prev/next buttons and clicking the last button. And that's all. FormValidation's concern - is forms - but it affects them that gently: if it can see that input is invalid, it blocks the submit event. If an input is valid - it allows the submit event to slip. Where does that submit event slips to? To default handler of the form. Now, when you understand their concerns, and movement of events, you can see the system that will make Fuel UX, FormValidation and Ajax play together.

    Below, I present a working code that solves your problem. You can copy it and test locally - it is almost stand-alone version. Only thing that you need - is steady internet connection - it uses CSS and JS from different CDNs, and it sends Ajax request to stackoverflow.com (you can change that, use any site - but It wouldn't work if you use URL from file:/// on your local machine)

    <!DOCTYPE html>
    <html>
        <head>
    
            <title>Test - teaching FormValidation, Fuel FX and AJAX play together</title>
    
            <!-- Styles - Bootstrap, FormValidation, Fuel UX -->
            <link rel="stylesheet" href="http://cdn.jsdelivr.net/bootstrap/3.3.2/css/bootstrap.min.css">
            <link rel="stylesheet" href="http://formvalidation.io/vendor/formvalidation/css/formValidation.min.css">
            <link rel="stylesheet" href="http://www.fuelcdn.com/fuelux/3.4.0/css/fuelux.min.css">
    
            <!-- Scripts - jQuery, Bootstrap, FormValidation, Fuel UX -->
            <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
            <script src="http://cdn.jsdelivr.net/bootstrap/3.3.2/js/bootstrap.min.js"></script>
            <script src="http://formvalidation.io/vendor/formvalidation/js/formValidation.min.js"></script>
            <script src="http://formvalidation.io/vendor/formvalidation/js/framework/bootstrap.min.js"></script>
            <script src="http://www.fuelcdn.com/fuelux/3.4.0/js/fuelux.min.js"></script>
    
        </head>
    
        <body>
    
            <h1>Hello, world!</h1>
    
            <div class="fuelux">
                <div class="wizard" id="orderWizard">
                    <ul class="steps">
                        <li data-step="1" class="active"><span class="badge">1</span> Your first step<span class="chevron"></span></li>
                        <li data-step="2"><span class="badge">2</span> Your second step<span class="chevron"></span></li>
                    </ul>
    
                    <div class="actions">
                        <button type="button" class="btn btn-default btn-prev"><span class="glyphicon glyphicon-arrow-left"></span>Prev</button>
                        <button type="button" class="btn btn-default btn-next" data-last="Order">Next<span class="glyphicon glyphicon-arrow-right"></span></button>
                    </div>
    
                    <form id="orderForm" method="post" class="form-horizontal" action="http://stackoverflow.com">
    
                        <div class="step-content">
                            <!-- The first panel -->
                            <div class="step-pane active" data-step="1">
                                <div class="form-group">
                                    <label class="col-xs-3 control-label">Text-1</label>
                                    <div class="col-xs-3">
                                        <input type="text" class="form-control" name="textA" />
                                    </div>
                                </div>
                            </div>
    
                            <!-- The second panel -->
                            <div class="step-pane" data-step="2">
                                <div class="form-group">
                                    <label class="col-xs-3 control-label">Text-2</label>
                                    <div class="col-xs-3">
                                        <input type="text" class="form-control" name="textB" />
                                    </div>
                                </div>
                            </div>
                        </div>
    
                    </form>
    
                </div>
            </div>
    
            <script>
    
            $(document).ready(function() {
                $('#orderForm').formValidation({
                    framework: 'bootstrap',
                    icon: {
                        valid: 'glyphicon glyphicon-ok',
                        invalid: 'glyphicon glyphicon-remove',
                        validating: 'glyphicon glyphicon-refresh'
                    },
                    // This option will not ignore invisible fields which belong to inactive panels
                    excluded: ':disabled',
                    fields: {
                        textA: {
                            validators: {
                                notEmpty: {
                                    message: 'The textA is required'
                                },
                                regexp: {
                                    regexp: /^[a-zA-Z\s]+$/,
                                    message: 'The textA can only consist of alphabetical and space'
                                }
                            }
                        },
                        textB: {
                            validators: {
                                notEmpty: {
                                    message: 'The textB is required'
                                },
                                regexp: {
                                    regexp: /^[a-zA-Z\s]+$/,
                                    message: 'The textB can only consist of alphabetical and space'
                                }
                            }
                        }
                    }
                })
                .on('submit', function() {
    
                    // make your form play with Fuel UX
                    $('#orderWizard').wizard('next');
                })
                .on('success.form.fv', function(e) {
                    // Prevent form submission
                    e.preventDefault();
                });
    
                $('#orderWizard')
                    // Call the wizard plugin
                    .wizard()
    
                    // Triggered when clicking the Next/Prev buttons
                    .on('actionclicked.fu.wizard', function(e, data) {
                        var fv         = $('#orderForm').data('formValidation'), // FormValidation instance
                            step       = data.step,                              // Current step
                            // The current step container
                            $container = $('#orderForm').find('.step-pane[data-step="' + step +'"]');
    
                        if (data.direction === 'previous') {
                            // Do nothing if you're going to the previous step
                            return;
                        }
    
                        // Validate the container
                        fv.validateContainer($container);
    
                        var isValidStep = fv.isValidContainer($container);
                        if (isValidStep === false || isValidStep === null) {
                            // Do not jump to the target panel
                            e.preventDefault();
                        }
                    })
    
                    // Triggered when clicking the Complete button
                    .on('finished.fu.wizard', function(e) {
                        var fv         = $('#orderForm').data('formValidation'),
                            step       = $('#orderWizard').wizard('selectedItem').step,
                            $container = $('#orderForm').find('.step-pane[data-step="' + step +'"]');
    
                        // Validate the last step container
                        fv.validateContainer($container);
    
                        var isValidStep = fv.isValidContainer($container);
                        if (isValidStep === true) {
    
                            // your Fuel UX wizard mustn't fire
                            // fv.defaultSubmit(); - because what it means
                            // is trigger raw form.submit() -
                            // this function it is designed
                            // to send form in a normal way - no validation,
                            // just a standard 'post' or 'get'
                            // 
                            // but you want ajax - so that means that
                            // normal submit is a no-no for you                     
    
                            var $form = $('#orderForm');
    
                            // For testing purpose
                            alert('We started to send your Ajax request');
    
                            // Use Ajax to submit form data
                            $.ajax({
                                url: $form.attr('action'),
                                type: 'POST',
                                data: $form.serialize(),
                                success: function(result) {
                                    // ... Process the result ...
                                    // For testing purpose
                                    alert('Your Ajax request was successful!');
                                },
                                error: function(result) {
                                    // ... Process the result ...
                                    // For testing purpose
                                    alert('Unfortunately your Ajax request failed');
                                }
                            });
                        }
                    });
            });
    
    
            </script>
    
        </body>
    
    </html>