Skip to content

Commit 2c80ab5

Browse files
Merge pull request #6 from rajeshwarpatlolla/master
added ui improvements in question view and survey builder view
2 parents b7e0f6d + f1e7c53 commit 2c80ab5

File tree

4 files changed

+63
-48
lines changed

4 files changed

+63
-48
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ This version is the initial release of this open source project. It has all the
8888
#### 0.2.0
8989
This version exports `SurveyBuilder`, `QuestionsView` and `SurveyBuilderJson` from index.js file.
9090

91+
#### 0.3.0
92+
This version improves the UI of the survey builder and question view components.
93+
9194
### To Do
92-
- Support for rating question
9395
- Introduce drag and drop
9496

9597
### Organisation

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-survey-builder",
3-
"version": "0.2.0",
3+
"version": "0.3.0",
44
"description": "A survey builder component for vue.js applications",
55
"main": "src/index.js",
66
"scripts": {

src/QuestionsView.vue

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
<div class="row">
99
<div class="p-0">
1010
<div class="question-section">
11-
<p class="question_color">Question
11+
<p class="question_number">Question
1212
<span class="">{{ index + 1 }}:</span>
1313
</p>
1414
<p class="question_body">{{question.body}}</p>
1515
</div>
1616
<div class="answer-section">
1717
<div class="option-section" v-if="question.type === 'BOOLEAN'">
18-
<div class="" v-for='(option, index) in question.options' :key="index">
18+
<div class="" v-for='(option, index) in question?.options' :key="index">
1919
<p class="radio-option">
2020
<input type="radio" name="boolean_type" :disabled="readOnly">
2121
<label>{{option.body}}</label>
@@ -76,7 +76,7 @@
7676
<script>
7777
// import _ from 'lodash';
7878
import vueSlider from 'vue-slider-component';
79-
import SurveyBuilder from './SurveyBuilder';
79+
import SurveyBuilder from './SurveyBuilder.vue';
8080
8181
export default {
8282
name: 'QuestionsView',
@@ -88,8 +88,7 @@ export default {
8888
props: ['questions', 'readOnly'],
8989
components: { SurveyBuilder, vueSlider },
9090
mounted() {
91-
this.$root.$on('selected-question', obj => {
92-
window.console.log(obj);
91+
this.$root.$on('selected-question', (obj) => {
9392
this.selectedQuestion = { id: null };
9493
});
9594
},
@@ -99,7 +98,7 @@ export default {
9998
this.selectedQuestion.questionNumber = index + 1;
10099
},
101100
deleteQuestion(question, index) {
102-
this.questions.splice(index, 1);
101+
this.questions.splice(index, 1); // eslint-disable-line
103102
},
104103
},
105104
};
@@ -130,10 +129,12 @@ h3 {
130129
.question_body {
131130
word-break: break-all;
132131
color: #555;
132+
font-weight: 500;
133+
font-size: 16px;
133134
}
134135
135136
.read-only-question {
136-
background-color: #fafafa;
137+
// background-color: #fafafa;
137138
}
138139
139140
.icon-style {
@@ -253,12 +254,21 @@ button {
253254
}
254255
255256
.card {
256-
border: 1px solid rgba(0, 0, 0, 0.125);
257-
padding: 12px;
258-
margin-bottom: 12px;
257+
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
258+
border-radius: 4px;
259+
padding: 16px;
260+
margin-bottom: 16px;
261+
&:hover {
262+
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
263+
}
264+
}
265+
266+
.question_number {
267+
color: #555;
268+
font-size: 16px;
269+
font-weight: 500;
259270
}
260271
261-
.question_color,
262272
input {
263273
color: #555;
264274
font-size: 16px;

src/SurveyBuilder.vue

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,37 @@
11
<template>
22
<div class="vue-survey-builder-content vsb-content">
33
<select class="vsb-select" v-model="selectedType" v-on:change="questionTypeChanged(selectedType)">
4-
<option v-for="(questionType, index) in questionTypes" :value="questionType.value" :key="index" :disabled="questionType.value === 'DEFAULT'" :selected="questionType.value === 'DEFAULT'">{{questionType.label}}</option>
4+
<option v-for="(questionType, index) in questionTypes" :value="questionType.value" :key="index" :disabled="questionType.value === 'DEFAULT'" :selected="questionType.value === 'DEFAULT'">
5+
{{ questionType.label }}
6+
</option>
57
</select>
68
<div class="question-section" v-if="selectedType !== 'DEFAULT'">
79
<div class="pb-10">
810
<div class="vsb-choices-text">Question</div>
9-
<input type="text" class="" placeholder="Enter question text" v-model="question.body">
11+
<input type="text" class="" placeholder="Enter question text" v-model="question.body" />
1012
</div>
1113
<div class="" v-if="selectedType === 'BOOLEAN'">
1214
<div class="vsb-choices-text">Answer Choices</div>
1315
<div class="" v-for="(option, index) in question.options" :key="index">
1416
<div class="clear-both">
15-
<input type="text" class="width-100 float-left" placeholder="Enter an answer choice" v-model="option.body">
17+
<input type="text" class="width-100 float-left" placeholder="Enter an answer choice" v-model="option.body" />
1618
<button class="vsb-btn-link color-red width-10 mt-10" v-on:click="deleteQuestionOptionItem(question.options, index)" v-if="index > 1">Remove</button>
1719
</div>
1820
</div>
1921
</div>
2022
<div class="" v-if="selectedType === 'DATE'">
2123
<div class="">
22-
<label class="vsb-block"><input type="radio" v-model="question.dateFormat" value="MM/DD/YY"> MM/DD/YY</label>
23-
<label class="vsb-block"><input type="radio" v-model="question.dateFormat" value="DD/MM/YY"> DD/MM/YY</label>
24-
<label class="vsb-block"><input type="radio" v-model="question.dateFormat" value="MM/DD/YYYY"> MM/DD/YYYY</label>
25-
<label class="vsb-block"><input type="radio" v-model="question.dateFormat" value="DD/MM/YYYY"> DD/MM/YYYY</label>
24+
<label class="vsb-block"><input type="radio" v-model="question.dateFormat" value="MM/DD/YY" /> MM/DD/YY</label>
25+
<label class="vsb-block"><input type="radio" v-model="question.dateFormat" value="DD/MM/YY" /> DD/MM/YY</label>
26+
<label class="vsb-block"><input type="radio" v-model="question.dateFormat" value="MM/DD/YYYY" /> MM/DD/YYYY</label>
27+
<label class="vsb-block"><input type="radio" v-model="question.dateFormat" value="DD/MM/YYYY" /> DD/MM/YYYY</label>
2628
</div>
2729
</div>
2830
<div class="" v-if="selectedType === 'MULTI_CHOICE'">
2931
<div class="vsb-choices-text">Answer Choices</div>
3032
<div class="" v-for="(option, index) in question.options" :key="index">
3133
<div class="clear-both">
32-
<input type="text" class="width-90 float-left" placeholder="Enter an answer choice" v-model="option.body">
34+
<input type="text" class="width-90 float-left" placeholder="Enter an answer choice" v-model="option.body" />
3335
<button class="vsb-btn-link color-red width-10 mt-10" v-on:click="deleteQuestionOptionItem(question.options, index)" v-if="index > 1">Remove</button>
3436
</div>
3537
</div>
@@ -41,14 +43,15 @@
4143
<div class="" v-if="selectedType === 'NUMBER'">
4244
<label class="display-block">
4345
<input type="checkbox" class="" v-model="question.hasUnits" name="hasUnits" />
44-
<span class="">Answer label <input type="text" class="width-10" placeholder="ex. mins, lbs, days" v-model="question.units" :disabled="!question.hasUnits"></span>
46+
<span class="">Answer label <input type="text" class="width-10" placeholder="ex. mins, lbs, days" v-model="question.units" :disabled="!question.hasUnits" /></span>
4547
</label>
4648
<label class="display-block">
4749
<input type="checkbox" v-model="question.hasMinMax" name="subType" />
48-
<span class="">Min/max value
49-
<input type="number" class="width-10" v-model="question.minValue" placeholder="min" min="1" max="2048" :disabled="!question.hasMinMax">
50+
<span class=""
51+
>Min/max value
52+
<input type="number" class="width-10" v-model="question.minValue" placeholder="min" min="1" max="2048" :disabled="!question.hasMinMax" />
5053
<span class="width-10">to</span>
51-
<input type="number" class="width-10" v-model="question.maxValue" placeholder="max" min="1" max="2048" :disabled="!question.hasMinMax">
54+
<input type="number" class="width-10" v-model="question.maxValue" placeholder="max" min="1" max="2048" :disabled="!question.hasMinMax" />
5255
</span>
5356
</label>
5457
<label class="display-block">
@@ -61,7 +64,7 @@
6164
<div class="">
6265
<div class="display-inline-block">Intervals</div>
6366
<div class="intervals display-inline-block">
64-
<input type="number" min="2" max="100" v-model="question.intervals" v-on:change="changeLabelsLength(question.intervals)">
67+
<input type="number" min="2" max="100" v-model="question.intervals" v-on:change="changeLabelsLength(question.intervals)" />
6568
</div>
6669
<span class="" v-if="question.reportable">Max of 100 intervals can be entered.</span>
6770
</div>
@@ -70,18 +73,18 @@
7073
<div v-if="index === 0">
7174
<div class="width-10 float-left pt-10">Top</div>
7275
<div class="width-90">
73-
<input type="text" class="" placeholder="Enter value" v-model="question.labels[question.labels.length - index - 1]">
76+
<input type="text" class="" placeholder="Enter value" v-model="question.labels[question.labels.length - index - 1]" />
7477
</div>
7578
</div>
76-
<div v-else-if="question.labels && (index === question.labels.length - 1)">
79+
<div v-else-if="question.labels && index === question.labels.length - 1">
7780
<div class="width-10 float-left pt-10">Bottom</div>
7881
<div class="width-90">
79-
<input type="text" name="vertical-labels" class="" placeholder="Enter value" v-model="question.labels[question.labels.length - index - 1]">
82+
<input type="text" name="vertical-labels" class="" placeholder="Enter value" v-model="question.labels[question.labels.length - index - 1]" />
8083
</div>
8184
</div>
82-
<div class="text-right" v-if="question.labels && index !== 0 && (index !== question.labels.length - 1)">
85+
<div class="text-right" v-if="question.labels && index !== 0 && index !== question.labels.length - 1">
8386
<div class="width-90">
84-
<input type="text" class="" placeholder="Enter value" v-model="question.labels[question.labels.length - index - 1]">
87+
<input type="text" class="" placeholder="Enter value" v-model="question.labels[question.labels.length - index - 1]" />
8588
</div>
8689
</div>
8790
</div>
@@ -91,24 +94,24 @@
9194
<div class="vsb-choices-text">Answer Choices</div>
9295
<div class="" v-for="(option, index) in question.options" :key="index">
9396
<div class="clear-both">
94-
<input type="text" class="width-90 float-left" placeholder="Enter an answer choice" v-model="option.body">
97+
<input type="text" class="width-90 float-left" placeholder="Enter an answer choice" v-model="option.body" />
9598
<button class="vsb-btn-link color-red width-10 mt-10" v-on:click="deleteQuestionOptionItem(question.options, index)" v-if="index > 1">Remove</button>
9699
</div>
97100
</div>
98-
<div class="display-block">
99-
<button class="vsb-btn-link color-blue" v-on:click="addAnotherAnswer()">Add another answer</button>
101+
<div class="vsb-add-answer-btn vsb-btn-link color-blue">
102+
<a v-on:click="addAnotherAnswer()">Add another answer</a>
100103
</div>
101104
</div>
102105
<div class="" v-if="selectedType === 'TEXT'">
103106
<label class="">
104107
<input type="checkbox" v-model="question.characterLimited" name="characterLimited" />
105-
<span class="">Character limit <input type="number" class="char-limit-input" v-model="question.textLimit" placeholder="" min="1" max="2048" :disabled="!question.characterLimited"></span>
108+
<span class="">Character limit <input type="number" class="char-limit-input" v-model="question.textLimit" placeholder="" min="1" max="2048" :disabled="!question.characterLimited" /></span>
106109
</label>
107110
</div>
108111
<div class="" v-if="selectedType === 'TIME'">
109112
<div class="">
110-
<label class=""><input type="radio" v-model="question.timeFormat" value="12" v-on:click="timeFormatModified(question.timeFormat)"> 12 hrs</label>
111-
<label class=""><input type="radio" v-model="question.timeFormat" value="24" v-on:click="timeFormatModified(question.timeFormat)"> 24 hrs</label>
113+
<label class=""><input type="radio" v-model="question.timeFormat" value="12" v-on:click="timeFormatModified(question.timeFormat)" /> 12 hrs</label>
114+
<label class=""><input type="radio" v-model="question.timeFormat" value="24" v-on:click="timeFormatModified(question.timeFormat)" /> 24 hrs</label>
112115
</div>
113116
</div>
114117
<div class="buttons-section">
@@ -155,7 +158,10 @@ export default {
155158
this.question.type = this.selectedType;
156159
switch (type) {
157160
case 'BOOLEAN':
158-
this.question.options = [{ body: 'Yes', sequence: 1 }, { body: 'No', sequence: 2 }];
161+
this.question.options = [
162+
{ body: 'Yes', sequence: 1 },
163+
{ body: 'No', sequence: 2 },
164+
];
159165
break;
160166
case 'SCALE':
161167
this.question.labels.length = 2;
@@ -181,7 +187,7 @@ export default {
181187
if (!this.question.options) {
182188
this.question.options = [];
183189
}
184-
let maxSequence = Number(Math.max(...this.question.options.map(x => x.sequence)));
190+
let maxSequence = Number(Math.max(...this.question.options.map((x) => x.sequence)));
185191
if (!maxSequence) {
186192
maxSequence = this.question.options.length;
187193
}
@@ -216,7 +222,7 @@ export default {
216222
*/
217223
saveQuestion(question) {
218224
question.id = question.id ? question.id : this.getGUID(); // eslint-disable-line
219-
this.$root.$emit('add-update-question', question);
225+
this.$root.$emit('add-update-question', { question, operation: 'save' });
220226
this.question = { type: 'DEFAULT' };
221227
},
222228
@@ -308,11 +314,9 @@ $color-green: #48bf7a;
308314
.vue-survey-builder-content {
309315
font-family: Arial, Helvetica, sans-serif;
310316
font-weight: normal;
311-
border: 1px solid #ddd;
312-
padding: 10px;
313-
box-shadow: 1px 1px 5px 0px #ddd;
314-
background-color: $color-primary;
315-
border-radius: 2px;
317+
padding: 12px;
318+
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
319+
border-radius: 4px;
316320
margin: 12px 0;
317321
318322
input[type='text'],
@@ -330,11 +334,10 @@ $color-green: #48bf7a;
330334
background-color: #fff;
331335
}
332336
select {
333-
-webkit-appearance: none;
334-
-moz-appearance: none;
337+
// -webkit-appearance: none;
338+
// -moz-appearance: none;
335339
background-position: right 50%;
336340
background-repeat: no-repeat;
337-
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAMCAYAAABSgIzaAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDZFNDEwNjlGNzFEMTFFMkJEQ0VDRTM1N0RCMzMyMkIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDZFNDEwNkFGNzFEMTFFMkJEQ0VDRTM1N0RCMzMyMkIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0NkU0MTA2N0Y3MUQxMUUyQkRDRUNFMzU3REIzMzIyQiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0NkU0MTA2OEY3MUQxMUUyQkRDRUNFMzU3REIzMzIyQiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuGsgwQAAAA5SURBVHjaYvz//z8DOYCJgUxAf42MQIzTk0D/M+KzkRGPoQSdykiKJrBGpOhgJFYTWNEIiEeAAAMAzNENEOH+do8AAAAASUVORK5CYII=);
338341
}
339342
340343
button {

0 commit comments

Comments
 (0)