Please briefly go over this component code.
<template>
<div>
<b-form-checkbox
id="checkbox-0"
v-model="checkboxIsChecked"
name="checkbox-1"
> Nested checkbox
</b-form-checkbox>
<nested-checkbox-error class="ml-4" v-if="checkboxIsChecked"></nested-checkbox-error>
</div>
</template>
<script>
export default {
name: "nested-checkbox-error",
data(){
return {
checkboxIsChecked: false
}
}
}
</script>
<style scoped>
</style>
Here, I am trying to make a nested checkbox. A child checkbox is supposed to appear when you check the box. It works fine for the root checkbox. But for the child checkbox, when I click it, parent's 'checkboxIsChecked' is the one being toggled. Is something wrong with how I understand v-model?
It appears you are using a recursive component.
Each checkbox in a group (that has the same name) should have a different value, and the v-model should also be an array (each checkbox, when checked, stores it's value in the array).
The ID assigned to each checkbox also needs to be unique per checkbox.
Related
Context -
I have a large form that I've broken up into components. I'm going to focus on only one parent/child component relationship for brevity here.
Doing some validation on each child component. Emitting back to parent when a submit button is clicked on the parent.
I have a submit button on the parent. When clicked I am emitting all child component data back to the parent
I have a method on the parent that receives the emitted data. As well as an object instantiated on the parent data() method to assign to the incoming data.
Problem -
When you hit submit, the emitted data is present on the child component, but it's empty on the parent. The submit method finishes before the emitting method finishes.
Is there a best way of accomplishing this?
I could take all inputs and put them in one giant form.. but I hate that approach.
I've tried setTimeout for a brief second. This seems to work at times, but it feels so hacky. I delay the submit method from finishing.. allowing the emit to finish.. that just doesn't feel sustainable or right.
Is there a clear way of doing this? Thank you so much for the assistance.
<1-- Parent -->
<template>
<!-- CHILD -->
<LabExposureType v-if="lab"
#passLabExposureToParent="exposureOnSubmit">
</LabExposureType>
<div class="submitAndClear d-flex justify-center pb-3">
<v-btn color="success" class="mr-4" #click="submit">submit</v-btn>
</div>
</template>
data(){
exposureVals:{},
}
//Removed some data and others for brevity
methods:{
submit() {
//collect vals before doing this
//Exposure values
console.log('emitted exposure vals', this.exposureVals); <- this of course is empty has the below has not finished
},
//Emitted method
exposureOnSubmit(input) {
this.exposureVals = input
}
}
EDIT - Added code for more clarity
Parent -
<LabExposureType v-if="lab" :labState="exposureState" v-model="standardNum"
#passLabExposureToParent="exposureOnSubmit">
</LabExposureType>
CHILD -
<v-text-field v-if="this.isStandardMethod" v-model="standardNum" label="Organization and Standard Number"
class="text-caption primary--text" required :error-messages="standardNumErrors"
:value="modelValue" #input="$emit('update:modelValue', $event.target.value)"
#blur="$v.standardNum.$touch()"></v-text-field>
props and emits -
props: [ "labState", "modelValue"],
emits:['update:modelValue'],
Your child components should emit their values before the submit is ever clicked. Best practice is to use the v-model directive so that the parent always has the latest value of the child. Define the v-model name on the parent with whatever name you want, just make sure the prop name in the child component is named modelValue and that the value is emitted using event update:modelValue:
<!-- Parent -->
<child v-model="searchText" />
<!-- Child -->
<script>
export default {
props: ['modelValue'],
emits: ['update:modelValue']
}
</script>
<template>
<input
:value="modelValue"
#input="$emit('update:modelValue', $event.target.value)"
/>
</template>
I have a textarea which is rendered dynamically when the page loads.
It looks like this :
<textarea type="textarea" class="form-control" name="symptoms_mlform" id="symptoms_mlform">affective</textarea>
I want to have a v-model in this textarea. How can I achieve this.
Purpose for this is I have a dropdown in child component, which emits event when something selected. So that event I am using in parent to populate this textarea.
<MLSubMenu
v-on:SelectedSymptoms="SelectedSymptoms"
>
</MLSubMenu>
SelectedSymptoms(event){
$("#symptoms_mlform").text(event);
},
The event is handled by SelectedSymptoms in parent, which sets the event value to textarea.
The drawback I faced while using this:
If you keep selecting the values from dropdown, it will keep coming in textarea.
But if you remove anything from textarea and then select from dropdown, it will not show in textarea but if I inspect this textarea, selected values will show there but not reflected in browser.
You can achieve this requirement by following the below mentioned steps.
In child component :
SelectedSymptoms(event){
this.$emit('send-selected-value', 'carrier');
}
In parent component :
<div v-on:send-selected-value="getSelectedValue(e)">
<textarea type="textarea" v-model="modelValue" class="form-control" name="symptoms_mlform" id="symptoms_mlform">affective</textarea>
</div>
methods: {
getSelectedValue: function (e) {
this.modelValue = e;
}
}
In the code pen I have two buttons. One Vuetify and the other not. both should call the updateData() function but only the Vuetify component is able to run it succesfully. How can I call the method defined in the component from outside the app div?
https://codepen.io/entropy283/pen/rNxMXGX?editors=1010
You are trying to trigger updateData method, which is accessible only inside the HTML element that Vue is mounted on. I assume you are mounting Vue to the element with id="app".
You have to put the button inside the <div id="app">:
<div id="app">
<button #click="updateData()">Button</button>
...
Or, if you don't need to access any Vue properties, you can just create a function inside script and trigger it with onclick event. Keep in mind that #click is also not accessible outside of Vue:
<button onclick="updateData()">Button</button>
<div id="app">
...
<script>
function updateData() {
console.log('test')
}
</script>
I'm trying to keep update component using checkbox, so if the item is checked then the value should be added to the state item in VueX store.
In child component:
childcomp.vue:
<q-item-section top>
<q-checkbox v-model="chosen" :val="NameProp" color="teal" />
</q-item-section>
Then in parent comopnent I want to display which one are checked
parent.vue:
<childcomp NameProp="Item1"></childcomp>
<childcomp NameProp="Item2"></childcomp>
<childcomp NameProp="Item3"></childcomp>
<p> {{chosen}} </p>
So for example if I check first and last item I should be seeing:
["Item1","Item3"] and empty array if I uncheck them.
What is the easiest way to keep this value updated using VueX store?
Try to observe that array using watcher property and inside the handler dispatch the action :
watch:{
chosen(newVal,oldVal){
this.$store.dispatch('yourAction',newVal);
}
}
I have a question and maybe a Vue bugg.
I have a custom component that needs a #change.native event. But it does not trigger anything and I could not find anything about this issue myself.
So i tried some different stuff and like #click.native and #input.native does work. Even tho #input.native works and do the trick i want to, i still want to know why the change event does not work.
Anybody? Else I should report this.
Vue version: 2.5.2
<custom-input type="search"
placeholder="search"
v-model="search"
#input.native="change" />
If the <input /> inside the custom component is a child element of another element, then the event listener bound by the .native modifier will not be reached, since it is listening to the event of a different element.
custom-input.vue:
<template>
<div>
<input :value="someValue" />
</div>
</template>
<script>
export default {
props: ['value']
}
</script>
so if you have this scenario, then the #change.native will be bound on the <div> (the wrapper).
(sadly) You need to manually propagate the event manually.