VinceG / twitter-bootstrap-wizard

This twitter bootstrap plugin builds a wizard out of a formatter tabbable structure. It allows to build a wizard functionality using buttons to go through the different wizard steps and using events allows to hook into each step individually.
MIT License
1.39k stars 676 forks source link

Returning false onNext with Ajax not prevent tab to move forward. #41

Closed ghost closed 11 years ago

ghost commented 11 years ago

returning false onNext with Ajax not prevent tab to move forward, if my ajax status equal success than move forward otherwise it is stay in currentIndex.

$('#rootwizard').bootstrapWizard('show','currentIndex');
return false;

I tried before return false but seems does not effect.

  $('#rootwizard').bootstrapWizard({
        'tabClass': 'bwizard-steps',
        'onTabClick': function(tab, navigation, index){
          return false;
      },
        'onNext': function(tab, navigation, index) {
      if (index == 1){
        var $valid = $("#d_form").valid();
        if(!$valid) {
          $d_validator.focusInvalid();
          return false;
        }else {
            var $form = $("#d_form");
                form_data = $form.serializeFormJSON() || '';
            $.ajax({
              url : "<?php echo base_url(); ?>joborder/form_wizard1",
              type : 'POST',
              dataType: 'json',
              data : form_data,
              async : false,
              success: function(d){
                if(d.status == 'success'){
                  $.pnotify({
                      title: 'Notification',
                      text: d.message,
                      type: d.status
                    });
                }else {
                  $('#rootwizard').bootstrapWizard('show','currentIndex');
                     return false;
                  // not prevent tab to move forward, 
                }
              }
          });
        }
      }
  });

Thanks, sorry for my English.

PaulWeb commented 11 years ago

I have the same problem. I took version lib from example http://vadimg.com/twitter-bootstrap-wizard-example/examples/basic-formvalidation.html# and now all work fine.

ghost commented 11 years ago

Thanks for your response, false in validator was prevent tab to move forward, but false in ajax if d.status='error' not prevent it

validator

if(!$valid) {
  $d_validator.focusInvalid();
  return false;
  // prevent tab to move forward
}

ajax

  success: function(d){
    if(d.status == 'success'){
      $.pnotify({
          title: 'Notification',
          text: d.message,
          type: d.status
        });
    }else {
      $('#rootwizard').bootstrapWizard('show','currentIndex');
         return false;
      // not prevent tab to move forward, 
    }
  }
ghost commented 11 years ago

Thanks i have resolve the problem with adding new variable like flag, and after ajax function conditional created. flag = 0; return false;

var flag = 0;

in ajax

success: function(d){
  $.pnotify({
        title: 'Notification',
        text: d.message,
        type: d.status
      });
  if(d.status == 'success'){ 
     flag = 1;
  }
}

after ajax

if(flag == 0){ return false; }

Thanks.

clydet commented 9 years ago

I got around this by extending the plugin so that it would allow the next, previous,... methods to be executed via promise's configured callbacks. So no synchronous ajax.

(function() {
    $.fn.overrideBootstrapWizard = function(options) {
        var returnValue = this.bootstrapWizard( options );

        if ( options.overrides ) {
            var wizard = $(this).data( 'bootstrapWizard' );

            for ( property in options.overrides ){
                wizard[property] = makeOverride( wizard[property], options.overrides[property] );
            }

            var settings = $.extend({}, this.bootstrapWizard.defaults, options);

            $(settings.nextSelector).unbind('click');
            $(settings.previousSelector).unbind('click');
            $(settings.lastSelector).unbind('click');
            $(settings.firstSelector).unbind('click');
            $(settings.finishSelector).unbind('click');
            $(settings.backSelector).unbind('click');

            wizard.fixNavigationButtons();
        }        

        return returnValue;
    };

    //override must return promise
    function makeOverride( original, override ) {
        return function(){
            console.log('override', arguments);
            override( arguments, original );
            return false;
        }
    };
})();

So your wrapping method may look something like this:

        function validate(e, callback) {
            var validatonPromise = $http.post('/validate', {info: 'blah'}).
                success(function(data, status, headers, config) {
                    console.log(data, status, headers, config);
                    callback( e );
                }).
                error(function(data, status, headers, config) {
                    console.log(data, status, headers, config);
                });

            return validatonPromise;
        };

and to initialize the wizard:

                $scope.wizard = $('#rootwizard').overrideBootstrapWizard( {
                    nextSelector: '.button-next', 
                    previousSelector: '.button-previous',
                    overrides: {
                        next: validate,
                        previous: validate
                    },
                    onTabShow: modalDisplay,
                    onTabClick: function(tab, navigation, index) {
                        return false;
                    }
                });
    <script type="text/javascript" src="[path]/twitter-bootstrap-wizard/jquery.bootstrap.wizard.min.js"></script>
    <script type="text/javascript" src="[path]/jquery.bootstrap.wizard.override.js"></script>