{extend name="common/common2" /} {block name="main"} <style> .main-content{ background-color: #f0f0f0; } .page-content{ padding: 0; background-color: #f0f0f0; } .page-content2{ padding: 8px 20px 24px; position: relative; } .box-left{ width: 200px; position: fixed; z-index: 10; top: 100px; left: 210px; bottom: 40px; border: 1px solid #000; } .question-box{ width: 800px; margin:0 auto; background-color: #ffffff; margin-top: 10px; padding: 55px 35px; box-shadow: #bbbbbb; min-height: 800px; overflow: hidden; } .question-box-title,.question-box-desc,.question-box-btn{ padding: 10px 0; overflow: hidden; } .question-box-desc{ text-indent:30px; } .question-box-info{ padding: 15px 0; overflow: hidden; cursor: pointer; } .border-line{ border-top: 1px solid #cccccc; border-bottom: 1px solid #cccccc; } .question-form{ height: 34px; line-height: 34px; margin: 5px 0; overflow: hidden; } .question-form-option{ height: auto; margin: 5px 0; overflow: hidden; } .question-form-title{ display: inline-block; width: 30px; height: 100%; } .question-form-input{ display: inline-block; width: 690px; height: 100%; } .question-options{ width: 640px; height: 32px; color: #606266!important; font-size: 13px!important; padding: 5px 15px!important; border-width: 1px; border-style: solid; border-color: rgb(229, 230, 231); } .xz:focus,.form-select:focus,.question-options:focus{ border-color: #284a94 !important; outline:0; } ul, ol { margin: 0; } .form-select{ height: 32px; color: #606266!important; font-size: 13px!important; padding: 5px 15px!important; box-shadow:none; border-width: 1px; border-style: solid; border-color: rgb(229, 230, 231); } .xz{ width: 60px; line-height: 1.2px; padding: 5px 4px; border-width: 1px; border-style: solid; border-color: rgb(229, 230, 231); } .lb{ width: 100px !important; } </style> <div class="row"> <div class="col-sm-12"> <div class="ibox float-e-margins"> <div class="ibox-content"> <div class="page-content2" id="vueapp"> <div class="question-box"> <div class="question-box-title"> <h3 v-if="editother !== 1" class="text-center" @click="editOthers(1)">{{title}}</h3> <input v-if="editother === 1" type="text" v-model="title" class="form-control" placeholder="请输入标题"> </div> <div class="question-box-desc"> <div v-if="editother !== 2" @click="editOthers(2)">{{description}}</div> <textarea v-if="editother === 2" v-model="description" class="form-control" rows="3" placeholder="请输入描述"></textarea> </div> <draggable :list="question" :move="getdata2" @update="datadragEnd2" :options="{animation: 100,handle:'.dargDiv2'}"> <transition-group name="list-complete" > <div v-for="(item,index) in question" :key="index" class="question-box-list"> <div v-if="edit !== item.id" class="question-box-info dargDiv2"> <div @click="editQuestion(item)"> <div>{{index + 1}}、{{item.title}} <span v-if="item.required" class="text-danger">*</span></div> <div>{{item.remark}}</div> <div v-if="item.type === 'radio'||item.type === 'checkbox'" style="padding: 20px;"> <div v-for="(oitem,oindex) in item.options" :key="oindex"> <label><input :type="item.type" disabled>{{oitem.text}}</label> </div> </div> <div v-if="item.type === 'text'" style="padding: 10px 20px;"> <input type="text" style="width: 100%" readonly> </div> <div v-if="item.type === 'textarea'" style="padding: 10px 20px;"> <textarea rows="3" style="width: 100%" readonly></textarea> </div> <div v-if="item.type === 'star'" style="padding: 10px 20px;"> <span>{{item.star_min_text}}</span> <label v-for="n in item.star_val_max" :key="n"><input type="radio" disabled>{{n}} </label> <span>{{item.star_max_text}}</span> </div> </div> </div> <div v-if="edit === item.id" class="question-box-info border-line"> <div class="question-form"> <div class="question-form-title">题目</div> <div class="question-form-input"> <input type="text" v-model="item.title" class="form-control"> </div> </div> <div class="question-form"> <div class="question-form-title">备注</div> <div class="question-form-input"> <input type="text" v-model="item.remark" class="form-control"> </div> </div> <div class="question-form"> <div class="question-form-title"> </div> <div class="question-form-input"> <select class="form-select" v-model="item.type" @change="changeType"> <option v-for="(type,index2) in types" :key="index2" :value="type.val">{{type.name}}</option> </select> <label><input type="checkbox" v-model="item.required" checked>必填</label> <label v-if="item.type === 'text'||item.type === 'textarea'">字数限制 <input v-model="item.limit" type="number" class="xz"> 字</label> </div> </div> <div class="question-form-option" v-if="item.type === 'radio'||item.type === 'checkbox'"> <ul class="list-group" id="question-options"> <draggable :list="item.options" :move="getdata" @update="datadragEnd" :options="{animation: 100,handle:'.dargDiv'}"> <transition-group name="list-complete" > <li v-for="(item3,index3) in item.options" :key="index3" class="list-group-item"> <span class="glyphicon glyphicon-menu-hamburger dargDiv"></span> <input type="text" v-model="item3.text" class="question-options "> <span @click="delOption(item,item3.id)">×</span> </li> </transition-group> </draggable> </ul> <a href="javascript:;" @click="addOption(item)">添加选项</a> </div> <div class="question-form-option" v-if="item.type === 'star'"> 量表程度 <input class="xz lb" v-model="item.star_min_text" type="text"> - <input v-model="item.star_max_text" type="text" class="xz lb" > 量表范围 {{item.star_val_min}} - {{item.star_val_max}} </div> <div class="question-form" style="text-align: center;margin-top: 20px;"> <button class="btn btn-primary btn-sm" type="button" @click="confirm(item)">确定</button> <button class="btn btn-danger btn-sm" type="button" @click="delQuestion(index)">删除</button> </div> </div> </div> </transition-group> </draggable> <div class="question-box-btn" v-if="!edit"> <button type="button" class="btn btn-primary btn-block" @click="addQuestion">新增题目</button> </div> <div class="question-box-btn" v-if="question.length > 0 && title && !edit"> <button type="button" class="btn btn-success btn-block" onclick="savequestionnaire(this)">保存问卷</button> </div> </div> </div> </div> </div> </div> </div> {/block} {block name="script"} <script type="text/javascript" src="/static/vuejs/require.js"></script> <script> $(document).ready(function(){ formSetValue("enable", {$info.enable|default=1}); }); var question = []; var qstr = ''; var tstr = ''; var dstr = ''; var types = [ {"name":"单选题",val:"radio"}, {"name":"多选题",val:"checkbox"}, {"name":"单行文本题",val:"text"}, {"name":"多行文本题",val:"textarea"}, {"name":"量表题",val:"star"}, ]; require.config({ urlargs: "ver=1.0_0", paths:{ "vue":'/static/vuejs/vue.min2', "sortablejs":'/static/vuejs/sortable', "vuedraggable":'/static/vuejs/vuedraggable' }, shim:{ 'vue':{ exports:'vue' } } }); require(['vue','vuedraggable'],function(Vue,draggable){ Vue.component('draggable', draggable); var vm = new Vue({ el: '#vueapp', data: { question: question, title: '满意度调查', description: '满意度调查描述', editother: 0, types: types, edit: 0, maxid: 1, info: { id: 1, title: "", remark: "", type: "radio", // radio=单选 checkbox=多选 text=单行文本题 textarea=多行文本题 star=量表题 required: true, // true=不填 options: [{ id: 2, text: "选项" }], star_min_text: "非常不满意", star_max_text: "非常满意", star_val_min: 1, star_val_max: 5, limit: 200 // 单行文本题/多行文本题字数限制 } }, computed: { resoptions: function () { return JSON.parse(JSON.stringify(this.question)); } }, watch: { resoptions: function (newval, oldval) { console.log(newval, oldval); this.formatData(); }, }, created: function () { this.formatData(); }, methods: { addQuestion() { const item = JSON.parse(JSON.stringify(this.info)); item.id = this.maxid; item.options[0].id = this.maxid; this.maxid += 2; this.edit = item.id; this.editother = 0; this.question.push(JSON.parse(JSON.stringify(item))); }, editQuestion(obj) { this.edit = obj.id; this.editother = 0; }, delQuestion(index) { let oldoptions = JSON.parse(JSON.stringify(this.question)); let newoptions = []; for(let o in oldoptions){ if(o != index){ newoptions.push(oldoptions[o]); } } this.question = JSON.parse(JSON.stringify(newoptions)); this.edit = 0; }, addOption(obj){ this.question.forEach((item) => { const info = item; if(obj.id === item.id){ const oitem = { id: this.maxid, text: "选项" }; this.maxid += 1; info.options.push(oitem); } }) }, delOption(obj,id){ this.question.forEach((item) => { const info = item; if(obj.id === item.id){ const opts = item.options.filter((item2) => { return item2.id !== id; }); info.options = opts; } }) }, editOthers(val){ this.editother = val; this.edit = 0; }, changeType(val){ console.log(this.question); }, confirm(obj){ // 检查内容是否填写完整 if(obj.title === ''){ layer.msg('题目不能为空'); return false; } if(obj.type === 'radio'||obj.type === 'checkbox'){ if(obj.options.lenght === 0){ layer.msg('未设置选项'); return false; } for (let o in obj.options){ if(obj.options[o].text === ''){ layer.msg('选项内容不能为空'); return false; } } } if(obj.type === 'star'){ if(obj.star_min_text === '' || obj.star_max_text === ''){ layer.msg('量表程度不能为空'); return false; } } this.edit = 0; }, formatData(){ qstr = JSON.stringify(this.question); tstr = this.title; dstr = this.description; }, getdata: function(evt){ console.log(evt); }, datadragEnd:function(evt){ console.log('拖动前的索引:'+evt.oldIndex); console.log('拖动后的索引:'+evt.newIndex); console.log(evt); }, getdata2: function(evt){ console.log(evt); }, datadragEnd2:function(evt){ console.log('拖动前的索引:'+evt.oldIndex); console.log('拖动后的索引:'+evt.newIndex); console.log(evt); } } }) }); function savequestionnaire(_self) { var flag = $(_self).attr('data-flag'); if(flag == 1){ return false; } $(_self).attr('data-flag',1).html('保 存...'); var url = "add"; $.post(url,{title:tstr,description:dstr,question:qstr},function (res) { if(res.code === 1){ parent.layer.closeAll(); }else{ layer.msg(res.info); } $(_self).attr('data-flag',0).html('保 存') }); } </script> {/block}