ASP.NET Core表单克隆后无法切换intl-tel-input国家选项问题
问题解决:克隆表单后intl-tel-input无法切换国家及号码获取方案
问题根源
- 重复ID冲突:原表单的input带有固定ID(
contact-phone/fax-contact),克隆后出现多个相同ID元素,导致JS选择器无法正确定位新元素。 - 克隆残留插件DOM:直接克隆包含intl-tel-input生成的额外DOM(如国家选择下拉框)的表单,会引发新旧实例的事件与DOM结构冲突,无法正常触发国家切换。
- 实例初始化逻辑问题:销毁实例的时机错误,克隆后的元素残留旧实例绑定,导致新实例初始化失败。
修正后的代码实现
视图部分(移除固定ID,保留类选择器)
<div id="contact-forms-container"> <!-- 初始联系表单 --> <div class="form-card contact-form-card"> <h5 class="form-title">Contact 1</h5> <form> <div class="form-row align-items-center"> <div class="col-md-6 mb-3"> <label>Phone number</label> <!-- 移除固定ID,仅保留类 --> <input type="text" class="form-control contact-phone" placeholder="Phone number"> </div> <div class="col-md-6 mb-3"> <label>Fax</label> <input type="text" class="form-control fax-contact" placeholder="Fax"> </div> </div> <button type="button" class="btn btn-danger remove-form-button">移除</button> </form> </div> </div> <button type="button" id="add-another-contact-form" class="btn btn-primary mt-3">添加新联系人表单</button>
JS部分(修复克隆逻辑、实例初始化及号码获取)
$(document).ready(function () { var contactCounter = 2; // 初始化第一个表单 initializeForm($(".contact-form-card").first()); $("#add-another-contact-form").on("click", function () { // 基于初始表单克隆并重置状态 const originalForm = $(".contact-form-card").first().clone(); const clonedForm = resetFormForClone(originalForm); // 设置新表单标题 clonedForm.find(".form-title").text(`Contact ${contactCounter}`); // 绑定移除事件 clonedForm.find(".remove-form-button").on("click", function () { // 移除前销毁插件实例 destroyFormInstances(clonedForm); clonedForm.remove(); }); // 添加到容器并初始化插件 $("#contact-forms-container").append(clonedForm); initializeForm(clonedForm); contactCounter++; }); // 重置克隆表单,清理插件生成的DOM和输入值 function resetFormForClone(form) { form.find(".iti").remove(); form.find(".contact-phone, .fax-contact").val("").removeClass("iti-input"); return form; } // 销毁表单内的插件实例,避免内存泄漏 function destroyFormInstances(form) { const phoneInput = form.find(".contact-phone"); const faxInput = form.find(".fax-contact"); if (phoneInput.data("itiContact")) { phoneInput.data("itiContact").destroy(); phoneInput.removeData("itiContact"); } if (faxInput.data("itiFax")) { faxInput.data("itiFax").destroy(); faxInput.removeData("itiFax"); } } // 初始化表单的intl-tel-input插件 function initializeForm(form) { const phoneInput = form.find(".contact-phone"); const faxInput = form.find(".fax-contact"); // 初始化电话输入框 const itiContact = window.intlTelInput(phoneInput[0], { formatOnDisplay: true, separateDialCode: true, hiddenInput: `full_phone_${contactCounter - 1}`, // 唯一命名隐藏输入,避免提交冲突 utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js" }); // 初始化传真输入框 const itiFax = window.intlTelInput(faxInput[0], { formatOnDisplay: true, separateDialCode: true, hiddenInput: `full_fax_${contactCounter - 1}`, utilsScript: "https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js" }); // 存储实例到元素数据,方便后续调用 phoneInput.data("itiContact", itiContact); faxInput.data("itiFax", itiFax); // 国家切换事件:获取选中国家代码和完整号码 phoneInput.on("countrychange", function () { const countryData = itiContact.getSelectedCountryData(); const fullNumber = itiContact.getNumber(); console.log(`电话:国家代码${countryData.dialCode},完整号码${fullNumber}`); }); faxInput.on("countrychange", function () { const countryData = itiFax.getSelectedCountryData(); const fullNumber = itiFax.getNumber(); console.log(`传真:国家代码${countryData.dialCode},完整号码${fullNumber}`); }); } });
关键修改说明
- 移除重复ID:所有input仅保留类选择器,规避ID冲突导致的元素定位错误。
- 克隆前清理DOM:克隆表单时先移除插件生成的
.iti容器,确保新表单从原始input状态初始化,避免旧实例残留。 - 唯一隐藏输入名:
hiddenInput使用带计数器的命名,确保提交时每个表单的完整号码不会被覆盖。 - 实例销毁逻辑:移除表单前先销毁对应的intl-tel-input实例,避免内存泄漏。
- 直接获取实例数据:通过插件实例的
getSelectedCountryData()和getNumber()方法,直接获取国家代码与完整号码,无需额外存储。
内容的提问来源于stack exchange,提问作者Hameed Hassam
相关产品推荐
相关产品推荐

