Required questions

pull/1/head
yflory 3 years ago
parent 5d04cd0f4f
commit 583060d130

@ -356,10 +356,25 @@
.cp-form-block-question { .cp-form-block-question {
margin-bottom: 5px; margin-bottom: 5px;
display: flex;
.cp-form-block-question-number { .cp-form-block-question-number {
font-weight: bold; font-weight: bold;
margin-right: 10px; margin-right: 10px;
} }
.cp-form-block-question-text {
flex: 1;
}
.cp-form-required-tag {
background: fade(@cryptpad_text_col, 15%);
padding: 5px;
margin-top: -10px;
margin-right: -10px;
&.cp-is-empty {
padding: 3px;
border: 2px solid @cryptpad_color_red;
color: @cp_form-invalid;
}
}
} }
.cp-form-block-content { .cp-form-block-content {
overflow-x: auto; overflow-x: auto;
@ -548,8 +563,8 @@
.cp-form-creator-results-content { .cp-form-creator-results-content {
padding-bottom: 100px; padding-bottom: 100px;
.cp-form-block { .cp-form-block {
background: @cp_form-bg1; background: @cp_form-bg1;
padding: 10px; padding: 10px;
} }
} }
.cp-form-block-question { .cp-form-block-question {

@ -1004,6 +1004,7 @@ define([
var setCursorGetter = function (f) { cursorGetter = f; }; var setCursorGetter = function (f) { cursorGetter = f; };
return { return {
tag: tag, tag: tag,
isEmpty: function () { return !$tag.val().trim(); },
getValue: function () { getValue: function () {
//var invalid = $tag.is(':invalid'); //var invalid = $tag.is(':invalid');
//if (invalid) { return; } //if (invalid) { return; }
@ -1091,6 +1092,7 @@ define([
var setCursorGetter = function (f) { cursorGetter = f; }; var setCursorGetter = function (f) { cursorGetter = f; };
return { return {
tag: tag, tag: tag,
isEmpty: function () { return !$text.val().trim(); },
getValue: function () { return $text.val().slice(0, opts.maxLength); }, getValue: function () { return $text.val().slice(0, opts.maxLength); },
setValue: function (val) { setValue: function (val) {
$text.val(val); $text.val(val);
@ -1148,6 +1150,7 @@ define([
}); });
return { return {
tag: tag, tag: tag,
isEmpty: function () { return !this.getValue(); },
getValue: function () { getValue: function () {
var res; var res;
els.some(function (el) { els.some(function (el) {
@ -1241,6 +1244,12 @@ define([
}); });
return { return {
tag: tag, tag: tag,
isEmpty: function () {
var v = this.getValue();
return !Object.keys(v).length || Object.keys(v).some(function (uid) {
return !v[uid];
});
},
getValue: function () { getValue: function () {
var res = {}; var res = {};
var l = lines.slice(1); var l = lines.slice(1);
@ -1384,6 +1393,10 @@ define([
var setCursorGetter = function (f) { cursorGetter = f; }; var setCursorGetter = function (f) { cursorGetter = f; };
return { return {
tag: tag, tag: tag,
isEmpty: function () {
var v = this.getValue();
return !v.length;
},
getValue: function () { getValue: function () {
var res = []; var res = [];
els.forEach(function (el) { els.forEach(function (el) {
@ -1495,6 +1508,12 @@ define([
var setCursorGetter = function (f) { cursorGetter = f; }; var setCursorGetter = function (f) { cursorGetter = f; };
return { return {
tag: tag, tag: tag,
isEmpty: function () {
var v = this.getValue();
return Object.keys(v).some(function (uid) {
return !v[uid].length;
});
},
getValue: function () { getValue: function () {
var res = {}; var res = {};
var l = lines.slice(1); var l = lines.slice(1);
@ -1659,13 +1678,14 @@ define([
forceFallback: true, forceFallback: true,
store: { store: {
set: function () { set: function () {
evOnChange.fire();
reorder(); reorder();
evOnChange.fire();
} }
} }
}); });
return { return {
tag: tag, tag: tag,
isEmpty: function () { return !this.getValue(); },
getValue: function () { getValue: function () {
if (!sorted) { return; } if (!sorted) { return; }
return sortable.toArray().map(function (id) { return sortable.toArray().map(function (id) {
@ -2215,6 +2235,7 @@ define([
if (typeof(data.reset) === "function") { data.reset(); } if (typeof(data.reset) === "function") { data.reset(); }
}); });
$(reset).attr('disabled', 'disabled'); $(reset).attr('disabled', 'disabled');
evOnChange.fire();
}); });
var $send = $(send).click(function () { var $send = $(send).click(function () {
$send.attr('disabled', 'disabled'); $send.attr('disabled', 'disabled');
@ -2266,6 +2287,9 @@ define([
reset = undefined; reset = undefined;
} }
Messages.form_requiredWarning = "These questions need an answer:"; // XXX
var errors = h('div.cp-form-invalid-warning');
var $errors = $(errors);
var invalid = h('div.cp-form-invalid-warning'); var invalid = h('div.cp-form-invalid-warning');
var $invalid = $(invalid); var $invalid = $(invalid);
if (evOnChange) { if (evOnChange) {
@ -2274,7 +2298,28 @@ define([
priv = metadataMgr.getPrivateData(); priv = metadataMgr.getPrivateData();
origin = priv.origin; origin = priv.origin;
} }
evOnChange.reg(function () {
var gotoQuestion = function (el) {
var $el = $(el).closest('.cp-form-block');
var number = $el.find('.cp-form-block-question-number').text();
var a = h('a', {
href: origin + '#' + Messages._getKey('form_invalidQuestion', [number])
}, Messages._getKey('form_invalidQuestion', [number]));
$(a).click(function (e) {
e.preventDefault();
if (!$el.is(':visible')) {
var pages = $el.closest('.cp-form-page').index();
if (APP.refreshPage) { APP.refreshPage(pages + 1); }
}
$el[0].scrollIntoView();
});
return h('li', a);
};
if (APP.checkInvalidEvt) { evOnChange.unreg(APP.checkInvalidEvt); }
if (APP.checkErrorEvt) { evOnChange.unreg(APP.checkErrorEvt); }
// Check invalid inputs
APP.checkInvalidEvt = function () {
var $container = $('div.cp-form-creator-content'); var $container = $('div.cp-form-creator-content');
var $inputs = $container.find('input:invalid'); var $inputs = $container.find('input:invalid');
if (!$inputs.length) { if (!$inputs.length) {
@ -2284,21 +2329,7 @@ define([
$send.text(update ? Messages.form_updateWarning : Messages.form_submitWarning); $send.text(update ? Messages.form_updateWarning : Messages.form_submitWarning);
var lis = []; var lis = [];
$inputs.each(function (i, el) { $inputs.each(function (i, el) {
var $el = $(el).closest('.cp-form-block'); lis.push(gotoQuestion(el));
var number = $el.find('.cp-form-block-question-number').text();
var a = h('a', {
href: origin + '#' + Messages._getKey('form_invalidQuestion', [number])
}, Messages._getKey('form_invalidQuestion', [number]));
$(a).click(function (e) {
e.preventDefault();
if (!$el.is(':visible')) {
var pages = $el.closest('.cp-form-page').index();
if (APP.refreshPage) { APP.refreshPage(pages + 1); }
}
$el[0].scrollIntoView();
});
var li = h('li', a);
lis.push(li);
}); });
var list = h('ul', lis); var list = h('ul', lis);
var content = [ var content = [
@ -2306,12 +2337,47 @@ define([
list list
]; ];
$invalid.empty().append(content); $invalid.empty().append(content);
}); };
// Check empty required questions
APP.checkErrorEvt = function () {
if (!Array.isArray(APP.formBlocks)) { return; }
var form = content.form;
var errorBlocks = APP.formBlocks.filter(function (data) {
var uid = data.uid;
var block = form[uid];
if (!data.isEmpty) { return; }
if (!block) { return; }
if (!block.opts || !block.opts.required) { return; }
console.error(data.getValue());
var isEmpty = data.isEmpty();
var $el = $(data.tag).closest('.cp-form-block');
$el.find('.cp-form-required-tag').toggleClass('cp-is-empty', isEmpty);
return isEmpty;
});
if (!errorBlocks.length) {
$send.removeAttr('disabled');
return void $errors.empty();
}
$send.attr('disabled', 'disabled');
var lis = [];
errorBlocks.forEach(function (data) {
lis.push(gotoQuestion(data.tag));
});
var list = h('ul', lis);
var divContent = [
h('span', Messages.form_requiredWarning),
list
];
$errors.empty().append(divContent);
};
evOnChange.reg(APP.checkInvalidEvt);
evOnChange.reg(APP.checkErrorEvt);
evOnChange.fire(true); evOnChange.fire(true);
} }
return h('div.cp-form-send-container', [ return h('div.cp-form-send-container', [
invalid, invalid,
errors,
cbox ? h('div.cp-form-anon-answer', [ cbox ? h('div.cp-form-anon-answer', [
cbox, cbox,
anonName anonName
@ -2465,10 +2531,17 @@ define([
} }
Messages.form_required = "Required"; // XXX
var requiredTag;
if (block.opts && block.opts.required) {
requiredTag = h('span.cp-form-required-tag', Messages.form_required);
}
var dragHandle; var dragHandle;
var q = h('div.cp-form-block-question', [ var q = h('div.cp-form-block-question', [
h('span.cp-form-block-question-number', (n++)+'.'), h('span.cp-form-block-question-number', (n++)+'.'),
h('span', block.q || Messages.form_default) h('span.cp-form-block-question-text', block.q || Messages.form_default),
requiredTag
]); ]);
// Static blocks don't have questions ("q" is not used) so we can decrement n // Static blocks don't have questions ("q" is not used) so we can decrement n
if (isStatic) { n--; } if (isStatic) { n--; }
@ -2480,6 +2553,38 @@ define([
Messages.form_preview = "Preview:"; // XXX Messages.form_preview = "Preview:"; // XXX
var previewDiv = h('div.cp-form-preview', Messages.form_preview); var previewDiv = h('div.cp-form-preview', Messages.form_preview);
Messages.form_required_on = "Required answer";
Messages.form_required_off = "Optional answer";
// Required radio displayed only for types that have an "isEmpty" function
var requiredDiv;
if (APP.isEditor && !isStatic && data.isEmpty) {
if (!block.opts) { block.opts = {}; }
var isRequired = Boolean(block.opts.required);
var radioOn = UI.createRadio('cp-form-required-'+uid, 'cp-form-required-on',
Messages.form_required_on, isRequired, {
input: { value: 1 },
mark: { tabindex:1 }
});
var radioOff = UI.createRadio('cp-form-required-'+uid, 'cp-form-required-off',
Messages.form_required_off, !isRequired, {
input: { value: 0 },
mark: { tabindex:1 }
});
var radioContainer = h('div.cp-form-required-radio', [radioOn, radioOff]);
requiredDiv = h('div.cp-form-required', [
radioContainer
]);
$(radioContainer).find('input[type="radio"]').on('change', function() {
var val = $('input:radio[name="cp-form-required-'+uid+'"]:checked').val();
val = Number(val) || 0;
block.opts.required = Boolean(val);
framework.localChange();
framework._.cpNfInner.chainpad.onSettle(function () {
UI.log(Messages.saved);
});
});
}
if (editable) { if (editable) {
// Drag handle // Drag handle
dragHandle = h('span.cp-form-block-drag-handle', [ dragHandle = h('span.cp-form-block-drag-handle', [
@ -2568,6 +2673,7 @@ define([
$(editButtons).show(); $(editButtons).show();
$(data.tag).show(); $(data.tag).show();
$(previewDiv).show(); $(previewDiv).show();
$(requiredDiv).show();
return; return;
} }
$(editContainer).empty(); $(editContainer).empty();
@ -2576,6 +2682,8 @@ define([
var $oldTag = $(data.tag); var $oldTag = $(data.tag);
framework._.cpNfInner.chainpad.onSettle(function () { framework._.cpNfInner.chainpad.onSettle(function () {
$(editButtons).show(); $(editButtons).show();
$(previewDiv).show();
$(requiredDiv).show();
UI.log(Messages.saved); UI.log(Messages.saved);
_answers = getBlockAnswers(APP.answers, uid); _answers = getBlockAnswers(APP.answers, uid);
data = model.get(newOpts, _answers, null, evOnChange); data = model.get(newOpts, _answers, null, evOnChange);
@ -2585,6 +2693,7 @@ define([
}; };
var onEdit = function (tmp) { var onEdit = function (tmp) {
data.editing = true; data.editing = true;
$(requiredDiv).hide();
$(previewDiv).hide(); $(previewDiv).hide();
$(data.tag).hide(); $(data.tag).hide();
$(editContainer).append(data.edit(onSave, tmp, framework)); $(editContainer).append(data.edit(onSave, tmp, framework));
@ -2660,7 +2769,8 @@ define([
APP.isEditor ? dragHandle : undefined, APP.isEditor ? dragHandle : undefined,
isStatic ? undefined : q, isStatic ? undefined : q,
h('div.cp-form-block-content', [ h('div.cp-form-block-content', [
isStatic || !APP.isEditor ? undefined : previewDiv, APP.isEditor && !isStatic ? requiredDiv : undefined,
APP.isEditor && !isStatic ? previewDiv : undefined,
data.tag, data.tag,
editButtons editButtons
]), ]),
@ -2780,8 +2890,8 @@ define([
if (!answers) { if (!answers) {
$container.find('.cp-reset-button').attr('disabled', 'disabled'); $container.find('.cp-reset-button').attr('disabled', 'disabled');
} }
}; };
var getTempFields = function () { var getTempFields = function () {
if (!Array.isArray(APP.formBlocks)) { return; } if (!Array.isArray(APP.formBlocks)) { return; }

Loading…
Cancel
Save