0

I have an jquery step wizard, inside of them exists two form. When pass to the next step i try validate the first form with valid() method, but jquery validate always return true.

Here is the fiddle:

https://jsfiddle.net/2uyp1g25/

$(document).ready(function(){
   var formBasico = $("#basico").show();
    formBasico.validate({
        ignore: ":disabled,:hidden",
        rules: {
            'nombre-temp': {
                required: true,
                range: [1, 50]
            },
            'descripcion-temp': {
                required: true,
                range: [1, 50]
            },
            'min-cli': {
                required: true,
                number: true
            },
            'max-cli': {
                required: true,
                number: true
            },
            'cantidad-celdas': {
                required: true,
                number: true
            }
        }
    });

   $('#pasosTemplate').steps({
        headerTag: "h3",
        bodyTag: "section",
        transitionEffect: "slideLeft",
        autoFocus: true,
        labels: {
            cancel: "Cancelar",
            current: "paso actual:",
            pagination: "Paginación",
            finish: "Guardar Template",
            next: "Siguiente",
            previous: "Anterior",
            loading: "Cargando ..."
        },
        onStepChanging: function (event, currentIndex, newIndex) {
            if (currentIndex < newIndex) {
                alert(formBasico.valid());
                return formBasico.valid();
            }
            return true;
        },
        onFinished: function (event, currentIndex) {
         alert('fin');
        }
    });
});
/*
    Common
*/

.wizard,
.tabcontrol
{
    display: block;
    width: 100%;
    overflow: hidden;
}

.wizard a,
.tabcontrol a
{
    outline: 0;
}

.wizard ul,
.tabcontrol ul
{
    list-style: none !important;
    padding: 0;
    margin: 0;
}

.wizard ul > li,
.tabcontrol ul > li
{
    display: block;
    padding: 0;
}

/* Accessibility */
.wizard > .steps .current-info,
.tabcontrol > .steps .current-info
{
    position: absolute;
    left: -999em;
}

.wizard > .content > .title,
.tabcontrol > .content > .title
{
    position: absolute;
    left: -999em;
}



/*
    Wizard
*/

.wizard > .steps
{
    position: relative;
    display: block;
    width: 100%;
}

.wizard.vertical > .steps
{
    display: inline;
    float: left;
    width: 30%;
}

.wizard > .steps .number
{
    font-size: 1.429em;
}

.wizard > .steps > ul > li
{
    width: 25%;
}

.wizard > .steps > ul > li,
.wizard > .actions > ul > li
{
    float: left;
}

.wizard.vertical > .steps > ul > li
{
    float: none;
    width: 100%;
}

.wizard > .steps a,
.wizard > .steps a:hover,
.wizard > .steps a:active
{
    display: block;
    width: auto;
    margin: 0 0.5em 0.5em;
    padding: 1em 1em;
    text-decoration: none;

    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
}

.wizard > .steps .disabled a,
.wizard > .steps .disabled a:hover,
.wizard > .steps .disabled a:active
{
    background: #eee;
    color: #aaa;
    cursor: default;
}

.wizard > .steps .current a,
.wizard > .steps .current a:hover,
.wizard > .steps .current a:active
{
    background: #007cc1;
    color: #fff;
    cursor: default;
}

.wizard > .steps .done a,
.wizard > .steps .done a:hover,
.wizard > .steps .done a:active
{
    background: #9dc8e2;
    color: #fff;
}

.wizard > .steps .error a,
.wizard > .steps .error a:hover,
.wizard > .steps .error a:active
{
    background: #ff3111;
    color: #fff;
}

.wizard > .content
{
    background: #eee;
    display: block;
    margin: 0.5em;
    min-height: 35em;
    overflow: hidden;
    position: relative;
    width: auto;

    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
}

.wizard.vertical > .content
{
    display: inline;
    float: left;
    margin: 0 2.5% 0.5em 2.5%;
    width: 65%;
}

.wizard > .content > .body
{
    float: left;
    position: relative;
    width: 95%;
    height: 95%;
    padding: 2.5%;
}

.wizard > .content > .body ul
{
    list-style: disc !important;
}

.wizard > .content > .body ul > li
{
    display: list-item;
}

.wizard > .content > .body > iframe
{
    border: 0 none;
    width: 100%;
    height: 100%;
}

.wizard > .content > .body input
{
    display: block;
    border: 1px solid #ccc;
}

.wizard > .content > .body input[type="checkbox"]
{
    display: inline-block;
}

.wizard > .content > .body input.error
{
    background: rgb(251, 227, 228);
    border: 1px solid #fbc2c4;
    color: #8a1f11;
}

.wizard > .content > .body label
{
    display: inline-block;
    margin-bottom: 0.5em;
}

.wizard > .content > .body label.error
{
    color: #8a1f11;
    display: inline-block;
    margin-left: 1.5em;
}

.wizard > .actions
{
    position: relative;
    display: block;
    text-align: right;
    width: 100%;
}

.wizard.vertical > .actions
{
    display: inline;
    float: right;
    margin: 0 2.5%;
    width: 95%;
}

.wizard > .actions > ul
{
    display: inline-block;
    text-align: right;
}

.wizard > .actions > ul > li
{
    margin: 0 0.5em;
}

.wizard.vertical > .actions > ul > li
{
    margin: 0 0 0 1em;
}

.wizard > .actions a,
.wizard > .actions a:hover,
.wizard > .actions a:active
{
    background: #007CC1;
    color: #fff;
    display: block;
    padding: 0.5em 1em;
    text-decoration: none;

    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
}

.wizard > .actions .disabled a,
.wizard > .actions .disabled a:hover,
.wizard > .actions .disabled a:active
{
    background: #eee;
    color: #aaa;
}

.wizard > .loading
{
}

.wizard > .loading .spinner
{
}



/*
    Tabcontrol
*/

.tabcontrol > .steps
{
    position: relative;
    display: block;
    width: 100%;
}

.tabcontrol > .steps > ul
{
    position: relative;
    margin: 6px 0 0 0;
    top: 1px;
    z-index: 1;
}

.tabcontrol > .steps > ul > li
{
    float: left;
    margin: 5px 2px 0 0;
    padding: 1px;

    -webkit-border-top-left-radius: 5px;
    -webkit-border-top-right-radius: 5px;
    -moz-border-radius-topleft: 5px;
    -moz-border-radius-topright: 5px;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
}

.tabcontrol > .steps > ul > li:hover
{
    background: #edecec;
    border: 1px solid #bbb;
    padding: 0;
}

.tabcontrol > .steps > ul > li.current
{
    background: #fff;
    border: 1px solid #bbb;
    border-bottom: 0 none;
    padding: 0 0 1px 0;
    margin-top: 0;
}

.tabcontrol > .steps > ul > li > a
{
    color: #5f5f5f;
    display: inline-block;
    border: 0 none;
    margin: 0;
    padding: 10px 30px;
    text-decoration: none;
}

.tabcontrol > .steps > ul > li > a:hover
{
    text-decoration: none;
}

.tabcontrol > .steps > ul > li.current > a
{
    padding: 15px 30px 10px 30px;
}

.tabcontrol > .content
{
    position: relative;
    display: inline-block;
    width: 100%;
    height: 35em;
    overflow: hidden;
    border-top: 1px solid #bbb;
    padding-top: 20px;
}

.tabcontrol > .content > .body
{
    float: left;
    position: absolute;
    width: 95%;
    height: 95%;
    padding: 2.5%;
}

.tabcontrol > .content > .body ul
{
    list-style: disc !important;
}

.tabcontrol > .content > .body ul > li
{
    display: list-item;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.0/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-steps/1.1.0/jquery.steps.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="/css/result-light.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-steps/1.1.0/jquery.steps.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.15.0/jquery.validate.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>



<body>

<div id="pasosTemplate">
                <h3>Información Básica</h3>
                <section>
                    <form class="form-horizontal" id="basico">
                        <div class="form-group">
                            <label class="col-lg-2">Nombre Template</label>
                            <div class="col-lg-6">
                                <input type="text" class="form-control" placeholder="Nombre Template" id="nombre-temp" name="nombre-temp" >
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-lg-2">Descripción Template</label>
                            <div class="col-lg-6">
                                <input type="text" class="form-control" placeholder="Descripción Template" id="descripcion-temp" name="descripcion-temp">
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-lg-2">Objetivo de Optimización</label>
                            <div class="col-lg-6">
                                <select class="form-control" id="objetivo-o" name="objetivo-o">
                                    <option value=" ">Selecciona un objetivo...</option>
                   
                                </select>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-lg-2">Establecer cantidad Mínima y Máxima de clientes</label>
                            <div class="col-lg-2">
                                <input type="number" class="form-control" placeholder="Mínimo" id="min-cli" name="min-cli">
                            </div>
                            <div class="col-lg-2">
                                <input type="number" class="form-control" placeholder="Máximo" id="max-cli" name="max-cli">
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-lg-2">Celdas de Comunicación</label>
                            <div class="col-lg-2">
                                <input type="number" placeholder="Cantidad celdas" class="form-control" id="cantidad-celdas" name="cantidad-celdas">
                            </div>
                        </div>
                    </form>
                </section>
                <h3>Segmentación</h3>
                <section>
                    <form class="form-horizontal" id="segmentacion" action="#">
                  
                        <div class="col-lg-12" id="segmentaciones">

                        </div>
                        <div class="form-group">
                            <label class="col-lg-2">Estimación de Clientes alcanzados</label>
                            <div class="col-lg-4">
                                <input type="text" readonly class="form-control" id="clientes-alcanzados">
                            </div>
                        </div>
                    </form>
                </section>
            </div>
            </body>

how can fix this error???

Sparky
  • 98,165
  • 25
  • 199
  • 285
Figa17
  • 781
  • 7
  • 20

1 Answers1

3

You've assigned the formBasico variable name to something that includes the .show() method.

var formBasico = $("#basico").show();

Then you've attach that to the .valid() method...

alert(formBasico.valid());

You can only attach the .valid() method to a form object or a form's data input element. However, in your case the formBasico variable represents neither.

Fix it by only attaching .valid() to something that represents the form object...

$("#basico").valid()

Looking at your jsFiddle, I can test .valid() method by moving it outside of .steps() and the form is validated.

https://jsfiddle.net/2uyp1g25/1/

For some reason, .valid() stops working when called from within the .steps() method. I'm thinking within .steps() it's returning true because the Steps plugin is hiding the panel before .valid() is called. Once hidden, the form would be valid since you are ignoring hidden fields.

The documentation for Steps says that onStepChanging:

Fires before the step changes and can be used to prevent step changing by returning false. Very useful for form validation.

Although your demo proves this is not the case.

  • If I return false within onStepChanging, I can stop the step; however I cannot run any other code before or after return false.

  • If I try it your way, the step changes before .valid() can run and then .valid() is true because the step is hidden.

I believe this is a bug within Steps.

I am getting the same result when I try onFinishing, which states...

Fires before finishing and can be used to prevent completion by returning false. Very useful for form validation.

I simply put return false in here and it does not even work as described in the documentation above! If return false is not even going to stop the step, then you are not going to be able to run any other code in there.

https://jsfiddle.net/2uyp1g25/2/

Why are there two totally different options, both described as "very useful for form validation" where one that works properly would be sufficient?

There are presently 109 open issues with the Steps plugin, and issues within onStepChanging, where many describe form validation issues. It also does not appear as if this plugin has been updated or maintained since September 2014.


EDIT:

After more experimentation, I discovered that this can be "fixed" by declaring validation rules inline as class names rather than within the rules object...

https://jsfiddle.net/2uyp1g25/3/

jQuery Validate works the same no matter how you declare the rules, so the only possible difference is its timing. This only confirms that the Steps plugin has some serious issues with how its onStepChanging callback works.

Sparky
  • 98,165
  • 25
  • 199
  • 285