pull/1/head
yflory 3 years ago
parent 0d4a834d42
commit 899d0b7d13

@ -1438,18 +1438,25 @@ define([
window.setTimeout(function () { $innerblock.hide(); }, 0); window.setTimeout(function () { $innerblock.hide(); }, 0);
}; };
config.options.forEach(function (o) { var setOptions = function (options) {
if (!isValidOption(o)) { return; } options.forEach(function (o) {
if (isElement(o)) { return $innerblock.append($(o)); } if (!isValidOption(o)) { return; }
var $el = $('<' + o.tag + '>', o.attributes || {}).html(o.content || ''); if (isElement(o)) { return $innerblock.append($(o)); }
$el.appendTo($innerblock); var $el = $('<' + o.tag + '>', o.attributes || {}).html(o.content || '');
if (typeof(o.action) === 'function') { $el.appendTo($innerblock);
$el.click(function (e) { if (typeof(o.action) === 'function') {
var close = o.action(e); $el.click(function (e) {
if (close) { hide(); } var close = o.action(e);
}); if (close) { hide(); }
} });
}); }
});
};
setOptions(config.options);
$container.setOptions = function (options) {
$innerblock.empty();
setOptions(options);
};
$container.append($button).append($innerblock); $container.append($button).append($innerblock);

@ -582,7 +582,7 @@ define([
flatpickr: true, flatpickr: true,
val: +f.selectedDates[0], val: +f.selectedDates[0],
y: rect && rect.y y: rect && rect.y
} };
}); });
} }
return { return {
@ -607,8 +607,9 @@ define([
val = +f.selectedDates[0]; val = +f.selectedDates[0];
} }
} }
var uid = $(el).data('uid');
var hasUid = values.some(function (i) { return i.uid === uid; }); var hasUid = values.some(function (i) { return i.uid === uid; });
var uid = hasUid ? Util.uid : $(el).data('uid'); if (hasUid) { uid = Util.uid(); }
values.push({ values.push({
uid: uid, uid: uid,
v: val v: val
@ -625,7 +626,7 @@ define([
var val = ($(el).val() || el.placeholder || '').trim(); var val = ($(el).val() || el.placeholder || '').trim();
var uid = $(el).data('uid'); var uid = $(el).data('uid');
var hasUid = items.some(function (i) { return i.uid === uid; }); var hasUid = items.some(function (i) { return i.uid === uid; });
var uid = hasUid ? Util.uid : $(el).data('uid'); if (hasUid) { uid = Util.uid(); }
items.push({ items.push({
uid: uid, uid: uid,
v: val v: val
@ -912,6 +913,12 @@ define([
return res; return res;
}; };
var getSections = function (content) {
var uids = Object.keys(content.form).filter(function (uid) {
return content.form[uid].type === 'section';
});
return uids;
};
var getFullOrder = function (content) { var getFullOrder = function (content) {
var order = content.order.slice(); var order = content.order.slice();
getSections(content).forEach(function (uid) { getSections(content).forEach(function (uid) {
@ -941,6 +948,25 @@ define([
}).filter(Boolean); }).filter(Boolean);
}; };
// When there is a change to the form, we need to check if we can still add
// conditions to the different sections
evShowConditions.reg(function () {
(APP.formBlocks || []).forEach(function (block) {
if (!block || !block.updateState) { return; }
block.updateState();
});
});
// When a section contains a condition that is now invalid (the question has been moved
// or deleted locally), we need to redraw the list of conditions for this section
evCheckConditions.reg(function (_uid) {
(APP.formBlocks || []).some(function (block) {
if (block.uid && block.uid !== _uid) { return; }
if (!block || !block.updateState) { return; }
return block.updateState(true, _uid);
});
});
Messages.form_type_section = "Conditional section"; // XXX Messages.form_type_section = "Conditional section"; // XXX
var STATIC_TYPES = { var STATIC_TYPES = {
md: { md: {
@ -1100,14 +1126,16 @@ define([
type: type, type: type,
q: block.q || Messages.form_default q: block.q || Messages.form_default
}; };
var val;
if (type === 'radio') { if (type === 'radio') {
obj.values = block.opts ? block.opts.values val = block.opts ? block.opts.values
: TYPES.radio.defaultOpts.values; : APP.TYPES.radio.defaultOpts.values;
} }
if (type === 'checkbox') { if (type === 'checkbox') {
obj.values = block.opts ? block.opts.values val = block.opts ? block.opts.values
: TYPES.checkbox.defaultOpts.values; : APP.TYPES.checkbox.defaultOpts.values;
} }
obj.values = extractValues(val);
return obj; return obj;
}).filter(Boolean); }).filter(Boolean);
return values; return values;
@ -1131,6 +1159,7 @@ define([
$container.append(btn); $container.append(btn);
return $b; return $b;
}; };
var values = getConditionsValues();
getConditions = function ($container, isNew, rules, condition, $btn) { getConditions = function ($container, isNew, rules, condition, $btn) {
Messages.form_condition_q = "Choose a question"; // XXX Messages.form_condition_q = "Choose a question"; // XXX
Messages.form_condition_v = "Choose a value"; // XXX Messages.form_condition_v = "Choose a value"; // XXX
@ -1168,7 +1197,6 @@ define([
onChange(); onChange();
var values = getConditionsValues();
var qOptions = values.map(function (obj) { var qOptions = values.map(function (obj) {
return { return {
tag: 'a', tag: 'a',
@ -1254,7 +1282,6 @@ define([
$container.append($content); $container.append($content);
} }
var isChange;
qSelect.onChange.reg(function (prettyVal, val, init) { qSelect.onChange.reg(function (prettyVal, val, init) {
qSelect.find('button').removeClass('btn-secondary') qSelect.find('button').removeClass('btn-secondary')
.addClass('btn-default'); .addClass('btn-default');
@ -1373,36 +1400,18 @@ define([
}; };
redraw(); redraw();
Messages.form_condition_hint = "To make this section conditional, please add a choice or checkbox question above it."; // XXX
var hintDiv = h('div.cp-form-conditional-hint', [
h('div.cp-form-conditional-hint', Messages.form_condition_hint)
]);
var $hint = $(hintDiv).prependTo(tag);
$addC.click(function () { $addC.click(function () {
var rulesC = h('div.cp-form-condition-rule'); var rulesC = h('div.cp-form-condition-rule');
var $rulesC = $(rulesC); var $rulesC = $(rulesC);
getConditions($rulesC, true); getConditions($rulesC, true);
$addC.before($rulesC); $addC.before($rulesC);
}); });
if (getConditionsValues().length) {
$condition.show();
} else {
$condition.hide();
}
// XXX unreg these 2 events
evShowConditions.reg(function () {
if (getConditionsValues().length) {
$condition.show();
} else {
$condition.hide();
}
});
evCheckConditions.reg(function (_uid) {
if (uid !== _uid) { return; }
// If our conditions are invalid, redraw them
if (getConditionsValues().length) {
$condition.show();
} else {
$condition.hide();
}
$condition.find('.cp-form-condition-rule').remove();
redraw();
});
var cursorGetter = function () { var cursorGetter = function () {
var $activeDrop = $condition.find('.cp-dropdown-content:visible').first(); var $activeDrop = $condition.find('.cp-dropdown-content:visible').first();
@ -1444,7 +1453,89 @@ define([
} }
} }
}); });
// If "needRedraw" is false, we only want to know if we can add conditions and
// if we can't, make sure we delete incomplete conditions before hiding the button
// If "needRedraw" is true, it means we ant to redraw a section because some
// conditions are invalid
var updateState = function (needRedraw, _uid) {
if (needRedraw && uid !== _uid) { return; }
values = getConditionsValues();
var available = values.length;
if (available) {
$condition.show();
$hint.hide();
} else {
$condition.hide();
$hint.show();
}
if (needRedraw) {
$condition.find('.cp-form-condition-rule').remove();
redraw();
return true;
} else {
if (available) {
// Questions may have moved. We need to redraw our dropdowns
// to make sure we use the correct list
$condition.find('.cp-form-condition').each(function (i, el) {
// Update question dropdown
var $q = $(el).find('.cp-dropdown-container[data-drop="q"]');
var drop = $q[0] && $q[0].dropdown;
if (!drop) { return; }
var qOptions = values.map(function (obj) {
return {
tag: 'a',
attributes: {
'class': 'cp-form-condition-question',
'data-value': obj.uid,
'href': '#',
},
content: obj.q
};
});
drop.setOptions(qOptions);
// Update values dropdown
var $v = $(el).find('.cp-dropdown-container[data-drop="v"]');
if (!$v.length) { return; }
var dropV = $v[0] && $v[0].dropdown;
if (!dropV) { return; }
var val = drop.getValue();
var res, type;
values.some(function (obj) {
if (String(obj.uid) === String(val)) {
res = obj.values;
type = obj.type;
return true;
}
});
var vOptions = res.map(function (str) {
return {
tag: 'a',
attributes: {
'class': 'cp-form-condition-value',
'data-value': str,
'href': '#',
},
content: str
};
});
dropV.setOptions(vOptions);
});
} else {
// We don't have invalid condition but we may have incomplete
// conditions to delete
block.opts.when = [];
$condition.find('.cp-form-condition-rule').remove();
}
}
};
updateState();
return { return {
updateState: updateState,
tag: tag, tag: tag,
noViewMode: true, noViewMode: true,
getCursor: cursorGetter, getCursor: cursorGetter,
@ -1483,7 +1574,7 @@ define([
return rows; return rows;
}; };
var TYPES = { var TYPES = APP.TYPES = {
input: { input: {
defaultOpts: { defaultOpts: {
type: 'text' type: 'text'
@ -1628,7 +1719,10 @@ define([
compatible: ['radio', 'checkbox', 'sort'], compatible: ['radio', 'checkbox', 'sort'],
defaultOpts: { defaultOpts: {
values: [1,2].map(function (i) { values: [1,2].map(function (i) {
return Messages._getKey('form_defaultOption', [i]); return {
uid: Util.uid(),
v: Messages._getKey('form_defaultOption', [i])
};
}) })
}, },
get: function (opts, a, n, evOnChange) { get: function (opts, a, n, evOnChange) {
@ -1716,7 +1810,10 @@ define([
}; };
}), }),
values: [1,2].map(function (i) { values: [1,2].map(function (i) {
return Messages._getKey('form_defaultOption', [i]); return {
uid: Util.uid(),
v: Messages._getKey('form_defaultOption', [i])
};
}) })
}, },
get: function (opts, a, n, evOnChange) { get: function (opts, a, n, evOnChange) {
@ -1869,7 +1966,10 @@ define([
defaultOpts: { defaultOpts: {
max: 3, max: 3,
values: [1, 2, 3].map(function (i) { values: [1, 2, 3].map(function (i) {
return Messages._getKey('form_defaultOption', [i]); return {
uid: Util.uid(),
v: Messages._getKey('form_defaultOption', [i])
};
}) })
}, },
get: function (opts, a, n, evOnChange) { get: function (opts, a, n, evOnChange) {
@ -1981,7 +2081,10 @@ define([
}; };
}), }),
values: [1,2,3].map(function (i) { values: [1,2,3].map(function (i) {
return Messages._getKey('form_defaultOption', [i]); return {
uid: Util.uid(),
v: Messages._getKey('form_defaultOption', [i])
};
}) })
}, },
get: function (opts, a, n, evOnChange) { get: function (opts, a, n, evOnChange) {
@ -2153,7 +2256,10 @@ define([
compatible: ['radio', 'checkbox', 'sort'], compatible: ['radio', 'checkbox', 'sort'],
defaultOpts: { defaultOpts: {
values: [1,2].map(function (i) { values: [1,2].map(function (i) {
return Messages._getKey('form_defaultOption', [i]); return {
uid: Util.uid(),
v: Messages._getKey('form_defaultOption', [i])
};
}) })
}, },
get: function (opts, a, n, evOnChange) { get: function (opts, a, n, evOnChange) {
@ -2279,7 +2385,10 @@ define([
defaultOpts: { defaultOpts: {
type: 'text', // Text or Days or Time type: 'text', // Text or Days or Time
values: [1, 2, 3].map(function (i) { values: [1, 2, 3].map(function (i) {
return Messages._getKey('form_defaultOption', [i]); return {
uid: Util.uid(),
v: Messages._getKey('form_defaultOption', [i])
};
}) })
}, },
get: function (opts, answers, username, evOnChange) { get: function (opts, answers, username, evOnChange) {
@ -2804,12 +2913,6 @@ define([
Messages.form_anonAnswer = "All answers to this form are anonymous"; // XXX Messages.form_anonAnswer = "All answers to this form are anonymous"; // XXX
Messages.form_authAnswer = "You can't answer anonymously to this form"; // XXX Messages.form_authAnswer = "You can't answer anonymously to this form"; // XXX
var getSections = function (content) {
var uids = Object.keys(content.form).filter(function (uid) {
return content.form[uid].type === 'section';
});
return uids;
};
var getSectionFromQ = function (content, uid) { var getSectionFromQ = function (content, uid) {
var arr = content.order; var arr = content.order;
var idx = content.order.indexOf(uid); var idx = content.order.indexOf(uid);
@ -2939,7 +3042,7 @@ define([
]); ]);
} }
if (!APP.cantAnon) { if (!APP.cantAnon) {
var $anon = $(anonName).hide(); $anon = $(anonName).hide();
$anonBox.on('change', function () { $anonBox.on('change', function () {
if (Util.isChecked($anonBox)) { $anon.hide(); } if (Util.isChecked($anonBox)) { $anon.hide(); }
else { $anon.show(); } else { $anon.show(); }
@ -3279,7 +3382,7 @@ define([
var order = getFullOrder(content); var order = getFullOrder(content);
order.forEach(function (uid, blockIdx) { order.forEach(function (uid) {
var block = form[uid]; var block = form[uid];
var type = block.type; var type = block.type;
var model = TYPES[type] || STATIC_TYPES[type]; var model = TYPES[type] || STATIC_TYPES[type];
@ -3344,7 +3447,7 @@ define([
Messages.form_required_on = "required"; Messages.form_required_on = "required";
Messages.form_required_off = "optional"; Messages.form_required_off = "optional";
// Required radio displayed only for types that have an "isEmpty" function // Required radio displayed only for types that have an "isEmpty" function
var requiredDiv, conditionalDiv; var requiredDiv;
if (APP.isEditor && !isStatic && data.isEmpty) { if (APP.isEditor && !isStatic && data.isEmpty) {
if (!block.opts) { block.opts = TYPES[type].defaultOpts; } if (!block.opts) { block.opts = TYPES[type].defaultOpts; }
var isRequired = Boolean(block.opts.required); var isRequired = Boolean(block.opts.required);
@ -4104,7 +4207,7 @@ define([
}); });
var save = h('button.btn.btn-primary', Messages.settings_save); var save = h('button.btn.btn-primary', Messages.settings_save);
$(save).click(function () { $(save).click(function () {
if (dataPicker.value === '') { if (datePicker.value === '') {
return void refreshEndDate(); return void refreshEndDate();
} }
var d = picker.parseDate(datePicker.value); var d = picker.parseDate(datePicker.value);

Loading…
Cancel
Save