Skip to content

Commit

Permalink
Ranking question type
Browse files Browse the repository at this point in the history
  • Loading branch information
datajohnson committed Apr 8, 2024
1 parent 7027053 commit accb3dd
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 2 deletions.
74 changes: 73 additions & 1 deletion src/web/src/components/QuestionRenderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
v-if="question.isValid() && question.OPTIONAL == 0"
>mdi-check-bold</v-icon
>
<span class="d-none">{{ question.answer }}</span>
</div>
</v-col>
</v-row>

<div v-if="question.TYPE == 'boolean'">
<v-radio-group v-model="question.answer" hide-details>
<v-radio label="Yes" value="Yes" class="pt-1"></v-radio>
Expand Down Expand Up @@ -115,9 +117,46 @@
</tr>
</table>
</div>

<div v-else-if="question.TYPE == 'ranking'">
<v-label
>Select items on the left to move them to the ordered list on the right. To remove items from the ranking,
click them.</v-label
>
<v-row class="mt-3">
<v-col>
<h3>Available options:</h3>
<div>
<div
v-for="option of options.filter((o) => !(question.answer || '').split(',').includes(o.val))"
@click="addChoiceClick(option)"
class="rankingOption">
{{ option.descr }}
</div>
</div>
</v-col>
<v-col>
<h3>
Ranked options:
<small v-if="question.SELECT_LIMIT">Please choose your top {{ question.SELECT_LIMIT }}</small
>:
</h3>

<div>
<div
v-for="(item, index) of (question.answer || '').split(',').filter((f) => f)"
@click="removeChoiceClick(item)"
class="rankingOption">
{{ index + 1 }}. {{ item }}
</div>
</div>
</v-col>
</v-row>
</div>
<div v-else-if="question.TYPE != 'text'">
{{ question }}
</div>

<!-- <hr />
{{ question }} -->
</v-card-text>
Expand All @@ -127,7 +166,7 @@

<script>
import { RenderMarkdown } from "@/utils";
import { isArray } from "lodash";
import { isArray, uniq } from "lodash";
import { nextTick } from "vue";
export default {
Expand Down Expand Up @@ -221,6 +260,30 @@ export default {
}
}
},
addChoiceClick(item) {
let items = (this.question.answer ?? "").split(",");
items = items.filter((i) => i);
items = uniq(items);
if (this.question.SELECT_LIMIT) {
const limit = parseInt(this.question.SELECT_LIMIT);
if (items.length >= limit) {
return;
}
}
if (items.includes(item.val)) return;
items.push(item.val);
this.question.answer = items.join(",");
this.$emit("answerChanged", this.question.answer);
},
removeChoiceClick(item) {
let items = (this.question.answer ?? "").split(",");
items = items.filter((i) => i && i != item);
this.question.answer = items.join(",");
this.$emit("answerChanged", this.question.answer);
},
},
};
</script>
Expand Down Expand Up @@ -248,4 +311,13 @@ table.matrix th {
font-weight: 400;
font-size: 0.95rem;
}
.rankingOption {
border: 1px #999 solid;
border-radius: 4px;
padding: 5px 10px;
margin-bottom: 5px;
background-color: white;
cursor: pointer;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,34 @@
clearable
item-title="TITLE" />
</v-col>
<v-col v-if="question.TYPE == 'quadrant'">
<v-select
v-model="question.GROUP_ID"
label="Group"
:items="groupOptions"
item-value="QID"
item-title="ASK" />

<v-select
v-model="question.JSON_ID"
label="List"
:items="survey.choices"
item-value="JSON_ID"
clearable
item-title="TITLE" />
</v-col>
<v-col v-if="question.TYPE == 'multi-select'">
<v-text-field v-model="question.SELECT_LIMIT" label="Select limit" hide-details />
<v-text-field v-model="question.SELECT_LIMIT" label="Select limit" />
<v-select
v-model="question.JSON_ID"
label="List"
:items="survey.choices"
item-value="JSON_ID"
clearable
item-title="TITLE" />
</v-col>
<v-col v-if="question.TYPE == 'ranking'">
<v-text-field v-model="question.SELECT_LIMIT" label="Select limit" />
<v-select
v-model="question.JSON_ID"
label="List"
Expand Down
11 changes: 11 additions & 0 deletions src/web/src/store/SurveyStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ export const useSurveyStore = defineStore("survey", {
return true;
}

if (q.TYPE == "ranking") {
let items = (q.answer ?? "").split(",").filter((i: string) => i);

if (q.SELECT_LIMIT) {
const limit = parseInt(q.SELECT_LIMIT);
if (items.length < limit) return false;
}

return items.length > 0;
}

if (q.TYPE == "matrix_question") {
return q.answer && q.answer != false;
}
Expand Down

0 comments on commit accb3dd

Please sign in to comment.