Kavvson Empcraft Kavvson Empcraft - 3 months ago 38
Javascript Question

Fuelux wizzard 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();
}
});

Answer

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 code you used didn't work properly? Fuel UX's concern - is about moving between steps. It doesn't know about forms it doesn't change form's behavior, it doesn't add form events or events. Only thing it cares about - are prev-next button and clicking 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 submit event. If input is valid - it allows 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 CND, 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>
Comments