如何在 Node-Express-Mongoose 中设置动态 select 控件的默认选项?
How to set default option for dynamic select control in Node-Express-Mongoose?
我现在在使用 PUG 作为视图引擎的 Node-Express 环境中工作。
我有 CompanySchema,其中一个字段“comp_ParentName”指的是模式本身:
comp_ParentName: {type: Schema.Types.ObjectId, ref: 'Company', required: false},
这不是必需的,因为并非每个公司都有母公司。因此,我想为用户提供一个选项,让他们在想要创建新公司时将此字段留空(在公司没有母公司或用户根本不知道公司是否成立的情况下)有任何母公司)。
我的“创建新公司”表单中有一些测试代码,但不幸的是它并没有 100% 达到我的目的:
div.form-group.row
label(class="col-sm-2 col-form-label col-form-label-sm")(for='comp_ParentName') Parent company:
div.col-sm-10
select#comp_ParentName.form-control(class="form-control form-control-sm" type='select', placeholder='Select parent company' name='comp_ParentName' required='false' )
- companies.sort(function(a, b) {let textA = a.comp_OfficialName_ENG.toUpperCase(); let textB = b.comp_OfficialName_ENG.toUpperCase(); return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;});
for company in companies
if company
option(value=company._id selected=(company._id.toString()===company._id.toString() ? 'selected' : false) ) #{company.comp_OfficialName_ENG}
else
option(value=company._id) #{company.comp_OfficialName_ENG}
我在上面的代码中遇到的问题是,我在表格中总是有一个“preselected”公司,但正如我所说,我希望可以选择将此字段留空。我试图在
的帮助下添加一些默认选项,例如“选择母公司”
option(value="" disabled selected) Choose Parent Company
但每次我尝试保存新公司时,都会弹出“请填写此字段”工具提示。
是否有任何可能的解决方法?
这是我在 companyController.js 中处理公司创建的代码:
exports.company_create_post = [
// Convert the companyrole to an array.
(req, res, next) => {
if(!(req.body.companyrole instanceof Array)){
if(typeof req.body.companyrole ==='undefined')
req.body.companyrole = [];
else
req.body.companyrole = new Array(req.body.companyrole);
}
next();
},
// Validate and sanitise fields.
body('comp_OfficialName_ENG', 'Must not be empty.').trim().isLength({ min: 1 }).escape(),
body('comp_ShortName_ENG', 'Must not be empty.').trim().isLength({ min: 1 }).escape(),
body('comp_GroupName_ENG', 'Must not be empty.').trim().isLength({ min: 1 }).escape(),
body('comp_Role.*').escape(),
body('comp_cntrID', 'comp_cntrID must be specified').trim().isLength({ min: 1 }).escape(), //reference to the associated country
body('comp_stID', 'comp_stID must be specified').trim().isLength({ min: 1 }).escape(), //reference to the associated state
body('comp_ctyID', 'comp_ctyID must be specified').trim().isLength({ min: 1 }).escape(), //reference to the associated city
// Process request after validation and sanitization.
(req, res, next) => {
// Extract the validation errors from a request.
const errors = validationResult(req);
// Create a Company object with escaped and trimmed data.
var company = new Company(
{ comp_OfficialName_ENG: req.body.comp_OfficialName_ENG,
comp_ShortName_ENG: req.body.comp_ShortName_ENG,
comp_GroupName_ENG: req.body.comp_GroupName_ENG,
comp_ParentName: req.body.comp_ParentName,
comp_Role: req.body.companyrole,
comp_cntrID: req.body.comp_cntrID,
comp_stID: req.body.comp_stID,
comp_ctyID: req.body.comp_ctyID
});
if (!errors.isEmpty()) {
// There are errors. Render form again with sanitized values/error messages.
// Get all Company roles for form.
async.parallel({
companyroles: function(callback) {
CompanyRole.find(callback);
},
}, function(err, results) {
if (err) { return next(err); }
// Mark our selected companyroles as checked.
for (let i = 0; i < results.companyroles.length; i++) {
if (company.companyrole.indexOf(results.companyroles[i]._id) > -1) {
results.companyroles[i].checked='true';
}
}
res.render('company_form', { title: 'Create Company', companyroles:results.companyroles, company: company, errors: errors.array() });
});
return;
}
else {
// Data from form is valid. Save company.
company.save(function (err) {
if (err) { return next(err); }
//successful - redirect to new company record.
res.redirect(company.url);
});
}
}];
更新:
在@Ankur R 的帮助下,问题已基本解决,但现在我面临另一个问题。
如果公司有母公司,那绝对没问题,我可以在 select 控件的下拉列表中选择母公司的名称。但是,在公司没有母公司的情况下,我的 company_detail.pug 中的点符号停止工作并给我一个错误。
company.comp_ParentName.comp_OfficialName_ENG
它说“无法读取未定义的 属性 'comp_OfficialName_ENG'”。考虑到为其分配了零值,这是非常合乎逻辑的:
option(value="" selected) No Parent Company
这是我在“company_form.pug”中的 select 控件(只是为了展示如何创建“comp_ParentName”):
div.form-group.row
label(class="col-sm-2 col-form-label col-form-label-sm")(for='comp_ParentName') Parent company:
div.col-sm-10
select#comp_ParentName.form-control(class="form-control form-control-sm" type='select', name='comp_ParentName' )
- companies.sort(function(a, b) {let textA = a.comp_OfficialName_ENG.toUpperCase(); let textB = b.comp_OfficialName_ENG.toUpperCase(); return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;});
option(value="" selected) No Parent Company
for company in companies
if company
option(value=company._id selected=(company._id.toString()===company._id.toString() ? 'selected' : false) ) #{company.comp_OfficialName_ENG}
else
option(value=company._id) #{company.comp_OfficialName_ENG}
这是“company_detail.pug”中的代码,其中点符号停止工作表示“comp_ParentName”未定义。
div.form-group.row
label(class="col-sm-2 col-form-label col-form-label-sm")(for='comp_ParentName') Parent company:
div.col-sm-3
input#comp_ParentName.form-control(class="form-control rdonly form-control-xs" type='text', name='comp_ParentName' value=(undefined===company ? '' : company.comp_ParentName.comp_OfficialName_ENG ) readonly)
关于如何处理这个问题有什么想法吗?
您创建 select 和选项的代码存在问题。
我尝试了下面的代码并且成功了。
form
div.form-group.row
label(class="col-sm-2 col-form-label col-form-label-sm")(for='comp_ParentName') Parent company:
div.col-sm-10
select#comp_ParentName.form-control(class="form-control form-control-sm", name="comp_ParentName")
option(value="" selected) Choose Parent Company
option(value="1") One
option(value="2") Two
div.form-group.row
button(type="submit") Submit
更新:
- 这里 select 无需指定 select="true/false" 因为浏览器只检查必需的属性。
- 不建议禁用select中的空值选项,因为一旦用户select其他选项并想取消select则不可能。
我在这里更正了您的控制器中的公司创建代码
// Create a Company object with escaped and trimmed data.
var company = new Company(
{ comp_OfficialName_ENG: req.body.comp_OfficialName_ENG,
comp_ShortName_ENG: req.body.comp_ShortName_ENG,
comp_GroupName_ENG: req.body.comp_GroupName_ENG,
...(!!req.body.comp_ParentName && { comp_ParentName: req.body.comp_ParentName }),
comp_Role: req.body.companyrole,
comp_cntrID: req.body.comp_cntrID,
comp_stID: req.body.comp_stID,
comp_ctyID: req.body.comp_ctyID
});
此外,如果您想对 mongo id 进行更严格的检查,那么请检查 here.
供参考。在对象创建中使用扩展运算符
https://medium.com/@slamflipstrom/conditional-object-properties-using-spread-in-javascript-714e0a12f496
终于解决了我的问题。只是我对 PUG 很陌生,不知道如何处理其中的 if 语句。我所要做的就是检查我的“company.comp_ParentName”是否被定义。因此添加以下 if 语句有助于解决问题:
if (typeof(company.comp_ParentName) == 'undefined')
我现在在使用 PUG 作为视图引擎的 Node-Express 环境中工作。
我有 CompanySchema,其中一个字段“comp_ParentName”指的是模式本身:
comp_ParentName: {type: Schema.Types.ObjectId, ref: 'Company', required: false},
这不是必需的,因为并非每个公司都有母公司。因此,我想为用户提供一个选项,让他们在想要创建新公司时将此字段留空(在公司没有母公司或用户根本不知道公司是否成立的情况下)有任何母公司)。
我的“创建新公司”表单中有一些测试代码,但不幸的是它并没有 100% 达到我的目的:
div.form-group.row
label(class="col-sm-2 col-form-label col-form-label-sm")(for='comp_ParentName') Parent company:
div.col-sm-10
select#comp_ParentName.form-control(class="form-control form-control-sm" type='select', placeholder='Select parent company' name='comp_ParentName' required='false' )
- companies.sort(function(a, b) {let textA = a.comp_OfficialName_ENG.toUpperCase(); let textB = b.comp_OfficialName_ENG.toUpperCase(); return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;});
for company in companies
if company
option(value=company._id selected=(company._id.toString()===company._id.toString() ? 'selected' : false) ) #{company.comp_OfficialName_ENG}
else
option(value=company._id) #{company.comp_OfficialName_ENG}
我在上面的代码中遇到的问题是,我在表格中总是有一个“preselected”公司,但正如我所说,我希望可以选择将此字段留空。我试图在
的帮助下添加一些默认选项,例如“选择母公司”option(value="" disabled selected) Choose Parent Company
但每次我尝试保存新公司时,都会弹出“请填写此字段”工具提示。
是否有任何可能的解决方法?
这是我在 companyController.js 中处理公司创建的代码:
exports.company_create_post = [
// Convert the companyrole to an array.
(req, res, next) => {
if(!(req.body.companyrole instanceof Array)){
if(typeof req.body.companyrole ==='undefined')
req.body.companyrole = [];
else
req.body.companyrole = new Array(req.body.companyrole);
}
next();
},
// Validate and sanitise fields.
body('comp_OfficialName_ENG', 'Must not be empty.').trim().isLength({ min: 1 }).escape(),
body('comp_ShortName_ENG', 'Must not be empty.').trim().isLength({ min: 1 }).escape(),
body('comp_GroupName_ENG', 'Must not be empty.').trim().isLength({ min: 1 }).escape(),
body('comp_Role.*').escape(),
body('comp_cntrID', 'comp_cntrID must be specified').trim().isLength({ min: 1 }).escape(), //reference to the associated country
body('comp_stID', 'comp_stID must be specified').trim().isLength({ min: 1 }).escape(), //reference to the associated state
body('comp_ctyID', 'comp_ctyID must be specified').trim().isLength({ min: 1 }).escape(), //reference to the associated city
// Process request after validation and sanitization.
(req, res, next) => {
// Extract the validation errors from a request.
const errors = validationResult(req);
// Create a Company object with escaped and trimmed data.
var company = new Company(
{ comp_OfficialName_ENG: req.body.comp_OfficialName_ENG,
comp_ShortName_ENG: req.body.comp_ShortName_ENG,
comp_GroupName_ENG: req.body.comp_GroupName_ENG,
comp_ParentName: req.body.comp_ParentName,
comp_Role: req.body.companyrole,
comp_cntrID: req.body.comp_cntrID,
comp_stID: req.body.comp_stID,
comp_ctyID: req.body.comp_ctyID
});
if (!errors.isEmpty()) {
// There are errors. Render form again with sanitized values/error messages.
// Get all Company roles for form.
async.parallel({
companyroles: function(callback) {
CompanyRole.find(callback);
},
}, function(err, results) {
if (err) { return next(err); }
// Mark our selected companyroles as checked.
for (let i = 0; i < results.companyroles.length; i++) {
if (company.companyrole.indexOf(results.companyroles[i]._id) > -1) {
results.companyroles[i].checked='true';
}
}
res.render('company_form', { title: 'Create Company', companyroles:results.companyroles, company: company, errors: errors.array() });
});
return;
}
else {
// Data from form is valid. Save company.
company.save(function (err) {
if (err) { return next(err); }
//successful - redirect to new company record.
res.redirect(company.url);
});
}
}];
更新: 在@Ankur R 的帮助下,问题已基本解决,但现在我面临另一个问题。 如果公司有母公司,那绝对没问题,我可以在 select 控件的下拉列表中选择母公司的名称。但是,在公司没有母公司的情况下,我的 company_detail.pug 中的点符号停止工作并给我一个错误。
company.comp_ParentName.comp_OfficialName_ENG
它说“无法读取未定义的 属性 'comp_OfficialName_ENG'”。考虑到为其分配了零值,这是非常合乎逻辑的:
option(value="" selected) No Parent Company
这是我在“company_form.pug”中的 select 控件(只是为了展示如何创建“comp_ParentName”):
div.form-group.row
label(class="col-sm-2 col-form-label col-form-label-sm")(for='comp_ParentName') Parent company:
div.col-sm-10
select#comp_ParentName.form-control(class="form-control form-control-sm" type='select', name='comp_ParentName' )
- companies.sort(function(a, b) {let textA = a.comp_OfficialName_ENG.toUpperCase(); let textB = b.comp_OfficialName_ENG.toUpperCase(); return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;});
option(value="" selected) No Parent Company
for company in companies
if company
option(value=company._id selected=(company._id.toString()===company._id.toString() ? 'selected' : false) ) #{company.comp_OfficialName_ENG}
else
option(value=company._id) #{company.comp_OfficialName_ENG}
这是“company_detail.pug”中的代码,其中点符号停止工作表示“comp_ParentName”未定义。
div.form-group.row
label(class="col-sm-2 col-form-label col-form-label-sm")(for='comp_ParentName') Parent company:
div.col-sm-3
input#comp_ParentName.form-control(class="form-control rdonly form-control-xs" type='text', name='comp_ParentName' value=(undefined===company ? '' : company.comp_ParentName.comp_OfficialName_ENG ) readonly)
关于如何处理这个问题有什么想法吗?
您创建 select 和选项的代码存在问题。
我尝试了下面的代码并且成功了。
form
div.form-group.row
label(class="col-sm-2 col-form-label col-form-label-sm")(for='comp_ParentName') Parent company:
div.col-sm-10
select#comp_ParentName.form-control(class="form-control form-control-sm", name="comp_ParentName")
option(value="" selected) Choose Parent Company
option(value="1") One
option(value="2") Two
div.form-group.row
button(type="submit") Submit
更新:
- 这里 select 无需指定 select="true/false" 因为浏览器只检查必需的属性。
- 不建议禁用select中的空值选项,因为一旦用户select其他选项并想取消select则不可能。
我在这里更正了您的控制器中的公司创建代码
// Create a Company object with escaped and trimmed data.
var company = new Company(
{ comp_OfficialName_ENG: req.body.comp_OfficialName_ENG,
comp_ShortName_ENG: req.body.comp_ShortName_ENG,
comp_GroupName_ENG: req.body.comp_GroupName_ENG,
...(!!req.body.comp_ParentName && { comp_ParentName: req.body.comp_ParentName }),
comp_Role: req.body.companyrole,
comp_cntrID: req.body.comp_cntrID,
comp_stID: req.body.comp_stID,
comp_ctyID: req.body.comp_ctyID
});
此外,如果您想对 mongo id 进行更严格的检查,那么请检查 here.
供参考。在对象创建中使用扩展运算符 https://medium.com/@slamflipstrom/conditional-object-properties-using-spread-in-javascript-714e0a12f496
终于解决了我的问题。只是我对 PUG 很陌生,不知道如何处理其中的 if 语句。我所要做的就是检查我的“company.comp_ParentName”是否被定义。因此添加以下 if 语句有助于解决问题:
if (typeof(company.comp_ParentName) == 'undefined')