radio updates

This commit is contained in:
Max 2022-03-04 14:22:25 -05:00
parent 13532b1c5d
commit b3c869f293
3 changed files with 203 additions and 164 deletions

View file

@ -1,33 +1,62 @@
<template>
<div class="container">
<div class="container">
<div class="row">
<p class="mb-0">{{ colorQuestionText }}</p>
<p class="mb-0">{{ colorQuestionText }}</p>
</div>
</div>
</div>
<div class="container nested-radio" v-for="(value, name, index) in featureListData" :key="index">
<div
class="container nested-radio"
v-for="(value, name, index) in featureListData"
:key="index"
>
<div class="row my-2">
<div class="col">
<listCard v-model="selectedTint[name]" :isRadio="true" :isWide="true" :buttonImage="
<div class="col">
<listCard
v-model="selectedTint[name]"
:value="`${glassLocation}-${glassName}-${name}`"
:isRadio="true"
:isWide="true"
:buttonImage="
require(`@/assets/img/tints/${getTintSourceImage(
glassLocation,
name
)}`)
" :buttonLabel="name" altText="" :buttonID="`${glassLocation}-${glassName}-${name}`" :groupName="`${glassLocation}-${glassName}`" @isCheckedChanged="ResetTintAndPartSelections()" />
</div>
"
:buttonLabel="name"
altText=""
:buttonID="`${glassLocation}-${glassName}-${name}`"
:groupName="`${glassLocation}-${glassName}`"
@isCheckedChanged="ResetTintAndPartSelections()"
/>
</div>
</div>
<transition name="fade" mode="out-in">
<div v-if="
<div
v-if="
selectedTint[name] != undefined &&
selectedTint[name].buttonId ===
`${glassLocation}-${glassName}-${name}`
" class="row my-2" aria-live="polite">
<div class="col">
<buttonQuestion v-model="selectedPart[glassLocation]" buttonType="radio" class="radioQuestion" :questionText="glassFeatureQuestion" :answers="value" textPosition="text-start" :loaderEnabled="false" :isRequired="true" :groupName="`${glassLocation}-${glassName}-${name}`" />
</div>
"
class="row my-2"
aria-live="polite"
>
<div class="col">
<buttonQuestion
v-model="selectedPart[glassLocation]"
buttonType="radio"
class="radioQuestion"
:questionText="glassFeatureQuestion"
:answers="value"
textPosition="text-start"
:loaderEnabled="false"
:isRequired="true"
:groupName="`${glassLocation}-${glassName}-${name}`"
/>
</div>
</div>
</transition>
</div>
</div>
</template>
<script>
@ -36,174 +65,175 @@ import listCard from "@/ux-components/list-card/list-card";
import buttonQuestion from "@/common-components/button-question/button-question";
// Supporting files
import {
getTintImage
} from "@/constants/tint-mapper";
import {
getCustomTransformValue
} from "@/constants/dynamictext-mapper";
import { getTintImage } from "@/constants/tint-mapper";
import { getCustomTransformValue } from "@/constants/dynamictext-mapper";
export default {
name: "glass-part-question",
inheritAttrs: false,
data() {
return {
glassColorQuestion: "",
glassFeatureQuestion: "",
selectedTint: {}, // v-model for the list card selections
};
name: "glass-part-question",
inheritAttrs: false,
data() {
return {
glassColorQuestion: "",
glassFeatureQuestion: "",
selectedTint: {}, // v-model for the list card selections
};
},
props: {
glassName: String,
glassLocation: String,
colorAnswers: Array,
modelValue: {
type: Object,
default: () => ({}),
},
props: {
glassName: String,
glassLocation: String,
colorAnswers: Array,
modelValue: {
type: Object,
default: () => ({}),
},
},
mounted() {
this.LoadPreselectedValues();
if (Object.keys(this.featureListData).length === 1) {
this.AutoSelectTintIfOnlyOneColor(Object.keys(this.featureListData)[0]);
}
},
components: {
listCard,
buttonQuestion,
},
computed: {
colorQuestionText() {
return getCustomTransformValue(
this.glassColorQuestion,
`${this.glassLocation} ${this.glassName}`
);
},
mounted() {
this.LoadPreselectedValues();
if (Object.keys(this.featureListData).length === 1) {
this.AutoSelectTintIfOnlyOneColor(Object.keys(this.featureListData)[0]);
selectedPart: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
},
},
// Creates a map of the feature list data in the correct Name/Value
// format for the button-question component.
featureListData() {
const tintMapByColor = this.colorAnswers.reduce((arr, item) => {
// Create the key
const itemColor = item.ColorAnswerText;
arr[itemColor] = arr[itemColor] || [];
// Map the data to Name/Text object for ButtonQuestion
const mappedItem = item.FeatureAnswers.reduce((featureArr, item) => {
featureArr["Text"] = item.FeatureAnswerText; // Display to User
featureArr["Name"] = item.PartNumber; // Backing Value
return featureArr;
}, {});
// Add onto the final object
arr[itemColor].push(mappedItem);
return arr;
}, {});
return tintMapByColor;
},
PartDataFromApi() {
return this.$store.getters.pageData(this.$route.query.fmgPage);
},
},
methods: {
initializeComponent(cmsContent) {
this.glassColorQuestion = cmsContent.ColorQuestionWidget.QuestionText;
this.glassFeatureQuestion = cmsContent.FeatureQuestionWidget.QuestionText;
},
// Gets tint images based on the glass type, and tint name.
// Returns an empty string if the src or object is undefined.
getTintSourceImage(glassLocation, tintColor) {
const tintSourceObject = getTintImage(glassLocation, tintColor);
if (tintSourceObject === undefined || tintSourceObject.src == undefined) {
return "";
}
return tintSourceObject.src;
},
// Reset selections when tint changes for the same glass to ensure proper selection.
// Also checks if only a single part is present for the tint.
ResetTintAndPartSelections() {
this.selectedTint = {};
this.selectedPart = {};
this.AutoSelectIfSinglePart();
},
// Check if only a single part is present for the tint and set the v-model if it is.
AutoSelectIfSinglePart() {
// Check if the selected tint only has a single feature
Object.keys(this.PartDataFromApi.partsOrQuestions).forEach((key) => {
const currentGlassSelection =
this.PartDataFromApi.partsOrQuestions[key];
if (
currentGlassSelection.glassName === this.glassName &&
currentGlassSelection.glassLocation === this.glassLocation
) {
if (currentGlassSelection.parts.length === 1) {
this.selectedPart = {
[currentGlassSelection.glassLocation]: [
currentGlassSelection.parts[0].partNumber,
],
};
}
}
});
},
components: {
listCard,
buttonQuestion,
AutoSelectTintIfOnlyOneColor(tintColor) {
this.selectedTint[tintColor] = {
buttonId: `${this.glassLocation}-${this.glassName}-${tintColor}`,
checkValue: "",
value: `${this.glassLocation}-${this.glassName}-${tintColor}`,
};
},
computed: {
colorQuestionText() {
return getCustomTransformValue(
this.glassColorQuestion,
`${this.glassLocation} ${this.glassName}`
);
},
selectedPart: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
},
},
LoadPreselectedValues() {
if (Object.keys(this.modelValue).length !== 0) {
// Populate button-question model-value if parts data already exists in VueX
const alreadyPopulatedPartsData =
this.$store.getters.lineItems.glassParts;
// Creates a map of the feature list data in the correct Name/Value
// format for the button-question component.
featureListData() {
const tintMapByColor = this.colorAnswers.reduce((arr, item) => {
// Create the key
const itemColor = item.ColorAnswerText;
arr[itemColor] = arr[itemColor] || [];
Object.keys(alreadyPopulatedPartsData).forEach((key) => {
const partNumber = alreadyPopulatedPartsData[key].partNumber;
const tintColor = alreadyPopulatedPartsData[key].color;
// Map the data to Name/Text object for ButtonQuestion
const mappedItem = item.FeatureAnswers.reduce((featureArr, item) => {
featureArr["Text"] = item.FeatureAnswerText; // Display to User
featureArr["Name"] = item.PartNumber; // Backing Value
return featureArr;
}, {});
// Add onto the final object
arr[itemColor].push(mappedItem);
return arr;
}, {});
return tintMapByColor;
},
PartDataFromApi() {
return this.$store.getters.pageData(this.$route.query.fmgPage);
}
},
methods: {
initializeComponent(cmsContent) {
this.glassColorQuestion = cmsContent.ColorQuestionWidget.QuestionText;
this.glassFeatureQuestion = cmsContent.FeatureQuestionWidget.QuestionText;
},
// Gets tint images based on the glass type, and tint name.
// Returns an empty string if the src or object is undefined.
getTintSourceImage(glassLocation, tintColor) {
const tintSourceObject = getTintImage(glassLocation, tintColor);
if (tintSourceObject === undefined || tintSourceObject.src == undefined) {
return "";
}
return tintSourceObject.src;
},
// Reset selections when tint changes for the same glass to ensure proper selection.
// Also checks if only a single part is present for the tint.
ResetTintAndPartSelections() {
this.selectedTint = {};
this.selectedPart = {};
this.AutoSelectIfSinglePart();
},
// Check if only a single part is present for the tint and set the v-model if it is.
AutoSelectIfSinglePart() {
// Check if the selected tint only has a single feature
Object.keys(this.PartDataFromApi.partsOrQuestions).forEach((key) => {
const currentGlassSelection = this.PartDataFromApi.partsOrQuestions[key];
if (currentGlassSelection.glassName === this.glassName && currentGlassSelection.glassLocation === this.glassLocation) {
if (currentGlassSelection.parts.length === 1) {
this.selectedPart = {
[currentGlassSelection.glassLocation]: [currentGlassSelection.parts[0].partNumber]
};
}
}
});
},
AutoSelectTintIfOnlyOneColor(tintColor) {
this.selectedTint[tintColor] = {
Object.keys(this.modelValue).forEach((key) => {
if (this.modelValue[key][0] === partNumber) {
this.selectedTint[tintColor] = {
buttonId: `${this.glassLocation}-${this.glassName}-${tintColor}`,
checkValue: "",
value: "",
};
},
LoadPreselectedValues() {
if (Object.keys(this.modelValue).length !== 0) {
// Populate button-question model-value if parts data already exists in VueX
const alreadyPopulatedPartsData =
this.$store.getters.lineItems.glassParts;
Object.keys(alreadyPopulatedPartsData).forEach((key) => {
const partNumber = alreadyPopulatedPartsData[key].partNumber;
const tintColor = alreadyPopulatedPartsData[key].color;
Object.keys(this.modelValue).forEach((key) => {
if (this.modelValue[key][0] === partNumber) {
this.selectedTint[tintColor] = {
buttonId: `${this.glassLocation}-${this.glassName}-${tintColor}`,
checkValue: "",
value: "",
};
}
});
});
value: `${this.glassLocation}-${this.glassName}-${tintColor}`,
};
}
},
});
});
}
},
},
};
</script>
<style lang="scss">
.nested-radio {
.ui-radio {
flex-direction: column;
margin: 0.25rem 0;
}
.ui-radio {
flex-direction: column;
margin: 0.25rem 0;
}
p {
font-size: 0.875rem;
}
p {
font-size: 0.875rem;
}
}
</style>

View file

@ -136,7 +136,7 @@ export default {
}
});
});
console.log(this.glassParts)
return {
glassName: g.glassName,
glassLocation: g.glassLocation,

View file

@ -70,6 +70,7 @@ export default {
colLength: String,
validationRules: String,
selectedValues: [Array, String],
modelValue: Object,
hasError: Boolean,
},
data(){
@ -81,6 +82,14 @@ export default {
if(Array.isArray(this.selectedValues)){
this.checkValue = this.isMultiSelect ? this.selectedValues.includes(this.value) : this.selectedValues[0];
}
this.$nextTick(() => {
if(Object.keys(this.modelValue).length > 0) {
this.checkValue = this.modelValue.value;
const emitEvent = { checkValue: this.checkValue, value: this.value.toString(), buttonId: this.buttonID.toString() };
this.$emit('isCheckedChanged', emitEvent);
this.$emit('update:modelValue', emitEvent);
}
})
},
computed: {
getLabelClasses() {