JSFiddle - React, Tailwind, and code Playground
by romanych
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-debug.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.js"></script>
<script type="text/html" id="questions-editor-tpl">
<div data-bind="foreach: questions">
<input type="text" data-bind="textInput: question" placeholder="Question text" />
<ul data-bind="foreach: options ">
<li>
<input type="text" data-bind="textInput: text" placeholder="Add new option" />
<button data-bind="click: $parent.removeOption, visible: $data.hideDelete ? $data.hideDelete() : true ">x</button>
</li>
</ul>
</div>
</div>
</script>
<div id="questions-editor ">
<div data-bind="template: {name: 'questions-editor-tpl'} ">
</div>
</div>
JavaScript
var questions = [{
"id": 1,
"anonymous": false,
"end_date": "2017-04-01",
"show_results_after_end": true,
"question": "Question 1",
"max_options": 1,
"options": [{
"id": 1,
"text": "Q1 O1"
}, {
"id": 2,
"text": "Q1 O2"
}]
}];
function getAvailableEndDates() {
var result = [];
var days = 31;
var d = moment();
for (var i = 1; i <= days; i++) {
d.add(1, 'days');
result.push({
date: d.format("YYYY-MM-DD"),
caption: d.format("LL")
})
};
return result;
}
function createNewOption() {
var newOption = {
"text": ko.observable(),
"new": true
};
newOption.hideDelete = ko.computed(function() {
return !!this.text();
}, newOption)
return newOption;
}
function QuestionViewModel(question) {
if (!question) {
question = {
question: "",
max_options: 1,
options: [],
anonymous: false,
end_date: null,
show_results_after_end: false
}
};
var isDefaultSettins = question.max_options === 1 && question.end_date === null && question.show_results_after_end === false;
ko.mapping.fromJS(question, {}, this);
var self = this;
self.showSettings = ko.observable(!isDefaultSettins);
self.toggleSettings = function() {
self.showSettings(!self.showSettings());
}
self.removeOption = function(option) {
self.options.remove(option);
}
self.availableMaxOptions = ko.computed(function() {
var count = self.options().filter(o => !!o.text()).length;
var result = [1];
for (var i = 2; i <= count; i++) {
result.push(i);
}
return result;
});
self.availableEndDates = getAvailableEndDates();
ko.computed(function() {
var needToAdd = true;
self.options().forEach(function(option) {
if (!option.text()) {
if (option.new) {
needToAdd = false;
}
}
})
if (needToAdd) {
setTimeout(function() {
self.options.push(createNewOption());
});
}
...