questionnaire/assets/js/components/editQuestion.js

652 lines
28 KiB
JavaScript
Vendored

import m from "mithril"
import moment from "moment"
import _ from "lodash"
import powerform from "powerform"
import { Card, Button, RaisedButton, TextField, RadioGroup, RadioButton, Checkbox, Dialog } from "polythene-mithril"
// import DatePicker from "../custom/mithril-datepicker"
import {} from "../../css/custom/mithril-datepicker.css"
import { nav } from "./nav"
import Question from "../models/Question"
var viewChoice = {
view: function(vnode) {
var data = vnode.attrs.data
return [
m(Card, {
style: {
width: "100%",
flexGrow: "1",
paddingTop: "1.5em"
},
content: [
{
text: {
content: [
m("i.fa.fa-times.fa-fw#remove" + data.id, {
style: {
position: "absolute",
top: "0",
right: "0",
cursor: "pointer"
}
}),
Question.current.questionType == "multichoice" ?
m(Checkbox, {
className: "choice-view",
label: data.text
})
: m(RadioButton, {
className: "choice-view",
label: data.text
}),
data.fillable ?
m(TextField, {
label: "Isikan jawaban anda",
required: true,
tight: true
})
: null
]
}
}
],
events: {
onclick: function(e) {
var parent = this.parentNode
if (e.target != document.querySelector("#remove" + data.id)) {
m.mount(parent, {
view: function() {
return m(editChoice, {data: data, parent: parent})
}
})
} else {
Dialog.show({
body: [
m(".pe-dialog-pane__title", "Hapus pilihan"),
m("div", "Pilihan ini akan dihapus setelah klik pada tombol 'Simpan'.")
],
footerButtons: [
m(Button, {
label: "Konfirmasi",
events: {
onclick: function() {
parent.removeChild(parent.childNodes[0])
Dialog.hide()
}
}
}),
m(Button, {
label: "Batal",
events: {
onclick: function() {
Dialog.hide()
}
}
})
],
backdrop: true
})
}
}
}
})
]
}
}
var Choices = {
data: [],
oninit: function(vnode) {
Choices.data = vnode.attrs.data
},
view: function() {
return [
m(Checkbox, {
label: "Dapat pilih lebih dari 1",
checked: Question.current.questionType == "multichoice" ?
true : false,
onChange: function(state) {
state.checked ?
Question.current.questionType = "multichoice"
: Question.current.questionType = "choice"
}
}),
_.isEmpty(Choices.data) ?
m(".flex#question-new", m(newChoice))
: [
Choices.data.map(function(choice) {
var id = ".flex"
return m(id, m(viewChoice, {data: choice}))
}),
m(Dialog),
m(plusButton)
]
]
}
}
var plusButton = {
view: function() {
return m(".flex#choice-new", m(Button, {
className: "flex",
label: [
m("i.fa.fa-plus.fa-fw"),
m.trust(" "),
"Tambah"
],
style: {
padding: ".8em",
fontSize: "14px",
lineHeight: "14px",
fontWeight: "500",
textTransform: "uppercase",
whiteSpace: "pre",
transition: ".2s all ease"
},
events: {
onmouseover: function() {
this.childNodes[0].style.backgroundColor = "rgba(255, 255, 255, .8)"
},
onmouseout: function() {
this.childNodes[0].style.backgroundColor = "#fff"
},
onclick: function() {
m.mount(document.getElementById("choice-new"), {
view: function() {
return m(newChoice)
}
})
}
}
}))
}
}
var editChoice = {
oncreate: function() {
var target = document.getElementsByClassName("choices")
for (var i = 0; i < target.length; i++) {
target[i].querySelector(".pe-card__content").style.width = "100%"
}
},
view: function(vnode) {
var data = vnode.attrs.data
return [
m("div", {
style: {
flexGrow: "1"
}
}), m(Card, {
className: "choices",
style: {
width: "100%",
flexGrow: "1"
},
content: [
{
text: {
content: [
m(".flex", m(TextField, {
label: "Teks",
required: true,
floatingLabel: true,
tight: true,
value: data.text,
events: {
oninput: m.withAttr("value", function(value) {
data.text = value
})
}
}), m("div", m.trust("&nbsp;")), m(Checkbox, {
style: {
marginTop: "2.5em",
flexBasis: "25%"
},
label: "Dapat diisi",
checked: data.fillable,
onChange: function(state) {
data.fillable = state.checked
}
})),
m(".flex", [
m(TextField, {
label: "Deskripsi",
floatingLabel: true,
tight: true,
value: data.description,
events: {
oninput: m.withAttr("value", function(value) {
data.description = value
})
}
})
]),
m("div", {
style: {
textAlign: "right"
}
}, [
m(RaisedButton, {
label: [
m("i.fa.fa-check.fa-fw"),
m.trust("&nbsp;"),
"Simpan"
],
tone: "dark",
style: {
padding: ".6em .8em",
fontSize: "14px",
lineHeight: "14px",
fontWeight: "500",
textTransform: "uppercase",
whiteSpace: "pre",
backgroundColor: "#009933"
},
events: {
onclick: function() {
m.mount(
vnode.attrs.parent,
{
view: function() {
return m(viewChoice, {data: data})
}
}
)
}
}
}),
m(RaisedButton, {
label: [
m("i.fa.fa-times.fa-fw"),
m.trust("&nbsp;"),
"Batal"
],
tone: "dark",
style: {
padding: ".6em .8em",
fontSize: "14px",
lineHeight: "14px",
fontWeight: "500",
textTransform: "uppercase",
whiteSpace: "pre",
backgroundColor: "#ff0000"
},
events: {
onclick: function() {
m.mount(
vnode.attrs.parent,
{
view: function() {
return m(viewChoice, {data: data})
}
}
)
}
}
})
])
]
}
}
]
}), m("div", {
style: {
flexGrow: "1"
}
})
]
}
}
var newChoice = {
data: {},
oninit: function() {
newChoice.data = {}
},
oncreate: function() {
var target = document.getElementsByClassName("choices")
for (var i = 0; i < target.length; i++) {
target[i].querySelector(".pe-card__content").style.width = "100%"
}
},
view: function() {
return [
m("div", {
style: {
flexGrow: "1"
}
}), m(Card, {
className: "choices",
style: {
width: "100%",
flexGrow: "1"
},
content: [
{
text: {
content: [
m(".flex", m(TextField, {
label: "Teks",
required: true,
floatingLabel: true,
tight: true,
value: newChoice.data.text,
events: {
oninput: m.withAttr("value", function(value) {
newChoice.data.text = value
})
}
}), m("div", m.trust("&nbsp;")), m(Checkbox, {
style: {
marginTop: "2.5em",
flexBasis: "25%"
},
label: "Dapat diisi",
checked: newChoice.data.fillable,
onChange: function(state) {
newChoice.data.fillable = state.checked
}
})),
m(".flex", [
m(TextField, {
label: "Deskripsi",
floatingLabel: true,
tight: true,
value: newChoice.data.description,
events: {
oninput: m.withAttr("value", function(value) {
newChoice.data.description = value
})
}
})
]),
m("div", {
style: {
textAlign: "right"
}
}, [
m(RaisedButton, {
label: [
m("i.fa.fa-plus.fa-fw"),
m.trust("&nbsp;"),
"Tambah"
],
tone: "dark",
style: {
padding: ".6em .8em",
fontSize: "14px",
lineHeight: "14px",
fontWeight: "500",
textTransform: "uppercase",
whiteSpace: "pre",
backgroundColor: "#009933"
},
events: {
onclick: function() {
Choices.data.push(newChoice.data)
m.mount(
document.getElementById("choice-new"),
{
view: function() {
return m(newChoice)
}
}
)
}
}
}),
m(RaisedButton, {
label: [
m("i.fa.fa-times.fa-fw"),
m.trust("&nbsp;"),
"Batal"
],
tone: "dark",
style: {
padding: ".6em .8em",
fontSize: "14px",
lineHeight: "14px",
fontWeight: "500",
textTransform: "uppercase",
whiteSpace: "pre",
backgroundColor: "#ff0000"
},
events: {
onclick: function() {
m.mount(
document.getElementById("choice-new"),
{
view: function() {
return m(plusButton)
}
}
)
}
}
})
])
]
}
}
]
}), m("div", {
style: {
flexGrow: "1"
}
})
]
}
}
var qsCard = {
form: powerform({
text: function(v) {
if (!v || v == "" || _.isNil(v) || _.isEmpty(v)) {
return "Kolom ini harus diisi"
}
},
length: function(v) {
if (!_.isNil(v) || !_.isEmpty(v)) {
if (/^\d+$/.test(v) == false) {
return "Kolom ini diisi dengan angka"
}
}
},
type: function(v) {
if (!v || v == "" || _.isNil(v) || _.isEmpty(v)) {
return "Kolom ini harus diisi"
}
},
// fill: function(v) {},
// choices: function(v) {},
}),
oncreate: function() {
qsCard.form.text(Question.current.text)
qsCard.form.length(Question.current.expectedLength)
qsCard.form.type(Question.current.questionType)
},
view: function() {
return m("form", {
onsubmit: function(e) {
e.preventDefault()
console.log(qsCard.form.isValid(), qsCard.form.error());
},
style: {
flexGrow: "1",
display: "flex"
}
}, m(Card, {
style: {
flexGrow: "1",
marginBottom: "14vh",
// marginTop: "11vh"
},
content: [
{
text: {
className: "edit-body",
content: [
m(TextField, {
label: "Judul",
floatingLabel: true,
tight: true,
value: Question.current.text,
events: {
oninput: m.withAttr("value", function(v) {
Question.current.text = v
qsCard.form.text(v)
})
},
validate: function() {
return {
valid: qsCard.form.text.isValid(),
error: qsCard.form.text.error()
}
}
}),
m(TextField, {
label: "Deskripsi",
floatingLabel: true,
tight: true,
value: Question.current.description,
events: {
oninput: m.withAttr("value", function(v) {
Question.current.description = v
})
},
}),
m(TextField, {
label: "Minimal Karakter",
floatingLabel: true,
tight: true,
// type: "number",
value: Question.current.expectedLength,
events: {
oninput: m.withAttr("value", function(v) {
Question.current.expectedLength = v
qsCard.form.length(v)
})
},
validate: function(v) {
if (_.isNil(v) || _.isEmpty(v)) {
qsCard.form.length.isValid(true)
} else {
return {
valid: qsCard.form.length.isValid(),
error: qsCard.form.length.error()
}
}
}
}),
m("div", {
style: {
color: "rgba(0, 0, 0, .4)",
fontSize: "small",
fontWeight: "400",
lineHeight: "24px",
marginBottom: ".5em"
}
}, "Tipe *"),
m(RadioGroup, {
name: "type",
buttons: [
{
label: "Teks",
value: "text",
defaultChecked: Question.current.questionType == "text"
},
{
label: "Pilihan",
value: "choice",
defaultChecked: Question.current.questionType == "choice"
|| Question.current.questionType == "multichoice"
},
{
label: "Angka",
value: "numeric",
defaultChecked: Question.current.questionType == "numeric"
},
{
label: "Benar/Salah",
value: "bool",
defaultChecked: Question.current.questionType == "bool"
}
],
onChange: function(state) {
Question.current.questionType = state.value
qsCard.form.type(state.value)
}
}),
Question.current.questionType == "choice"
|| Question.current.questionType == "multichoice" ?
[
m(Choices, {data: Question.current.choices})
]
: null
]
}
},
{
actions: {
bordered: true,
content: [
m(RaisedButton, {
element: "button",
label: [
m("i.fa.fa-floppy-o.fa-fw"),
m.trust("&nbsp;"),
"Simpan"
],
style: {
padding: ".6em .8em",
fontSize: "14px",
lineHeight: "14px",
fontWeight: "500",
textTransform: "uppercase",
whiteSpace: "pre",
backgroundColor: "#00cc00"
},
tone: "dark"
}),
m(".flex"),
m(RaisedButton, {
label: [
m("i.fa.fa-times.fa-fw"),
m.trust("&nbsp;"),
"Hapus"
],
style: {
padding: ".6em .8em",
fontSize: "14px",
lineHeight: "14px",
fontWeight: "500",
textTransform: "uppercase",
whiteSpace: "pre",
backgroundColor: "#ff0000"
},
tone: "dark"
})
]
}
}
]
}))
}
}
export const editQuestion = {
oninit: function(vnode) {
Question.current = {id: vnode.attrs.id}
Question.fetchCurrent()
},
view: function() {
return [
m(nav, {
title: "Ubah - " + Question.current.text,
back: "/user/questions/" + Question.current.id
}),
m(".flex", m(qsCard))
]
}
}