mirror of https://github.com/xwiki-labs/cryptpad
Merge branch 'form-date-condorcet' into 5.3-rc
This commit is contained in:
commit
b1af6da17c
|
@ -679,6 +679,12 @@
|
|||
line-height: 31px;
|
||||
}
|
||||
}
|
||||
.cp-form-result-details {
|
||||
margin: 10px 0px;
|
||||
&> * {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
||||
&.editable {
|
||||
&:not(.nodrag) { cursor: grab; }
|
||||
.cp-form-edit-save {
|
||||
|
@ -1276,6 +1282,17 @@
|
|||
.cp-form-setting-title {
|
||||
color: @cryptpad_color_link;
|
||||
}
|
||||
.cp-form-status-container {
|
||||
.cp-form-input-block {
|
||||
display: flex;
|
||||
.flatpickr-input { // expiration date picker
|
||||
margin: 0 10px 0 0;
|
||||
}
|
||||
& > * {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
& > .flatpickr-calendar {
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
|
||||
define([], function () {
|
||||
var Condorcet = {};
|
||||
|
||||
// Creates every possible combination pair of given options
|
||||
var getPermutations = function(array, size) {
|
||||
|
||||
var result = [];
|
||||
|
||||
var generatePermutations = function (t, i) {
|
||||
if (t.length === size) {
|
||||
result.push(t);
|
||||
result.push(t.slice().reverse());
|
||||
return;
|
||||
}
|
||||
if (i >= array.length) {
|
||||
return;
|
||||
}
|
||||
generatePermutations(t.concat(array[i]), i + 1);
|
||||
generatePermutations(t, i + 1);
|
||||
};
|
||||
|
||||
generatePermutations([], 0);
|
||||
return result;
|
||||
};
|
||||
|
||||
Condorcet.showCondorcetWinner = function (method, optionArray, listOfLists) {
|
||||
|
||||
var comparePairs = function () {
|
||||
var pairs = getPermutations(optionArray, 2);
|
||||
var pairDict = {};
|
||||
pairs.forEach(function (pair) {
|
||||
pairDict[pair] = 0;
|
||||
listOfLists.forEach(function(optionList) {
|
||||
var idx1 = optionList.indexOf(pair[0]);
|
||||
var idx2 = optionList.indexOf(pair[1]);
|
||||
// Put missing options as last in the array
|
||||
if (idx1 === -1) { idx1 = Infinity; }
|
||||
if (idx2 === -1) { idx2 = Infinity; }
|
||||
if (idx1 < idx2) { pairDict[pair] ++; }
|
||||
});
|
||||
});
|
||||
|
||||
var pathDictionary = {};
|
||||
//Adds winner of each pairwise comparison to path
|
||||
pairs.forEach(function (pair) {
|
||||
var key1 = [pair[0], pair[1]].join();
|
||||
var key2 = [pair[1], pair[0]].join();
|
||||
if (pairDict[key1] > pairDict[key2]) {
|
||||
pathDictionary[key1] = pairDict[key1] - pairDict[key2];
|
||||
} else if (pairDict[key2] > pairDict[key1]) {
|
||||
pathDictionary[key2] = pairDict[key2] - pairDict[key1];
|
||||
}
|
||||
});
|
||||
return pathDictionary;
|
||||
};
|
||||
|
||||
var schulzeMethod = function(optionArray) {
|
||||
|
||||
var findWeakestPath = function(optionArray) {
|
||||
|
||||
var pathDictionary = comparePairs(optionArray);
|
||||
|
||||
//Iterates through paths between two options comparing the weakest edge to current score
|
||||
optionArray.forEach(function(option1) {
|
||||
optionArray.forEach(function(option2) {
|
||||
if (option1 === option2) {
|
||||
return;
|
||||
} else {
|
||||
optionArray.forEach(function(option3){
|
||||
if (option1 === option3 || option2 === option3) {
|
||||
return;
|
||||
} else {
|
||||
var key1 = [option2, option3].join();
|
||||
var key2 = [option2, option1].join();
|
||||
var key3 = [option1, option3].join();
|
||||
var score;
|
||||
if (!pathDictionary[key1]) {
|
||||
score = 0;
|
||||
} else {
|
||||
score = pathDictionary[key1];
|
||||
}
|
||||
var path1;
|
||||
if (pathDictionary[key2]) {
|
||||
path1 = pathDictionary[key2];
|
||||
} else {
|
||||
path1 = 0;
|
||||
}
|
||||
var path2;
|
||||
if (pathDictionary[key3]) {
|
||||
path2 = pathDictionary[key3];
|
||||
} else {
|
||||
path2 = 0;
|
||||
}
|
||||
var weakestPath = Math.min(path1, path2);
|
||||
if (weakestPath > score) {
|
||||
pathDictionary[key1] = weakestPath;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return pathDictionary;
|
||||
};
|
||||
|
||||
var calculateWinner = function() {
|
||||
|
||||
var pathDictionary = findWeakestPath(optionArray);
|
||||
|
||||
//Calculate scores for each option and select winner
|
||||
var winningMatches = {};
|
||||
optionArray.forEach(function(option){
|
||||
winningMatches[option] = 0;
|
||||
});
|
||||
Object.keys(pathDictionary).forEach(function(pair) {
|
||||
var option1 = pair.split(',')[0];
|
||||
var option2 = pair.split(',')[1];
|
||||
winningMatches[option1] ++;
|
||||
winningMatches[option2] --;
|
||||
|
||||
Object.keys(pathDictionary).forEach(function(p) {
|
||||
if (p.split(',')[1] === option1 && pathDictionary[p] > pathDictionary[pair]) {
|
||||
winningMatches[option1] --;
|
||||
}
|
||||
});
|
||||
});
|
||||
var rankedResults = {};
|
||||
Object.keys(winningMatches).forEach(function(option) {
|
||||
if (rankedResults[winningMatches[option]]) {
|
||||
rankedResults[winningMatches[option]].push(option);
|
||||
} else {
|
||||
rankedResults[winningMatches[option]] = [option];
|
||||
}
|
||||
});
|
||||
|
||||
var losing = [];
|
||||
var winning = [];
|
||||
var winningPairs = [];
|
||||
Object.keys(pathDictionary).forEach(function(pair) {
|
||||
var option1 = pair.split(',')[0];
|
||||
var option2 = pair.split(',')[1];
|
||||
|
||||
losing.push(option2);
|
||||
winning.push(option1);
|
||||
|
||||
});
|
||||
Object.keys(pathDictionary).forEach(function(pair) {
|
||||
var option1 = pair.split(',')[0];
|
||||
if (!losing.includes(option1)) {
|
||||
winningPairs.push(option1);
|
||||
}
|
||||
});
|
||||
|
||||
var winner;
|
||||
var winnersArray = [];
|
||||
|
||||
winningPairs.forEach(function(pair) {
|
||||
if (!winnersArray.includes(pair)) {
|
||||
winnersArray.push(pair);
|
||||
}
|
||||
});
|
||||
|
||||
var sortedRankedResults = [];
|
||||
Object.keys(rankedResults).map(Number).sort(function(a, b){return a - b;}).forEach(function(score) {
|
||||
sortedRankedResults.push([score, rankedResults[score]]);
|
||||
});
|
||||
|
||||
|
||||
if (winnersArray.length !== 0) {
|
||||
winner = winnersArray;
|
||||
} else if (winnersArray.length === 0 && Object.keys(rankedResults).length === 1) {
|
||||
winner = [];
|
||||
} else {
|
||||
var maxScore = Math.max.apply(null, Object.keys(rankedResults));
|
||||
winner = rankedResults[maxScore];
|
||||
}
|
||||
return [winner, sortedRankedResults];
|
||||
};
|
||||
return(calculateWinner());
|
||||
};
|
||||
|
||||
var rankedPairsMethod = function (optionArray) {
|
||||
|
||||
//'Locks' pairwise comparisons which do not create a beatpath cycle
|
||||
var pathDictionary = comparePairs();
|
||||
|
||||
var items = Object.keys(pathDictionary).map(function(key) {
|
||||
return [key, pathDictionary[key]];
|
||||
});
|
||||
var itemsDict = {};
|
||||
Object.values(items).forEach(function(value) {
|
||||
if (itemsDict[value[1]]) {
|
||||
itemsDict[value[1]].push(value[0]);
|
||||
} else {
|
||||
itemsDict[value[1]] = [];
|
||||
itemsDict[value[1]].push(value[0]);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var sortedArray = [];
|
||||
Object.keys(itemsDict).map(Number).sort(function(a, b){return a - b;}).forEach(function(score) {
|
||||
sortedArray.push([score, itemsDict[score]]);
|
||||
});
|
||||
|
||||
var rankingDict = {};
|
||||
var winning = [];
|
||||
var losing = [];
|
||||
sortedArray.forEach(function(arr) {
|
||||
arr[1].forEach(function(pair) {
|
||||
winning.push(pair.split(',')[0]);
|
||||
losing.push(pair.split(',')[1]);
|
||||
});
|
||||
});
|
||||
optionArray.forEach(function(option){
|
||||
rankingDict[option] = 0;
|
||||
});
|
||||
|
||||
var rankingArray = [];
|
||||
Object.values(rankingDict).forEach(function(pair) {
|
||||
if (!rankingArray .includes(pair)) {
|
||||
rankingArray .push(pair);
|
||||
}
|
||||
});
|
||||
|
||||
if (rankingArray.length <= 1) {
|
||||
optionArray.forEach(function(option){
|
||||
if (winning.includes(option)) {
|
||||
rankingDict[option] ++;
|
||||
}
|
||||
if (losing.includes(option)) {
|
||||
rankingDict[option] --;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var rankedResults = {};
|
||||
Object.keys(rankingDict).forEach(function(option) {
|
||||
if (rankedResults[rankingDict[option]]) {
|
||||
rankedResults[rankingDict[option]].push(option);
|
||||
} else {
|
||||
rankedResults[rankingDict[option]] = [option];
|
||||
}
|
||||
});
|
||||
|
||||
var rankedKeys = Object.keys(rankedResults).map(function(key) {
|
||||
return [key, rankedResults[key]];
|
||||
});
|
||||
|
||||
var finalsortedItems = {};
|
||||
Object.values(rankedKeys).forEach(function(value){
|
||||
if (finalsortedItems[value[1]]) {
|
||||
finalsortedItems[value[1]].push(value[0]);
|
||||
} else {
|
||||
finalsortedItems[value[1]] = [value[0]];
|
||||
}
|
||||
});
|
||||
|
||||
var finalRankingArray = [];
|
||||
Object.values(rankingDict).forEach(function(pair) {
|
||||
if (!finalRankingArray.includes(pair)) {
|
||||
finalRankingArray.push(pair);
|
||||
}
|
||||
});
|
||||
|
||||
var winner;
|
||||
if (finalRankingArray.length > 1) {
|
||||
var maxScore = Math.max.apply(null, Object.keys(rankedResults));
|
||||
winner = rankedResults[maxScore];
|
||||
} else if (sortedArray.length === 0) {
|
||||
winner = [];
|
||||
} else {
|
||||
var topScoring = sortedArray.slice(-1);
|
||||
topScoring.forEach(function(pair) {
|
||||
pair[1].forEach(function(p) {
|
||||
var index = winning.indexOf(p.split(',')[1]);
|
||||
winning.splice(index, 1);
|
||||
});
|
||||
});
|
||||
|
||||
var winnerArray = [];
|
||||
winning.forEach(function(option){
|
||||
if (!winnerArray.includes(option)) {
|
||||
winnerArray.push(option);
|
||||
}
|
||||
});
|
||||
|
||||
if (winnerArray.length === optionArray.length) {
|
||||
winner = [];
|
||||
} else {
|
||||
winner = winnerArray;
|
||||
}
|
||||
}
|
||||
|
||||
var sortedRankedResults = [];
|
||||
Object.keys(rankedResults).map(Number).sort(function(a, b){return a - b;}).forEach(function(score) {
|
||||
sortedRankedResults.push([score, rankedResults[score]]);
|
||||
});
|
||||
return [winner, sortedRankedResults];
|
||||
|
||||
};
|
||||
|
||||
var pickMethod = function (optionArray){
|
||||
if (method === "schulze") {
|
||||
return schulzeMethod(optionArray);
|
||||
} else if (method === "ranked") {
|
||||
return rankedPairsMethod(optionArray);
|
||||
}
|
||||
};
|
||||
return pickMethod(optionArray);
|
||||
};
|
||||
|
||||
return Condorcet;
|
||||
});
|
|
@ -6,6 +6,7 @@ define([
|
|||
'/common/sframe-app-framework.js',
|
||||
'/common/toolbar.js',
|
||||
'/form/export.js',
|
||||
'/form/condorcet.js',
|
||||
'/bower_components/nthen/index.js',
|
||||
'/common/sframe-common.js',
|
||||
'/common/common-util.js',
|
||||
|
@ -52,6 +53,7 @@ define([
|
|||
Framework,
|
||||
Toolbar,
|
||||
Exporter,
|
||||
Condorcet,
|
||||
nThen,
|
||||
SFCommon,
|
||||
Util,
|
||||
|
@ -73,6 +75,7 @@ define([
|
|||
Sortable
|
||||
)
|
||||
{
|
||||
|
||||
var APP = window.APP = {
|
||||
blocks: {}
|
||||
};
|
||||
|
@ -140,7 +143,6 @@ define([
|
|||
evOnSave.fire();
|
||||
}, 500));
|
||||
}
|
||||
|
||||
var type, typeSelect;
|
||||
if (opts.type) {
|
||||
// Messages.form_text_text.form_text_number.form_text_url.form_text_email
|
||||
|
@ -201,6 +203,15 @@ define([
|
|||
saveAndCancel
|
||||
];
|
||||
};
|
||||
|
||||
var editDateOptions = function (cb) {
|
||||
var saveAndCancel = saveAndCancelOptions(cb);
|
||||
|
||||
return [
|
||||
saveAndCancel
|
||||
];
|
||||
};
|
||||
|
||||
var editOptions = function (v, isDefaultOpts, setCursorGetter, cb, tmp) {
|
||||
var evOnSave = Util.mkEvent();
|
||||
|
||||
|
@ -650,7 +661,6 @@ define([
|
|||
if (typeSelect) {
|
||||
res.type = typeSelect.getValue();
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
|
@ -2013,6 +2023,75 @@ define([
|
|||
},
|
||||
icon: h('i.cptools.cptools-form-grid-radio')
|
||||
},
|
||||
date: {
|
||||
defaultOpts: {
|
||||
type: 'date',
|
||||
},
|
||||
get: function (opts, a, n, evOnChange) {
|
||||
opts = Util.clone(TYPES.date.defaultOpts);
|
||||
|
||||
var tag = h('input');
|
||||
|
||||
Flatpickr(tag, {
|
||||
enableTime: true,
|
||||
time_24hr: is24h,
|
||||
dateFormat: dateFormat,
|
||||
});
|
||||
|
||||
var $tag = $(tag);
|
||||
$tag.on('change keypress', Util.throttle(function () {
|
||||
evOnChange.fire();
|
||||
}, 500));
|
||||
|
||||
|
||||
return {
|
||||
tag: tag,
|
||||
isEmpty: function () { return !$tag.val().trim(); },
|
||||
getValue: function () {
|
||||
var invalid = $tag.is(':invalid');
|
||||
if (invalid) { return; }
|
||||
return $tag.val();
|
||||
|
||||
},
|
||||
setValue: function (val) { $tag.val(val); },
|
||||
setEditable: function (state) {
|
||||
if (state) { $tag.removeAttr('disabled'); }
|
||||
else { $tag.attr('disabled', 'disabled'); }
|
||||
},
|
||||
edit: function (cb) {
|
||||
|
||||
return editDateOptions(cb);
|
||||
},
|
||||
reset: function () { $tag.val(''); }
|
||||
};
|
||||
},
|
||||
printResults: function (answers, uid) { // results text
|
||||
var results = [];
|
||||
var empty = 0;
|
||||
var tally = {};
|
||||
|
||||
var isEmpty = function (answer) {
|
||||
return !answer || !answer.trim();
|
||||
};
|
||||
|
||||
Object.keys(answers).forEach(function (author) {
|
||||
var obj = answers[author];
|
||||
var answer = obj.msg[uid];
|
||||
if (isEmpty(answer)) { return empty++; }
|
||||
Util.inc(tally, answer);
|
||||
});
|
||||
|
||||
//if (max < 2) { // there are no duplicates, so just return text
|
||||
results.push(getEmpty(empty));
|
||||
Object.keys(answers).forEach(function (author) {
|
||||
var obj = answers[author];
|
||||
var answer = obj.msg[uid];
|
||||
if (!answer || !answer.trim()) { return empty++; }
|
||||
results.push(h('div.cp-charts-row', h('span.cp-value', answer)));
|
||||
});
|
||||
return h('div.cp-form-results-contained', h('div.cp-charts.cp-text-table', results));
|
||||
},
|
||||
icon: h('i.cp-calendar-active.fa.fa-calendar')},
|
||||
checkbox: {
|
||||
compatible: ['radio', 'checkbox', 'sort'],
|
||||
defaultOpts: {
|
||||
|
@ -2420,7 +2499,8 @@ define([
|
|||
});
|
||||
sortNode(toSort);
|
||||
reorder();
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
},
|
||||
|
@ -2442,7 +2522,6 @@ define([
|
|||
Util.inc(count, el, score);
|
||||
});
|
||||
});
|
||||
|
||||
var rendered = renderTally(count, empty, showBars);
|
||||
return h('div.cp-charts.cp-bar-table', rendered);
|
||||
},
|
||||
|
@ -2786,7 +2865,9 @@ define([
|
|||
var switchMode = h('button.btn.btn-secondary', Messages.form_showIndividual);
|
||||
$controls.hide().append(switchMode);
|
||||
|
||||
|
||||
var show = function (answers, header) {
|
||||
|
||||
var order = getFullOrder(content);
|
||||
var elements = order.map(function (uid) {
|
||||
var block = form[uid];
|
||||
|
@ -2801,8 +2882,136 @@ define([
|
|||
answers: answers
|
||||
});
|
||||
|
||||
var q = h('div.cp-form-block-question', block.q || Messages.form_default);
|
||||
|
||||
var showCondorcetWinner = function(answers, opts, condorcetMethod, uid) {
|
||||
|
||||
var _answers = parseAnswers(answers);
|
||||
|
||||
var optionArray = [];
|
||||
opts.values.forEach(function (option) {
|
||||
optionArray.push(option.v);
|
||||
});
|
||||
|
||||
var listOfLists = [];
|
||||
Object.keys(_answers).forEach(function(a) {
|
||||
if (_answers[a].msg[uid]) {
|
||||
listOfLists.push(_answers[a].msg[uid]);
|
||||
}
|
||||
});
|
||||
try {
|
||||
if (listOfLists.length) {
|
||||
return Condorcet.showCondorcetWinner(condorcetMethod, optionArray, listOfLists);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
var condorcetWinnerDiv = h('div.cp-form-block-content');
|
||||
var condorcetMethod = 'schulze';
|
||||
try {
|
||||
if (type === "sort" && summary) {
|
||||
var calculateCondorcet = function() {
|
||||
var condorcetResults = h('span');
|
||||
var c = showCondorcetWinner(answers, block.opts, condorcetMethod, uid);
|
||||
if (!c) { return; }
|
||||
var condorcetWinner = c[0];
|
||||
var rankedResults = c[1];
|
||||
if (!condorcetWinner || !condorcetResults) { return; }
|
||||
if (condorcetWinner.length > 1) {
|
||||
condorcetResults.append(h('span', condorcetWinner.join(', ')));
|
||||
} else if (condorcetWinner.length === 1 ) {
|
||||
condorcetResults.append(h('span', condorcetWinner));
|
||||
} else {
|
||||
condorcetResults.append(h('span', Messages.form_noCondorcetWinner));
|
||||
}
|
||||
var detailedResults = rankedResults.reverse().map(function(result) {
|
||||
if (result.length > 1) {
|
||||
return result[1].join(', ') + ' : ' + result[0];
|
||||
} else {
|
||||
return result[1] + ' : ' + result[0];
|
||||
}
|
||||
});
|
||||
return [condorcetResults, detailedResults];
|
||||
};
|
||||
|
||||
var dropdownOpts = [{
|
||||
key: 'schulze',
|
||||
str: Messages.form_condorcetSchulze
|
||||
}, {
|
||||
key: 'ranked',
|
||||
str: Messages.form_condorcetRanked
|
||||
}];
|
||||
|
||||
var options = dropdownOpts.map(function (t) {
|
||||
return {
|
||||
tag: 'a',
|
||||
attributes: {
|
||||
'class': 'cp-form-type-value',
|
||||
'data-value': t.key,
|
||||
'href': '#',
|
||||
},
|
||||
content: t.str
|
||||
};
|
||||
});
|
||||
var dropdownConfig = {
|
||||
text: '', // Button initial text
|
||||
options: options,
|
||||
isSelect: true,
|
||||
caretDown: true,
|
||||
buttonCls: 'btn btn-secondary'
|
||||
};
|
||||
var typeSelect = UIElements.createDropdown(dropdownConfig);
|
||||
typeSelect.setValue(condorcetMethod);
|
||||
var evOnChange = Util.mkEvent();
|
||||
typeSelect.onChange.reg(evOnChange.fire);
|
||||
|
||||
var method = h('div.cp-dropdown-container', typeSelect[0]);
|
||||
|
||||
condorcetWinnerDiv = h('div.cp-form-edit-type');
|
||||
var detailsContainer, condorcetWinner;
|
||||
|
||||
var condorcetResult = calculateCondorcet();
|
||||
if (condorcetResult) {
|
||||
condorcetWinner = h('span#cp-condorcet-winner', condorcetResult[0]);
|
||||
detailsContainer = h('details#cp-condorcet-details', [
|
||||
h('summary', Messages.form_showDetails),
|
||||
Messages.form_condorcetExtendedDisplay,
|
||||
h('div', condorcetResult[1].join(', '))
|
||||
]);
|
||||
}
|
||||
|
||||
evOnChange.reg(function () {
|
||||
$('#cp-condorcet-winner').empty();
|
||||
$('#cp-condorcet-details').empty();
|
||||
condorcetMethod = typeSelect.getValue();
|
||||
var condorcetResult = calculateCondorcet();
|
||||
if (!condorcetResult || !condorcetResult[0] || !condorcetResult[1]) {
|
||||
return;
|
||||
}
|
||||
$('#cp-condorcet-winner').replaceWith(h('span#cp-condorcet-winner', condorcetResult[0]));
|
||||
$('#cp-condorcet-details').replaceWith(h('details#cp-condorcet-details', [
|
||||
h('summary', Messages.form_showDetails),
|
||||
Messages.form_condorcetExtendedDisplay,
|
||||
h('div', condorcetResult[1].join(', '))
|
||||
]));
|
||||
});
|
||||
|
||||
condorcetWinnerDiv.append(h('div.cp-form-result-details', [
|
||||
h('span', Messages.form_showCondorcetMethod),
|
||||
method,
|
||||
h('span', Messages.form_showCondorcetWinner, condorcetWinner),
|
||||
detailsContainer
|
||||
]));
|
||||
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
|
||||
var q = h('div.cp-form-block-question', block.q || Messages.form_default);
|
||||
//Messages.form_type_checkbox.form_type_input.form_type_md.form_type_multicheck.form_type_multiradio.form_type_poll.form_type_radio.form_type_sort.form_type_textarea.form_type_section
|
||||
return h('div.cp-form-block', [
|
||||
h('div.cp-form-block-type', [
|
||||
|
@ -2811,6 +3020,7 @@ define([
|
|||
]),
|
||||
q,
|
||||
h('div.cp-form-block-content', print),
|
||||
condorcetWinnerDiv,
|
||||
]);
|
||||
});
|
||||
$results.empty().append(elements);
|
||||
|
@ -2818,6 +3028,7 @@ define([
|
|||
};
|
||||
show(answers);
|
||||
|
||||
|
||||
if (APP.isEditor || APP.isAuditor) { $controls.show(); }
|
||||
|
||||
var $s = $(switchMode).click(function () {
|
||||
|
@ -3463,7 +3674,6 @@ define([
|
|||
if (!data.isEmpty) { return; }
|
||||
if (!block) { return; }
|
||||
if (!block.opts || !block.opts.required) { return; }
|
||||
|
||||
// Don't require questions that are in a hidden section
|
||||
var section = getSectionFromQ(content, uid);
|
||||
if (section.uid) {
|
||||
|
@ -3698,6 +3908,7 @@ define([
|
|||
uid: uid,
|
||||
tmp: temp && temp[uid]
|
||||
});
|
||||
|
||||
if (!data) { return; }
|
||||
data.uid = uid;
|
||||
if (answers && answers[uid] && data.setValue) { data.setValue(answers[uid]); }
|
||||
|
@ -3767,6 +3978,7 @@ define([
|
|||
data.editing = true;
|
||||
}
|
||||
|
||||
|
||||
var changeType;
|
||||
if (editable) {
|
||||
// Drag handle
|
||||
|
@ -3846,6 +4058,7 @@ define([
|
|||
h('span', Messages['form_type_'+type])
|
||||
]);
|
||||
|
||||
|
||||
// Values
|
||||
if (data.edit) {
|
||||
var edit = h('button.btn.btn-default.cp-form-edit-button', [
|
||||
|
@ -4597,7 +4810,6 @@ define([
|
|||
refreshEndDate();
|
||||
});
|
||||
var confirmContent = h('div', [
|
||||
h('div', Messages.form_setEnd),
|
||||
h('div.cp-form-input-block', [datePicker, save, cancel]),
|
||||
]);
|
||||
$button.after(confirmContent);
|
||||
|
|
Loading…
Reference in New Issue