jquery 无法获取包含空必填字段的选项卡

hec6srdp  于 2023-10-17  发布在  jQuery
关注(0)|答案(1)|浏览(100)

在一个模态中,有包含必填字段的选项卡:

<div class="col-md-12 scrollable_h" style="max-width: 100%;" id="block_clients">
    
    <table id="liste_clients" class="table table-striped">
        <thead>
            <tr>
                <th>Compte</th>
                <th>Nom</th>
                <th>Pr&eacute;nom</th>
                <th>Adresse</th>
                <th>Ville(Code)</th>
                <th>T&eacute;l&eacute;phone / mobile</th>
                <th>E-mail</th>
                <th>Nationalit&eacute;</th>
                <th>Qualit&eacute;</th>
                <th>Type</th>
                <th>Segment</th>
                <th>Prescripteur</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody></tbody>
    </table>
    
    <div id="modalAjoutClient" class="modal">
        <form id="frmClient">
            <input type="hidden" id="mode_" name="mode_" />
            <div class="modal-content tabs">
                <div class="modal-header" style="padding:0px;font-size: 13px !important;justify-content: center !important;">
                    <span class="close"></span>
                    <nav class="navbar navbar-expand-lg" style="font-family: 'Public sans';">
                        <div class="container-fluid">
                            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkupClient" aria-controls="navbarNavAltMarkupClient" aria-expanded="false" aria-label="Toggle navigation">
                                <span class="navbar-toggler-icon"></span>
                            </button>
                            <div class="collapse navbar-collapse" id="navbarNavAltMarkupClient">
                                <div class="navbar-nav tab-registers">
                                    <a class="nav-link active-tab" aria-current="page" href="#block_add_client_adr_comm">Adresse Commerciale</a>&emsp;&emsp;
                                    <a class="nav-link" href="#block_add_client_adr_factur">Adresse Facturation</a>&emsp;&emsp;
                                    <a class="nav-link" href="#block_add_client_facturation">Facturation</a>
                                </div>
                            </div>
                        </div>
                    </nav>
                </div>
                <div class="modal-body">
                    <div class="row tab-bodies">
                        <div class="col-md-12 scrollable_h" style="display:block; max-width: 100%;" id="block_add_client_adr_comm">
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Nom :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="nom" maxlength="100" required>
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">T&eacute;l&eacute;phone :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="telephone" maxlength="45">
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Pr&eacute;nom :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="prenom" maxlength="100">
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">Mobile :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="mobile" maxlength="20">
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Ville :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="ville" maxlength="45">
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">Nationalit&eacute; :</label>
                                        <div class="" style="position: relative;">
                                            <select class="form-select champ-modal listbox-modal medium" name="nationalite" required>
                                                <option value=''></option>
                                                <option value='A'>Autriche</option>
                                                <option value='AF'>Afghanistan</option>
                                                <option value='AL'>Albania</option>
                                                ...
                                            </select>
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Code Postal :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="codePostal" maxlength="45">
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">Qualit&eacute; :</label>
                                        <div class="" style="position: relative;">
                                            <select class="form-select champ-modal listbox-modal medium" name="qualite">
                                                <option value="SOC">Soci&eacute;t&eacute;</option>
                                                <option value="MR">Monsieur</option>
                                                <option value="MME">Madame</option>
                                                <option value="MLLE">Mademoiselle</option>
                                            </select>
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                        </div>
                        <div class="col-md-12 scrollable_h" style="display:none; max-width: 100%;" id="block_add_client_adr_factur">
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Nom :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="nomFacturation" maxlength="45" required>
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">T&eacute;l&eacute;phone :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="telephoneFacturation" maxlength="15">
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Pr&eacute;nom :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="prenomFacturation" maxlength="45">
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">Mobile :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="mobileFacturation" maxlength="15">
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Adresse :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="adresseFacturation" maxlength="100">
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">E-mail :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="emailFacturation" maxlength="80">
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Ville :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="villeFacturation" maxlength="45">
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">Nationalit&eacute; :</label>
                                        <div class="" style="position: relative;">
                                            <select class="form-select champ-modal listbox-modal medium" name="paysFacturation" required>
                                                <option value=''></option>
                                                <option value='A'>Autriche</option>
                                                <option value='AF'>Afghanistan</option>
                                                <option value='AL'>Albania</option>
                                                ...
                                            </select>
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                        </div>
                        <div class="col-md-12 scrollable_h" style="display:none; max-width: 100%;" id="block_add_client_facturation">
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Compte de prise en charge :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="" maxlength="">
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">Compte de tarification :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="" maxlength="">
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                            <div class="row block-champs">
                                <div class="col-md-5">
                                    <div class="form-group">
                                        <label class="label">Compte d'allotement :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="" maxlength="">
                                        </div>
                                    </div>
                                </div>
                                <div class="col-md-7" style="padding-left: 45px;">
                                    <div class="form-group">
                                        <label class="label">Compte de fid&eacute;lit&eacute; :</label>
                                        <div class="" style="position: relative;">
                                            <input type="text" class="form-control input-sm champ-modal" name="" maxlength="">
                                        </div>
                                    </div>                              
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="submit" class="btn" style="background-color: black; color: white; font-size: 12px;" id="btnValiderPopupAjoutClient">Valider</button>
                    <button type="button" class="btn dark btn-outline dismiss-modal" style="background-color: white; color: black; font-size: 12px; font-weight: 700; border: 1px solid black;">Annuler</button>
                </div>
            </div>
        </form>
    </div>
</div>

tab机制的JavaScript代码:

tabs = [];
divs = [];
Array.from(document.querySelectorAll('#frmClient .tabs')).forEach((tab_container, TabID) => {
    const registers = tab_container.querySelector('.tab-registers');
    const bodies = tab_container.querySelector('.tab-bodies');
    Array.from(registers.children).forEach((el, i) => {
        el.setAttribute('aria-controls', `${TabID}_${i}`);
        bodies.children[i]?.setAttribute('id', `${TabID}_${i}`);
        el.addEventListener('click', (ev) => {
            let activeRegister = registers.querySelector('.active-tab');
            activeRegister.classList.remove('active-tab');
            activeRegister = el;
            activeRegister.classList.add('active-tab');
            let tabnum = `${i}`;
            changeBody_(registers, bodies, activeRegister, tabnum);
        });
        tabs.push(el);
        divs.push(el.getAttribute("href"));
    });
});

function changeBody_(registers, bodies, activeRegister, tabnum) {
    Array.from(registers.children).forEach((el, i) => {
        if (bodies.children[i]) {
            bodies.children[i].style.display = el == activeRegister ? 'block' : 'none';
        }
        el.setAttribute('aria-expanded', el == activeRegister ? 'true' : 'false');
    })
}

在运行时,当单击模态中的提交按钮时,会出现错误invalid form control with name='nomFacturation' is not focusableinvalid form control with name='paysFacturation' is not focusable。我是这样管理的:

$(document).ready(function() {

    $("#btnValiderPopupAjoutClient").on("click", function(e) {
        $("#frmClient").attr('novalidate', 'novalidate');
        let videExist = false;
        let onglet = 0;
        for(let i in divs) {
            let obligatoiresVide = $(divs[i]+" input,textarea,select").filter('[required]').filter(function(idx) {
                return $(this).val() == "";
            });
            console.log("============ number of empty required =",obligatoiresVide.length);
            if (obligatoiresVide.length > 0) {
                videExist = true;
                onglet = i;
                break;
            }
        }
        if (videExist) {
            console.log("=========== tab index =",onglet);
            tabs[onglet].click();
            $("#frmClient").removeAttr('novalidate');
        }
    });

    ....

});

但是在运行时,当我在第一个选项卡上填写所有必填字段并将其他选项卡的必填字段留空时,控制台显示============ number of empty required = 1=========== tab index = 0,尽管它应该是=========== tab index = 1!我的代码有什么问题?

aiazj4mn

aiazj4mn1#

据我所知,你需要一个可以在选项卡之间导航的表单。我从头开始--这只是对结构的一个建议。
最主要的是表单上invalid的事件侦听器。我使用preventDefault()和useCapture参数来停止无效表单字段的默认行为。相反,我在表单字段上将类名设置为invalid,并将字段集名称设置为表单的data-feedback属性。这可以用于设置选项卡的样式。
现在,您可以在选项卡之间导航,并查看哪些选项卡/字段集无效。

// navigating the tabs
document.forms.form01.querySelector('.tabs').addEventListener('click', e => {
  e.preventDefault();
  if (e.target.nodeName == 'A') {
    let tabs = e.target.closest('ul.tabs');
    tabs.querySelectorAll('li').forEach(li => li.classList.remove('current'));
    e.target.closest('li').classList.add('current');
    e.target.closest('form').querySelectorAll('fieldset').forEach(fieldset => fieldset.classList.remove('current'));
    e.target.closest('form')[e.target.getAttribute('href')].classList.add('current');
  }
});

// when the form is valid it will submit
document.forms.form01.addEventListener('submit', e => {
  e.preventDefault();
  console.log('submitting...');
});

// when a form field is not valid
document.forms.form01.addEventListener('invalid', e => {
  e.preventDefault();
  e.target.classList.add('invalid');
  let feedback = new Set(e.target.form.dataset.feedback.split(' '));
  feedback.delete(''); // in the case of an empty item
  feedback.add(e.target.closest('fieldset').name);
  e.target.form.dataset.feedback = [...feedback.values()].join(' ');
}, true);

// when there is input on a form field
document.forms.form01.addEventListener('input', e => {
  let fieldset = e.target.closest('fieldset');
  if (e.target.validity.valid) {
    e.target.classList.remove('invalid');
    if (fieldset.validity.valid) {
      let feedback = new Set(e.target.form.dataset.feedback.split(' '));
      feedback.delete(fieldset.name);
      e.target.form.dataset.feedback = [...feedback.values()].join(' ');
    }
  }
});
input.invalid {
  border: red solid;
}

fieldset {
  display: none;
  flex-direction: column;
  align-items: flex-start;
}

fieldset.current {
  display: flex;
}

form[data-feedback~="fieldset1"] li.fieldset1 {
  background-color: orange;
}

form[data-feedback~="fieldset2"] li.fieldset2 {
  background-color: orange;
}

ul.tabs {
  margin: 0;
  padding: 0;
  display: flex;
  list-style: none;
}

ul.tabs a {
  text-decoration: none;
}

ul.tabs li.current a {
  text-decoration: underline;
}
<form name="form01" data-feedback="">
  <ul class="tabs">
    <li class="fieldset1 current"><a href="fieldset1">Test 1</a></li>
    <li class="fieldset2"><a href="fieldset2">Test 2</a></li>
  </ul>
  <fieldset name="fieldset1" class="current">
    <label>Text 1<input type="text" name="text1" required></label>
  </fieldset>
  <fieldset name="fieldset2">
     <label>Text 2<input type="text" name="text2" required></label>
  </fieldset>
  <button>Submit</button>
</form>

相关问题