我正在为从事特殊项目的承包商提交时间申请。我有两个选择元素,
projectSelect
和 payPeriodSelect
。
我使用 JavaScript 承诺链来检索和加载项目和付款周期。在项目选择中选择项目后,付款周期选择中就会填充选项。
用户单击“提交”后,我将时间条目保存到数据库中,并根据时间表状态更新选择选项突出显示颜色(绿色表示已批准,红色表示拒绝,灰色表示已提交)。我需要刷新项目和付款期选择选项列表,以便选项以正确的颜色突出显示。
为了做到这一点,我需要再次调用
getProjects()
和 getPayPeriods()
,并以编程方式更改 projectSelect
和 payPeriodSelect
的值。我可以使用 jQuery 的 payPeriodSelect
函数更改 .val()
的值。然而,当我使用相同的方法时,projectSelect
值设置为null
。为什么它对一个选择有效,但对另一选择无效?
选择元素的定义如下:
<select id='projectSelect' class="form-select"></select>
<select id='payPeriodSelect' class="form-select"></select>
页面首次加载时,将调用加载项目的承诺链:
getProjects()
.then(data => {
return loadProjects(data);
})
.then(data => {
$('#projectSelect').change(); // select the default project to display (1st option in list)
})
.catch(error => {
// display error in modal
});
function loadProjects(projectData) {
return new Promise((resolve, reject) => {
let select = document.getElementById("projectSelect");
select.length = 0;
projectData.reduce((previousPromise, project) => { // map each project object in the array to a new promise
return previousPromise
.then(x => getPayPeriods(project.id))
.then(payPeriods => {
let option = document.createElement("option")
if (payPeriods.length) {
// if all timesheets for the project have been approved, change highlight color of option to green
if (payPeriods.every(payPeriod => payPeriod.approvalStatus)) {
option.setAttribute('class', 'approvedColor')
}
// If all timesheets are rejected, change color to red
else if (payPeriods.every(payPeriod => payPeriod.rejectionStatus)) {
option.setAttribute('class', 'rejectedColor')
}
// if all timesheets are submitted, change color to gray
else if (payPeriods.every(payPeriod => payPeriod.submissionStatus)) {
option.setAttribute('class', 'submittedColor')
}
}
option.text = project.code + ' - ' + project.name
option.value = project.id
select.appendChild(option)
select.value = select.options[0].value // set 1st option's project ID as default value
return resolve(true)
})
.catch(error => {
return reject(error)
})
}, Promise.resolve()) // Promise.resolve() is the initial promise function that starts the chain
return resolve(true);
})
}
projectSelect
和负荷支付期功能的更改事件如下所示:
$('#projectSelect').on('change', function (e) {
$('tr').find("input.timeBox").val("") // clear timesheet inputs
let projectId = this.value
getPayPeriods(projectId)
.then(data => {
return loadPayPeriods(data)
})
.then(x => {
$('#payPeriodSelect').trigger('change')
})
.catch(error => {
})
})
function loadPayPeriods(data) {
return new Promise((resolve, reject)=>{
var select = document.getElementById("payPeriodSelect")
select.length = 0
if (!data.length) {
$('#payPeriodSelect').attr('disabled', true)
return reject(false)
}
// enable dropdown if there are pay periods to load into it
$('#payPeriodSelect').attr('disabled', false)
for (let payPeriod of data) {
let option = document.createElement("option")
option.text = payPeriod.start_d + ' - ' + payPeriod.end_d
option.value = payPeriod.start_d + '|' + payPeriod.end_d
// change pay period option highlight colors based on timesheet status
if (payPeriod.approval_d) {
option.setAttribute('class', 'approved')
} else if (payPeriod.rejection_d) {
option.setAttribute('class', 'rejected')
} else if (payPeriod.submission_d) {
option.setAttribute('class', 'submitted')
}
select.appendChild(option)
}
select.value = select.options[0].value
return resolve(true)
})
}
payPeriodSelect
更改事件:
$('#payPeriodSelect').on('change', function (e) {
// get and populate timesheet data for the selected pay period
getTimeData(this.value)
.then(data=> {
return loadTimeData(data)
})
.then(data => {
if (data) {
let payPeriodSelect = document.getElementById('payPeriodSelect')
if (data.approvalStatus) {
payPeriodSelect.options[payPeriodSelect.selectedIndex].setAttribute('class', 'approvedColor')
} else if (data.rejectionStatus) {
payPeriodSelect.options[payPeriodSelect.selectedIndex].setAttribute('class', 'rejectedColor')
} else if (data.submissionStatus) {
payPeriodSelect.options[payPeriodSelect.selectedIndex].setAttribute('class', 'submittedColor')
}
}
})
.then(x => {
return calculateTotalTime()
})
.catch(error => {
})
})
提交时间功能。我获取并加载项目,并更改两个选择元素的值。
projectSelect
值设置为空,而 payPeriodSelect
值设置为正确值。
$('#submitTol').on('click', function (e) {
return saveDataToDatabase()
.then(data => {
return getProjects()
})
.then(data => {
return loadProjects(data)
})
.then(x => {
return new Promise((resolve, reject) => {
$('#projectSelect').val(project.id).change()
return resolve(true)
})
})
.then(x => {
return new Promise((resolve, reject) => {
$('#payPeriodSelect').val( payPeriod.start_d + '-' + payPeriod.end_d).change()
return resolve(true)
})
}
}
抱歉有一堆代码,但我想提供一些有关如何在选择元素中检索和显示数据的上下文。我很困惑为什么改变
payPeriodSelect
的值有效,而不是 projectSelect
。
方法 .change() 不会更改所选的
<select>
<option>
,而是 .on('change') 和 .trigger('change') 的简写。而且它在 jQuery 3.3 中已被弃用,所以可能不要使用它。
select.value
和option.value
之间有区别。您很可能想要选定的选项值。
要获取该值,您可以使用:
$('select option:selected').val(); //jquery
document.querySelector('select').selectedOptions[0].value // javascript
要设置该值,您必须循环所有选项并找到与您想要的属性/文本/值相匹配的选项:
$('select option').each(function() { //jquery
if (this.value === value) { this.selected = true; }
});
document.querySelectorAll('select option').forEach(function(option) { //javascript
if (option.value === value) { option.selected = true; }
});