[jQuery] Tabbladen > validatie per tabblad?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Ik maak gebruik van jQuery UI tabs om een soort "Wizard" formulier te maken. De interface werkt prima. Je klikt op volgende en dan pas wordt het volgende tabblad actief en kan je er naar toe.

Mijn tabs en de velden erop vormen samen een formulier, maar ik zou de validatie per tabblad willen laten verlopen.

Er zijn wel voorbeelden te vinden van validatie met tabbladen maar niet in de "Wizard" stijl. Verder zijn er wat oplossingen te vinden die een dergelijk iets wel toepassen maar deze zijn me niet dynamisch genoeg (hard verwijzingen etc) of hebben een custom validatie. Ik zou graag van de validate() functie van jquery zelf gebruik willen maken.

Het probleem waar ik zelf tegen aan loop is dat als ik op het eerste tab een veld verplicht maak, en ook op het tweede tab dat je niet naar de volgende tabs kan springen omdat de validatie namelijk meldt dat op tab2 nog geen waarde is opgegeven. Ondanks dat je dus nog op tab1 zit en daar een waarde hebt opgegeven..

Is er iemand die dit wel eens gedaan heeft of hier een idee over heeft?

Dit is de code die ik gebruik:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
        <title></title>
    
            <link type="text/css" href="css/custom-theme/jquery-ui-1.7.2.custom.css" rel="stylesheet" />

      <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script>
      <script type="text/javascript" src="js/jquery-ui-1.7.2.custom.min.js"></script>

        <script type="text/javascript" src="js/jquery.validate.js"></script>    
            <script type="text/javascript"> 

            $(document).ready(function() {          
        
            // disable de tabs behalve de eerste (0)
            $('#tabs').tabs({ disabled: [1,2] });   
            
            var validator = $("#gsmwissel").validate({
                    errorPlacement: function(label, element) {
                        label.insertAfter(element);
                    },
                    rules: {
                        naam:{
                            required: true,
                            minlength: 2
                            },
                        adres:{
                            required: true,
                            minlength: 2
                            }
                    },
                    messages: {
                        naam:{
                            required: " Naam is een verplicht veld",
                            minlength: jQuery.format(" Naam moet minimaal 2 tekens bevatten")
                        },
                    }
                });
    
    

            // voeg overal de volgende en vorige link toe.
                var $tabs = $('#tabs').tabs();
            
                $(".tabs").each(function(i){
            
                    var totalSize = $(".tabs").size() - 1;
            
                    if (i != totalSize) {
                        
                        next = i + 2;               
                        $(this).append("<a href='#' class='next-tab' rel='" + next + "'>Volgende »</a>");
                        
                    }
            
                    if (i != 0) {
                        
                        prev = i;
                        $(this).append("<a href='#' class='prev-tab' rel='" + prev + "'>« Vorige</a>");
            
                    }
            
            });
            
            // springen naar volgende en vorige tab. Bij volgende tab enablen we die direct.
            
                $('.next-tab').click(function() {
                                                                            
                    if(validator.form()) {
                        $tabs.tabs('enable', $(this).attr("rel")-1);                                                                             
                        $tabs.tabs('select', $(this).attr("rel"));
                        return false;
                    }
                    
                });
                
                $('.prev-tab').click(function() {
                                                                                                 
                    $tabs.tabs('select', $(this).attr("rel"));
                    return false;
                                 
                });
                
            });             

                        

      </script>
      
      <style>
            body {
                font-size: 75%;
            }
            
            #wrapper {
                width: 700px;
                margin-left: auto;
                margin-right: auto;
                
            }
            
            h2 {
                font-family: Verdana, Geneva, sans-serif;
                font-size: 16px;
                font-weight: bold;
                color: #000;
                
            }
            .tabs {
                margin-bottom: 6px;
            }
            
            #tabs .next-tab {
                float: right;
                text-decoration:none;
                color: #004276;
                font-weight: bold;
            }
            
            #tabs .prev-tab {
                float: left;
                text-decoration:none;
                color: #004276;
                font-weight: bold;
            }

        </style>
    
    </head>
    <body>
  
  <form id="gsmwissel" name="gsmwissel">
  <div id="wrapper">
    <div id="tabs" style="width:600px">

    
      <ul>
        <li><a href="#tabs1">Stap 1</a></li>
        <li><a href="#tabs2">Stap 2</a></li>
        <li><a href="#tabs3">Stap 3</a></li>
      </ul>
      
      <div id="tabs1" class="tabs">
        <p><label for="Naam">Naam: </label><input name="naam" id="naam" type="text"></p>

      </div>
      <div id="tabs2" class="tabs">
        <p><label for="Adres">Adres: </label><input name="adres" id="adres" type="text"></p>
        <p>Morbi tincidunt, dui sit amet facilisis feugiat, odio metus gravida ante, ut pharetra massa metus id nunc. Duis scelerisque molestie turpis. Sed fringilla, massa eget luctus malesuada, metus eros molestie lectus, ut tempus eros massa ut dolor. Aenean aliquet fringilla sem. Suspendisse sed ligula in ligula suscipit aliquam. Praesent in eros vestibulum mi adipiscing adipiscing. Morbi facilisis. Curabitur ornare consequat nunc. Aenean vel metus. Ut posuere viverra nulla. Aliquam erat volutpat. Pellentesque convallis. Maecenas feugiat, tellus pellentesque pretium posuere, felis lorem euismod felis, eu ornare leo nisi vel felis. Mauris consectetur tortor et purus.</p>

      </div>
      <div id="tabs3" class="tabs">
        <p>Mauris eleifend est et turpis. Duis id erat. Suspendisse potenti. Aliquam vulputate, pede vel vehicula accumsan, mi neque rutrum erat, eu congue orci lorem eget lorem. Vestibulum non ante. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Fusce sodales. Quisque eu urna vel enim commodo pellentesque. Praesent eu risus hendrerit ligula tempus pretium. Curabitur lorem enim, pretium nec, feugiat nec, luctus a, lacus.</p>

        <p>Duis cursus. Maecenas ligula eros, blandit nec, pharetra at, semper at, magna. Nullam ac lacus. Nulla facilisi. Praesent viverra justo vitae neque. Praesent blandit adipiscing velit. Suspendisse potenti. Donec mattis, pede vel pharetra blandit, magna ligula faucibus eros, id euismod lacus dolor eget odio. Nam scelerisque. Donec non libero sed nulla mattis commodo. Ut sagittis. Donec nisi lectus, feugiat porttitor, tempor ac, tempor vitae, pede. Aenean vehicula velit eu tellus interdum rutrum. Maecenas commodo. Pellentesque nec elit. Fusce in lacus. Vivamus a libero vitae lectus hendrerit hendrerit.</p>            
        <input type="submit">
      </div>    
      
      
    </div>
    
  </div>
  
  </form>
    </body>
</html>

Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 12:45
Ik zit even hardop met je mee te denken, kan je niet met Jquery alle id's formuliervelden uitlezen in een array die in een bepaalde tab staan? (dus voor tab2 staat daar alleen adres in)

Je geeft dan aan de "algemene controlefunctie" de id's mee van alle velden die binnen de openstaande tab staan.Wat je daarmee kan bereiken is dat je kan aangeven dat die alleen die velden moet controleren, wanneer je verder wilt gaan.

Stel: Je zit op tab1, je controleert dan automatisch alleen de velden van de 1e tab, doordat je alleen de velden controleert die worden meegegeven aan de functie. Zit er een fout in, gaat die niet naar de volgende tab, is het goed gaat die wel door naar de volgende tab.

Dat is volgens mij wat je wilt bereiken, en lijkt mij alleen mogelijk door je script te laten bepalen op welke tab je zit (geef bijv tab id mee bij de controle aanroep) en dan te bepalen welke velden daarbinnen zitten. Volgens mij moet dat gewoon kunnen met Jquery, hoe weet ik zo niet precies maar het is denk ik de moeite waard om dit uit te zoeken.

Acties:
  • 0 Henk 'm!

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Wat je dan doet is inderdaad de velden alleen opgeven, alleen je kan naar mijn weten de validate functie alleen aanroepen voor een heel formulier. Je moet dan ook het tab even afvangen (dus als de tab niet op is bevonden door validate, blijf dan op dit tab).. Verder is me dat teveel custom werk en wil ik het zo dynamisch mogelijk houden..

Mijn voorbeeld: http://wijmakenwebsites.nl/google/example.html

Deze checkt de velden dus zodra je op volgende klikt. Als op tab1 een veld leeg is dan krijg je een melding en gaat alles goed. Druk je nu op volgende dan gaat dat niet omdat het veld op tab2 nog leeg is :s. Dan zou dus niet moeten gebeuren...

[ Voor 6% gewijzigd door ViNyL op 25-06-2009 13:23 ]


Acties:
  • 0 Henk 'm!

  • Bjornski
  • Registratie: September 2002
  • Laatst online: 29-07 14:59
Volgens mij is de makkelijkste oplossing om een formulier per tab te maken.
Zodra de gebruiker op het "voltooien" knopje klikt alle kinderen (dus alle inputs) moven naar één groot formulier en dat submitten.

Wat echter misschien netter is, is om zelf even een validator te schrijven die alle input elementen binnen een tab valideert.

Edit:
Of simpelweg bij elke tabswitch dit stukje code aanroepen met alleen de velden die op de tab staan waar je naartoe switcht:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 var validator = $("#gsmwissel").validate({
                    errorPlacement: function(label, element) {
                        label.insertAfter(element);
                    },
                    rules: {
                        naam:{
                            required: true,
                            minlength: 2
                            },
                        adres:{
                            required: true,
                            minlength: 2
                            }
                    },
                    messages: {
                        naam:{
                            required: " Naam is een verplicht veld",
                            minlength: jQuery.format(" Naam moet minimaal 2 tekens bevatten")
                        },
                    }
                }); 

[ Voor 59% gewijzigd door Bjornski op 25-06-2009 13:38 ]


Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 12:45
@ViNyL
Je geeft dus dan niet de velden op, maar bij de knop naar de volgende tab geef je de tabnaam op waar je je bevindt: Bijvoorbeeld, op tab1 krijg je: validate('tab1');

Je kan dan alle formuliervelden van tab1 inlezen binnen de validatefunctie en deze valideren (net als dat je dat nu doet. Je geeft dus zelf niet de velden mee, maar alleen de tab en je laat de velden binnen deze tab uitlezen en deze dan controleren. Dat lijkt mij toch behoorlijk dynamisch. Sorry als ik de vorige keer niet duidelijk uitlegde, maar 't is ook best ingewikkeld uit te leggen.

Het is nu redelijk custom werk om dat te maken, dat klopt maar je kan gewoon de validatiefunctie gebruiken welke je nu ook gebruikt.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var validator = $("#gsmwissel").validate({
                    errorPlacement: function(label, element) {
                        label.insertAfter(element);
                    },
                    rules: {
                        naam:{
                            required: true,
                            minlength: 2
                            },
                        adres:{
                            required: true,
                            minlength: 2
                            }
                    },
                    messages: {
                        naam:{
                            required: " Naam is een verplicht veld",
                            minlength: jQuery.format(" Naam moet minimaal 2 tekens bevatten")
                        },
                    }
                });


Je kan om deze code ook een extra functie zetten voor de betreffende veldnaam. Het is nu veel werk om het te maken, maar uiteindelijk kan je gewoon een nieuw veld in een tab toevoegen, de controlefunctie schrijven en voilla...
@Bjornski
Gemakkelijker is dan om alles wat je al hebt verzonden in een sessie/ cookie (alleen wanneer er geen privacygevoelige gegevens in het formulier zitten) te zetten, lijkt mij in elk geval.

Acties:
  • 0 Henk 'm!

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
@Bjornski:
Zelf een validator schrijven is het eerste wat ik gedaan heb. Alleen niet voor de velden op één tab. Ik haalde ze in eerste instantie met hun ID op. Dit werkte prima, tot dat ik me afvroeg of het niet gewoon met de validator plugin van jQuery zelf kon.

@jbdeiman/Bjornski:
Ik wist niet dat je de validator ook per tab kon aanroepen. Moet zeggen dat het wel in me op is gekomen maar ik aan het kijken was naar een oplossing voor het hele form. Dit is wel een mooie oplossing inderdaad! Ga eens even kijken of ik dat er tussen kan stoppen.

update:

als ik probeer de validatie op het ID van de tab op te roepen, dan gebeurt er niets. Zet ik er de naam van het form weer neer dan lukt het wel. Blijkbaar kun je niet per ID een check laten lopen...

dit roep ik aan als je op de next tab link klikt:
JavaScript:
1
$('tabs1').validate();


en de validate is als hier boven met als enige wijziging de naam van de tab er in (tabs1 bv)..

[ Voor 27% gewijzigd door ViNyL op 25-06-2009 14:20 ]


Acties:
  • 0 Henk 'm!

  • Bjornski
  • Registratie: September 2002
  • Laatst online: 29-07 14:59
Je moet de validator op de form aanroepen, dat staat ook in de documentatie van jQuery.
Echter, je kunt die validator bij elke tabswitch wel opnieuw initialiseren.

Dus voor de eerste tab doe je:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
var validator = $("#gsmwissel").validate({
                    errorPlacement: function(label, element) {
                        label.insertAfter(element);
                    },
                    rules: {
//De veldjes van de eerste tab
                    },
                    messages: {
//De messages die erbij horen
                        },
                    }
                }); 


Zodra je bent geswitcht naar de tweede tab (select event) voer je diezelfde code uit, maar ditmaal met veldjes uit de tweede tab, enzovoort.

Het hele form wordt dan dus gevalideerd, maar je geeft in de toegepaste validator alleen die veldjes op die op je actieve tab staan.

Acties:
  • 0 Henk 'm!

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Ok dat zou dus betekenen dat ik in mijn code voor het switchen van de tabs:
JavaScript:
1
2
3
4
5
$('.next-tab').click(function() {
$tabs.tabs('enable',$(this).attr("rel")-1);                                                                              
$tabs.tabs('select', $(this).attr("rel"));
return false;
});


eerst even moet kijken op welke tab je zit (if statement oid) en daar dan steeds:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
var validator = $("#gsmwissel").validate({
                    errorPlacement: function(label, element) {
                        label.insertAfter(element);
                    },
                    rules: {
//De veldjes van de eerste tab
                    },
                    messages: {
//De messages die erbij horen
                        },
                    }
                });


moet aanroepen?

Acties:
  • 0 Henk 'm!

  • Bjornski
  • Registratie: September 2002
  • Laatst online: 29-07 14:59
Precies. :)

Voorbeeldje voor hoe je de geselecteerde tab uitvraagt vindt je hier.

Dit zou ik overigens oplossen met een switch en even onderbrengen in aparte functies. Dan blijft het overzichtelijk.

Acties:
  • 0 Henk 'm!

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
en perhaps nog een hele domme vraag maar het aanroepen van die select event

JavaScript:
1
2
3
$('.selector').tabs({
   select: function(event, ui) { ... }
});


doe ik dat op deze manier?

JavaScript:
1
2
3
4
5
6
7
8
9
10
$('.next-tab').click(function() {
$tabs.tabs({
select: function(){
//validatie functie etc
}

$tabs.tabs('enable',$(this).attr("rel")-1);                                                                                
$tabs.tabs('select', $(this).attr("rel"));
return false;
});

Acties:
  • 0 Henk 'm!

  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

Weet je op welke tab welk element komt? ZO ja, dan kun je een (dummy) class als tab1, tab2, etc opnemen op elke (input) element van de tab.

Op het moment dat je gaat valideren neem je tab kun je tab1 als extra selectie opnemen.

JavaScript:
1
2
$("#gsmwissel .tab1").validate();
$("#gsmwissel .tab2").validate();


Er simpele, maar effectieve manier om je validatie per tab te laten lopen. Vergeet je niet de gegevens ook server-sided te controleren?

If it isn't broken, fix it until it is..


Acties:
  • 0 Henk 'm!

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Dank voor je reply.

De serverside controle is al af. Ik ben nu bezig met de interface. Heb het belangrijkste eerst gedaan ;)

Ok its working so far!

Wat ik gedaan heb is het volgende:

ik laad eerst de veld controle volledig in.
Vervolgens kijk ik op welke tab je zit en laadt de velden van de tab in en voer de controle uit :

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$('.next-tab').click(function() {

// velden op de tab inlezen
// moet nog automatisch laten doen ipv harde verwijzingen 
  var naam = $("#naam");

// voer de controle voor de tab uit
  var tab = $([]).add(naam).valid();

// is de check ok, dan mag de volgende tab open en actief worden
  if(tab == true){
    $tabs.tabs('enable', $(this).attr("rel")-1);                                                                             
    $tabs.tabs('select', $(this).attr("rel"));
  } else {
// schakel volgende tabs uit afhankelijk van waar je bent
// ook nog automatisch laten gaan ipv harde verwijzingen 
    tabs.tabs('option', 'disabled', [2, 3]);
  }

    return false;                   
  
}); 

[ Voor 77% gewijzigd door ViNyL op 25-06-2009 15:59 ]


Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 12:45
@ViNyL
Ik hoop dat het gaat lukken, is wel een mooie manier van checken zo. Toch redelijk dynamisch, moet ook zeggen dat het je toch aardig vlot af gaat.

Was het nu eerst niet duidelijk wat ik bedoelde, want dan zal ik er de volgende keer wat meer op letten dat ik het wat duidelijker omschrijf.

Acties:
  • 0 Henk 'm!

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Thanks voor alle hulp, zal als ik het plaatje compleet heb hier even posten hoe het eruit ziet!

Acties:
  • 0 Henk 'm!

  • ViNyL
  • Registratie: Augustus 2001
  • Niet online
Ik heb mijn probleem op de onderstaande manier opgelost. Om het geheel dynamischer te maken zal ik daar nog wat verder induiken, maar dit script geeft je de mogelijkheid om tabbladen te gebruiken en veld controle per tabblad.

Zodra een veld niet in orde is wordt deze in een div (errors) vermeldt. Hierin komen dus alle foutmeldingen te staan.

Je kan altijd terug, maar niet verder als een tabblad niet door de controle komt.

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
$(document).ready(function() {  


// disable de tabs behalve de eerste (0)
$('#tabs').tabs({ disabled: [1,2] });   

// veldcontrole + opties defineren
var validator = $('#form').validate({
errorLabelContainer: $("#errors"),
rules: {
  naam:{
    required: true,
    minlength: 2
    },
  nummer:{
    required: true,
    minlength: 10,
    maxlength: 10,
    number: true
    },
  locatie:{
    required: true
    }
},
messages: {
  naam:{
    required: "<li>Naam is een verplicht veld</li>",
    minlength: jQuery.format("<li>Naam moet minimaal 2 tekens bevatten</li>")
  },
  locatie:{
    required: "<li>Geen locatie opgegeven</li>"
  },
  nummer:{
    required: "<li>Nummer is een verplicht veld</li>",
    minlength: "<li>Nummer moet 10 tekens bevatten</li>",
    number: "<li>Nummer mag alleen nummers bevatten</li>"
  }

  }
});     


// voeg overal de volgende en vorige link toe.
  var $tabs = $('#tabs').tabs();
        
  $(".tabs").each(function(i){

    var totalSize = $(".tabs").size() - 1;

    if (i != totalSize) {
      
      next = i + 2;             
      $(this).append("<a href='#' class='next-tab' rel='" + next + "'>Volgende »</a>");
      
    }

    if (i != 0) {
      
      prev = i;
      $(this).append("<a href='#' class='prev-tab' rel='" + prev + "'>« Vorige</a>");

    }

});

// springen naar volgende tab. Bij volgende tab enablen we die direct.

  $('.next-tab').click(function() {

  var selected = $('#tabs').tabs('option', 'selected') + 1;
  
  var currenttab = "tabs" + selected + "";
  

// veld controle per tab, helaas nog niet dynamisch

  if (currenttab == "tabs1") {  

    var naam = $("#naam");
    var locatie = $("#locatie");

    

    var tabfields = $([]).add(naam).add(locatie).valid();
    
  }


  if (currenttab == "tabs2") {  

    var nummer = $("#nummer");

    

    var tabfields = $([]).add(nummer).valid();
    
  } 

    
  if(tabfields == true){
      $tabs.tabs('enable', $(this).attr("rel")-1);                                                                               
      $tabs.tabs('select', $(this).attr("rel"));
    } else {
      tabs.tabs('option', 'disabled', [2,3]);
    }

      return false;                 
    
  });
 
// springen naar vorige tab.
  $('.prev-tab').click(function() {
                                           
    $tabs.tabs('select', $(this).attr("rel"));
    return false;
           
  });
  
});             

    


Niet alle code is van mezelf, maar met hulp van andere bronnen is het naar mijn idee een mooie oplossing voor tabs met veldcontrole.
Pagina: 1