【发布时间】:2020-09-21 02:42:32
【问题描述】:
在我的 Laravel 应用程序中,我有一个可能包含动态字段的表单。在“添加联系人”按钮上,单击从模板中添加的字段组。必须验证某些字段,因此我使用.rules() 方法为每个字段动态添加了规则。当我创建一个新实体时,这些动态字段应该是它的一部分,对我来说工作正常:
当我编辑实体时,我会根据从控制器获得的 json 字符串创建这些字段组。创建了具有值的字段,但由于某种原因,这些规则不适用于这些动态创建的字段。当我尝试将规则应用于此类字段时,出现错误:
Uncaught TypeError: Cannot read property 'settings' of undefined
我发现当我向动态字段添加规则时会发生这种情况:
let firstName = $('#first-name-' + elementNumber);
let jobTitle = $('#job-title-' + elementNumber);
let contactEmail = $('#contact-email-' + elementNumber);
firstName.rules("add", {
required: true
});
jobTitle.rules("add", {
required: true
});
contactEmail.rules("add", {
required: true,
email: true
});
我的代码:
let buildingForm = $('#building_form');
let addContactButton = $('#add_contact');
let contactsContainer = $('#contacts_container');
var elementNumber = 1;
let model = "{{ $model->building_id ?? '' }}"
if (model) {
let buildingContacts = '{!! $buildingContacts ?? "" !!}'
if (buildingContacts) {
buildingContacts = JSON.parse(buildingContacts)
$.each(buildingContacts, function (index, value) {
addContact(value)
elementNumber++
});
}
}
addContactButton.on('click', function () {
addContact()
elementNumber++
});
buildingForm.validate({
ignore: ""
});
function addContact(value = null) {
let contactLayout = getContactLayout(elementNumber, value);
contactsContainer.prepend(contactLayout);
let firstName = $('#first-name-' + elementNumber);
let jobTitle = $('#job-title-' + elementNumber);
let contactEmail = $('#contact-email-' + elementNumber);
firstName.rules("add", {
required: true
});
jobTitle.rules("add", {
required: true
});
contactEmail.rules("add", {
required: true,
email: true
});
$('#delete-contact-button-' + elementNumber).on('click', function (e) {
$.confirm({
title: 'Confirm action',
content: 'Are you sure you want to delete Contact?',
buttons: {
confirm: function () {
deleteContact(e.target.id);
},
cancel: function () {
$.alert('Canceled');
},
}
});
});
}
function deleteContact(buttonId) {
let buttonOneContactContainer = $('#' + buttonId).closest('div.one-contact-container');
buttonOneContactContainer.remove();
}
function getContactLayout(elementNumber, value = null) {
return `
<div class="p-t-10 p-b-10 p-l-10 p-r-10 m-t-10 border one-contact-container" id="one-contact-container-${elementNumber}">
<div class="row">
<div class="col-sm-6">
<div class="form-group row">
<label for="first-name-${elementNumber}" class="col-md-4 label-right">First Name <span class="required">*</span></label>
<div class="col-md-8">
<input name="contacts[first_name][${elementNumber}]" id="first-name-${elementNumber}" type="text" value="${value ? value.first_name : ''}" class="form-control first-name-input">
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group row">
<label for="last-name-${elementNumber}" class="col-md-4 label-right">Last Name</label>
<div class="col-md-8">
<input name="contacts[last_name][${elementNumber}]" id="last-name-${elementNumber}" type="text" value="${value ? value.last_name : ''}" class="form-control">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group row">
<label for="job-title-${elementNumber}" class="col-md-4 label-right">Job Title <span class="required">*</span></label>
<div class="col-md-8">
<input name="contacts[job_title][${elementNumber}]" id="job-title-${elementNumber}" type="text" value="${value ? value.job_title : ''}" class="form-control job-title-input">
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group row">
<label for="contact-email-${elementNumber}" class="col-md-4 label-right">Email <span class="required">*</span></label>
<div class="col-md-8">
<input name="contacts[contact_email][${elementNumber}]" id="contact-email-${elementNumber}" type="text" value="${value ? value.email : ''}" class="form-control email-input">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group row">
<label for="office-phone-${elementNumber}" class="col-md-4 label-right">Office Phone</label>
<div class="col-md-8">
<input name="contacts[office_phone][${elementNumber}]" id="office-phone-${elementNumber}" type="text" value="${value ? value.office_phone : ''}" class="form-control">
</div>
</div>
</div>
<div class="col-sm-6">
<div class="form-group row">
<label for="mobile-phone-${elementNumber}" class="col-md-4 label-right">Mobile Phone</label>
<div class="col-md-8">
<input name="contacts[mobile_phone][${elementNumber}]" id="mobile-phone-${elementNumber}" type="text" value="${value ? value.mobile_phone : ''}" class="form-control">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="form-group row">
<label for="contact-notes-${elementNumber}" class="col-md-2 label-right">Notes</label>
<div class="col-md-10">
<textarea name="contacts[contact_notes][${elementNumber}]" id="contact-notes-${elementNumber}" class="form-control">${value ? value.notes : ''}</textarea>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 test-right">
<span class="btn-danger btn pull-right delete-contact" id="delete-contact-button-${elementNumber}">Delete contact</span>
</div>
</div>
</div>
`;
}
因此,创建新字段并从 json 字符串生成现有字段具有相同的功能。
JSON 示例:
[{
"building_contact_id": 781,
"building_id": 76516,
"job_title": "Officer",
"first_name": "John",
"last_name": "",
"mobile_phone": "",
"office_phone": "",
"email": "john.doe@mail.com",
"notes": "",
"created_at": "2020-06-02T13:42:32.000000Z",
"updated_at": "2020-06-02T13:42:32.000000Z"
}]
【问题讨论】:
-
firstName = $('#first-name-' + elementNumber)不是“动态”变量 - 它获取当时存在的匹配元素。所以firstName.rules将只适用于它运行时存在的元素。
标签: jquery laravel jquery-validate