mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
feat: add date and multiselect custom fields
This commit is contained in:
@@ -12,7 +12,9 @@
|
||||
"input-type-text": "Input (Text)",
|
||||
"input-type-link": "Input (Link)",
|
||||
"input-type-number": "Input (Number)",
|
||||
"input-type-date": "Input (Date)",
|
||||
"input-type-select": "Select",
|
||||
"input-type-select-multi": "Select Multiple",
|
||||
"select-options": "Options",
|
||||
"select-options-help": "Add one option per line for the select element",
|
||||
"minimum-reputation": "Minimum reputation",
|
||||
|
||||
@@ -213,6 +213,7 @@
|
||||
"custom-user-field-select-value-invalid": "Custom field selected option is invalid, %1",
|
||||
"custom-user-field-invalid-link": "Custom field link is invalid, %1",
|
||||
"custom-user-field-invalid-number": "Custom field number is invalid, %1",
|
||||
"custom-user-field-invalid-date": "Custom field date is invalid, %1",
|
||||
"invalid-custom-user-field": "Invalid custom user field, \"%1\" is already used by NodeBB",
|
||||
"post-already-flagged": "You have already flagged this post",
|
||||
"user-already-flagged": "You have already flagged this user",
|
||||
|
||||
@@ -69,7 +69,7 @@ define('admin/manage/user/custom-fields', [
|
||||
label: '[[global:save]]',
|
||||
callback: function () {
|
||||
const formData = modal.find('form').serializeObject();
|
||||
if (formData.type === 'select') {
|
||||
if (formData.type === 'select' || formData.type === 'select-multi') {
|
||||
formData.selectOptionsFormatted = formData['select-options'].trim().split('\n').join(', ');
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ define('admin/manage/user/custom-fields', [
|
||||
modal.find('#type-select').on('change', function () {
|
||||
const type = $(this).val();
|
||||
modal.find(`[data-input-type]`).addClass('hidden');
|
||||
modal.find(`[data-input-type="${type}"]`).removeClass('hidden');
|
||||
modal.find(`[data-input-type-${type}]`).removeClass('hidden');
|
||||
});
|
||||
|
||||
modal.find('#icon-select').on('click', function () {
|
||||
|
||||
@@ -46,8 +46,18 @@ define('forum/account/edit', [
|
||||
const els = $('[component="group/badge/list"] [component="group/badge/item"][data-selected="true"]');
|
||||
return els.map((i, el) => $(el).attr('data-value')).get();
|
||||
}
|
||||
const editForm = $('form[component="profile/edit/form"]');
|
||||
const userData = editForm.serializeObject();
|
||||
|
||||
// stringify multi selects
|
||||
editForm.find('select[multiple]').each((i, el) => {
|
||||
const name = $(el).attr('name');
|
||||
if (userData[name] && !Array.isArray(userData[name])) {
|
||||
userData[name] = [userData[name]];
|
||||
}
|
||||
userData[name] = JSON.stringify(userData[name] || []);
|
||||
});
|
||||
|
||||
const userData = $('form[component="profile/edit/form"]').serializeObject();
|
||||
userData.uid = ajaxify.data.uid;
|
||||
userData.groupTitle = userData.groupTitle || '';
|
||||
userData.groupTitle = JSON.stringify(getGroupSelection());
|
||||
|
||||
@@ -144,14 +144,23 @@ helpers.getCustomUserFields = async function (userData) {
|
||||
});
|
||||
|
||||
fields.forEach((f) => {
|
||||
let userValue = userData[f.key];
|
||||
if (f.type === 'select-multi' && userValue) {
|
||||
userValue = JSON.parse(userValue || '[]');
|
||||
}
|
||||
f['select-options'] = f['select-options'].split('\n').filter(Boolean).map(
|
||||
opt => ({
|
||||
value: opt,
|
||||
selected: opt === userData[f.key],
|
||||
selected: Array.isArray(userValue) ?
|
||||
userValue.includes(opt) :
|
||||
opt === userValue,
|
||||
})
|
||||
);
|
||||
if (userData[f.key]) {
|
||||
f.value = validator.escape(String(userData[f.key]));
|
||||
if (userValue) {
|
||||
if (Array.isArray(userValue)) {
|
||||
userValue = userValue.join(', ');
|
||||
}
|
||||
f.value = validator.escape(String(userValue));
|
||||
}
|
||||
});
|
||||
return fields;
|
||||
|
||||
@@ -113,6 +113,10 @@ module.exports = function (User) {
|
||||
throw new Error(tx.compile(
|
||||
'error:custom-user-field-invalid-number', field.name
|
||||
));
|
||||
} else if (value && type === 'input-date' && !validator.isDate(value)) {
|
||||
throw new Error(tx.compile(
|
||||
'error:custom-user-field-invalid-date', field.name
|
||||
));
|
||||
} else if (value && field.type === 'input-link' && !validator.isURL(String(value))) {
|
||||
throw new Error(tx.compile(
|
||||
'error:custom-user-field-invalid-link', field.name
|
||||
@@ -124,6 +128,14 @@ module.exports = function (User) {
|
||||
'error:custom-user-field-select-value-invalid', field.name
|
||||
));
|
||||
}
|
||||
} else if (field.type === 'select-multi') {
|
||||
const opts = field['select-options'].split('\n').filter(Boolean);
|
||||
const values = JSON.parse(value || '[]');
|
||||
if (!Array.isArray(values) || !values.every(value => opts.includes(value))) {
|
||||
throw new Error(tx.compile(
|
||||
'error:custom-user-field-select-value-invalid', field.name
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<td class="text-nowrap">{{{ if ./icon }}}<i class="text-muted {./icon}"></i> {{{ end }}}{./name}</td>
|
||||
<td>
|
||||
{./type}
|
||||
{{{ if (./type == "select") }}}
|
||||
{{{ if ((./type == "select") || (./type == "select-multi")) }}}
|
||||
<div class="text-muted">
|
||||
({./selectOptionsFormatted})
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
<option value="input-text" {{{ if (type == "input-text") }}}selected{{{ end }}}>[[admin/manage/user-custom-fields:input-type-text]]</option>
|
||||
<option value="input-link" {{{ if (type == "input-link") }}}selected{{{ end }}}>[[admin/manage/user-custom-fields:input-type-link]]</option>
|
||||
<option value="input-number" {{{ if (type == "input-number") }}}selected{{{ end }}}>[[admin/manage/user-custom-fields:input-type-number]]</option>
|
||||
<option value="input-date" {{{ if (type == "input-date") }}}selected{{{ end }}}>[[admin/manage/user-custom-fields:input-type-date]]</option>
|
||||
<option value="select" {{{ if (type == "select") }}}selected{{{ end }}}>[[admin/manage/user-custom-fields:input-type-select]]</option>
|
||||
<option value="select-multi" {{{ if (type == "select-multi") }}}selected{{{ end }}}>[[admin/manage/user-custom-fields:input-type-select-multi]]</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -33,7 +35,7 @@
|
||||
<p class="form-text">[[admin/manage/user-custom-fields:minimum-reputation-help]]</p>
|
||||
</div>
|
||||
|
||||
<div class="mb-3 {{{ if (type != "select") }}}hidden{{{ end }}}" data-input-type="select">
|
||||
<div class="mb-3 {{{ if ((type != "select") && (type != "select-multi")) }}}hidden{{{ end }}}" data-input-type data-input-type-select data-input-type-select-multi>
|
||||
<label class="form-label">[[admin/manage/user-custom-fields:select-options]]</label>
|
||||
<textarea class="form-control" name="select-options" rows="6">{./select-options}</textarea>
|
||||
<p class="form-text">[[admin/manage/user-custom-fields:select-options-help]]</p>
|
||||
|
||||
Reference in New Issue
Block a user