Hi Guys I'm Newbie at VueJS,
Anyone who can help me about on getting default checked at my checkbox list
I'm using v-model so the checked won't work
Any idea or suggestion?
You bind the input to a truthy value using the v-model directive
<input type="checkbox" v-model="selected">
In your component data (Updated based on #Phil s comment)
data () {
return {
selected: true, // True of false, or other truthy value depending on needs
}
}
Then, depending on the value on selected your input will be checked/unchecked.
Note - in the documents it is stated that
v-model will ignore the initial value, checked, or selected attributes
found on any form elements. It will always treat the Vue instance data
as the source of truth. You should declare the initial value on the
JavaScript side, inside the data option of your component.
Read more at https://v2.vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components
Related
The value(s) are being stored correctly—the v-model is correct, I'm just having trouble getting the checkboxes to be checked or not.
Here is my template:
<input type="checkbox"
v-for="thing in things"
:value="thing.id"
v-model="$v.thing.activities.$model"
:checked="$v.thing.activities.$model.some((el) => el.id === thing.id)"
/>
I am using NestJs to handle saving my data. There is a many:many relationship, so the system returning the entire object.
Here is what my v-model looks like. It's an array of objects:
[
0:Object
createdAt:""
description:"This is what thing is."
id:"07347f64-..."
name:"Thing"
updatedAt:""
]
When I click on a checkbox, I can see that the v-model is updated properly with the new id which is great.
I know it's working properly, when I do this on my template to test, it renders true or false as expected:
{{ $v.thing.activities.$model.some((el) => el.id === thing.id) }} // true
I see in the vue docs that v-model will take precedence over :checked, but since my v-model is an array of objects, I'm not sure how to set the checked property of the checkbox.
I've also tried pulling the current loop value and creating a temporary array push/splice values out to get the checkbox to render properly in a created hook. No luck there either. I think everything needs to come from the v-model, but I'm at a loss.
How can I correctly show the checkbox as checked?
I want to create an input field that the user can fill out. The catch is that I don't want them to fill this field in with special characters. Currently, I have this html setup:
<input class="rc-input-editing" id="bioInput" type="text" v-model="wrappedBioName">
And this Vue.js setup (As you can see, I'm trying to approach this problem using a computed setter) :
data () {
return {
newBioName: '',
}
},
computed: {
wrappedBioName: {
get () {
alert('getting new name!')
return this.newBioName
},
set: function (newValue) {
const restrictedChars = new RegExp('[.*\\W.*]')
if (!restrictedChars.test(newValue)) {
this.newBioName = newValue
}
}
}
Currently, my issue is that the client is able to continue filling out the text input field, even when this.newBioName isn't updating. In other words, they are able to enter special characters into the input field, even though the this.newBioName isn't being updated with these special characters.
This behavior is different than what I'm expecting, given my current understanding of v-model. Based on what I've read until now, v-model binds the input element to some vue instance data, and that vue instance data to the input element (two way binding). Therefore, I'm expecting that the text in the text input field will directly match the value of this.newBioName.
Clearly, I'm missing something, and would appreciate a second pair of eyes!
Vue.js two way binding system doesn't work as you expected. Each binding process works one way each time. So, the thing you should do is not to let the input text change.
Try keypress event instead of computed property like this:
<input class="rc-input-editing" id="bioInput" type="text" v-model="newBioName" #keypress="nameKeyPressAction">
data() {
return {
newBioName: ""
};
},
methods: {
nameKeyPressAction(event) {
const restrictedChars = new RegExp("[.*\\W.*]");
const newValue = this.newBioName + event.key;
if (!restrictedChars.test(newValue))
this.newBioName = newValue;
return event.preventDefault();
}
}
Edit:
When you set a data property or a computed property as v-model of an input, vue associates them and yet, if user updates dom object via the input, property's setter is triggered and the process ends here. On the other hand, when you change the value of the property on javascript side, vue updates the dom object and this process also ends here.
In your sample code, it seems like you expect that the computed property's getter to set the dom again but it can't. The property is already updated via dom change and it can't also update it. Othervise, there might occur infinite loop.
I'm using bootstrap-vue table, according to documentation regarding formatter callback: https://bootstrap-vue.org/docs/components/table .
A variable is defined in data(), I will need this variable as a flag to control the cell content.
data() {
return {
aFlag: 0,
}
}
Then in the fields I use the formatter call back:
{ key: 'value', label: 'Value', formatter: this.updateValue},
In the methods area I use updateValue to update the flag:
methods: {
updateValue(value) {
..
aFlag = value
..
}
}
Then error "You may have an infinite update loop in a component render function." happened here.
If I want to do such a thing, is there any best practice? The cell content may cause other cell's change, so currently I use a variable to control the behavior as a flag. Thanks in adavance.
The formatter callback is only intended to change how the value is displayed to the user, not change its value.
If you want to be able to change the value, I'd suggest using a slot for the value property and use v-model on a form component within the slot:
<template v-slot:cell(value)="data">
<input type="text" v-model="data.value"/>
</template>
Considering following HTML code:
<div id="app">
<comp :is_checked="is_checked" v-on:ch="function(x){is_checked_2=x}"></comp>
<p>{{ is_checked_2 }}</p>
</div>
<script src="app.js"></script>
and app.js:
var tm = `<div>
<input type="checkbox" v-model="is_checked"
v-on:change="$emit('ch',is_checked)"
>{{ is_checked }}
</div>`
Vue.component('comp', {
template: tm,
props: ["is_checked"]
})
new Vue({
el: "#app",
data: function() {
return {
is_checked: null,
is_checked_2: null
};
}
});
If we replace is_checked_2=x by console.log(x) in v-on:ch="function(x){...}, everything works correct and v-model is changing is_checked when input checkbox value changes.
Also if we don't send the value of variable by props and define it locally in component, everything works correct.
It seems that changing the parent Vue's object variable is
regenerating the whole HTML of component where the value of variable
is sent by props and the variable is reset there immediately after
firing the event inside template. It is causing that functions
triggered by events don't change component's variables.
Is it a bug in Vue.js?
To make it more clear, the behavior is following: changing whatever Vue parent value that is not bound and however related to the component (no props, no slots) results at resetting all values in the component that are bound by props. Following only occurs if we reactivelly write to parent/main HTML using modified parent variable, we can achieve that by placing {{ .... }} there. This seems to be the bug.
Example: Vue has variables a and b. We place {{ a }} to the main code. The value of variable b is sent by props to component and matched to variable c. With the time we are changing that value of variable c inside the component. In one moment we decide to change value of a and it results by "forgetting" current state of c and it is reset to initial state by invoked props.
To summarize: the bug itself gets stuck that props should be reactivelly invoked only if corresponding parent variable is changed and not if whatever parent variable changes and at the same time they modify HTML code.
This issue doesn't have nothing to do with event listeners neither events, because it is possible to replicate it without using them.
Conclusion:
{{ is_checked_2 }} or {{ '',is_checked_2 }} or {{ '',console.log(is_checked_2) }} after changing value of is_checked_2 is causing rerendering the whole top Vue component having is_checked as variable and it is resetting child component variable, because it has the same name. The solution is never using the same name for child and parent component variables bound by props. This is issue of Vue/props architecture how it was designed.
I don't think it's a bug.
You're most likely running into a race condition where your change event gets executed before or in place of the internally attached one (hence the seemingly nullified data binding).
Because v-model is essentially just a syntactic sugar for updating data on user input events. Quoting the docs:
v-model internally uses different properties and emits different events for different input elements:
text and textarea elements use value property and input event;
checkboxes and radiobuttons use checked property and change event;
select fields use value as a prop and change as an event.
You might also want to see "Customizing Component v-model".
I cannot for the life of me figure this out.
Fiddle at: https://jsfiddle.net/s8xvkt10/
I want
User clicks checkbox
Then based on separate conditions
Checkbox calculatedCheckedValue returns a data property /v-model of true/false
And the checked state reflects the calculatedCheckedValue
I can get:
The calculatedCheckedValue calculates and interpolates properly
But I fail at:
Having the :checked attribute render the calculatedCheckedValue properly in the DOM
e.g. If a false checkbox is clicked and the calculatedCheckedValue still returns false, the checkbox toggles onscreen between checked and unchecked
I’ve tried:
Using a v-model with a custom set that does the calculation and sets the local state which the custom get returns
Imitating a v-model using #change.prevent.stop="updateCalculatedValue" and :checked="calculatedValue"
Assuming the #change happens after the #click (which i think is wrong) and using #click.prevent.stop="updateCalculatedValue" and :checked="calculatedValue"
The model is working and rendering the calculated value as string in a DOM span,
but the checked value doesn't seem to respect the model value
Can someone please help me out?
I've solved the problem at: https://jsfiddle.net/pc7y2kwg/2/
As far as I can tell, the click event is triggered even by keyboard events (src)
And happens before the #change or #input events (src)
So you can click.prevent the event, but you need to either prevent it selectively or retrigger the event after the calculation.
//HTML Template
<input :checked="calculatedValue5" #click="correctAnswer" type="checkbox">
//VUE component
data() {
return {
calculatedValue5: false,
};
},
methods: {
correctAnswer(e){
const newDomValue = e.target.checked;
this.calculatedValue5 = this._calculateNewValue(newDomValue);
if(this.calculatedValue5 !== newDomValue){
e.preventDefault();
}
}
}
I think this is preventing checkbox value from updating before the data value, which seems to break the reactivity. I'm not sure the technical reason why, but the demo does work