Reputation: 554
I have a vuetify 2.0 view-list which when selected populates a form for editing (standard list-detail design pattern). The selected item gets highlighted in the list which is good (I know I can turn it off...). What I would like to do is if the selected item is selected again to clear the form, or if the user clicks the [Clear] button to un-select the list item.
I can't see anything in either the App or Vuetify objects that is tracking this state. How do I wire up the populated state of the form with the selected/active status of the view-list-item
Example codepen https://codepen.io/E4CAaron/pen/NWWeBXZ
Example Code below: Script;
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
msg: 'Hello',
email: '',
rules:[
{id:"1","name":"rule one",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"},
{id:"2",name:"rule two",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"},
{id:"3",name:"rule three",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"},
{id:"4",name:"rule four",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"},
{id:"5",name:"rule five",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"}
],
SelectedRule:{},
state:{
formIsDirty:false
}
},
methods: {
editRule(rule){
this.SelectedRule = Object.assign({},rule);
this.state.formIsDirty = false
},
clearRule(){
this.SelectedRule ={}
},
dirtyForm(){
this.state.formIsDirty =true;
},
onScroll (e) {
this.offsetTop = e.target.scrollTop
},
}
})
HTML:
<div id="app" v-cloak>
<v-app>
<v-container>
<v-row>
<v-col cols="4">
<v-list
dense
id="scroll-target"
style="max-height: 100%"
class="overflow-y-auto"
>
<v-subheader>Rules</v-subheader>
<v-list-item-group
color="warning"
dense
>
<v-list-item
v-for="rule in rules"
:key="rule.id"
@click="editRule(rule)"
>
{{rule.name}}
</v-list-item>
</v-list-item-group>
</v-list>
</v-col>
<v-col cols="8">
<v-form fixed >
<v-text-field label="Rule Name" v-model="SelectedRule.name" @change="dirtyForm"></v-text-field>
<v-text-field label="Conversion Rate" v-model="SelectedRule.conversion_rate" @change="dirtyForm"></v-text-field>
<v-text-field label="Round To Nearest" v-model="SelectedRule.round_to_nearest" @change="dirtyForm"></v-text-field>
<v-checkbox label="is Brand RRP" v-model="SelectedRule.isRRP" checked @change="dirtyForm"></v-checkbox>
<v-btn color="primary" :disabled="!state.formIsDirty">Save</v-btn>
<v-btn color="info" @click="clearRule()">Clear</v-btn>
</v-form>
</v-col>
</v-row>
</v-container>
</v-app>
</div>
Upvotes: 3
Views: 6975
Reputation: 1267
Add v-model
to the v-list-item-group
and you will be able to change the selected item of v-list-item-group
programmatically.
Now, step-by-step. First, add v-model
:
<v-list-item-group
v-model="rule"
color="warning"
dense
>
Then add the rule
in data
and watch it. If it became null
, clear your form.
...
data: {
...,
rule: null
},
watch: {
rule: function () {
if (this.rule==null) this.clearRule()
}
},
...
And finally, clear rule
when the user clicks Clear button. Modify your clearRule
method like this:
clearRule(){
this.SelectedRule ={}
this.rule = nul
},
Here is working code snippet:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
msg: 'Hello',
email: '',
rules:[
{id:"1","name":"rule one",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"},
{id:"2",name:"rule two",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"},
{id:"3",name:"rule three",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"},
{id:"4",name:"rule four",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"},
{id:"5",name:"rule five",conversion_rate:"1.17",round_to_nearest:".05",isRRP:"0"}
],
SelectedRule:{},
state:{
formIsDirty:false
},
rule:null
},
watch: {
rule: function () {
if (this.rule==null) this.clearRule()
}
},
methods: {
editRule(rule){
this.SelectedRule = Object.assign({},rule);
this.state.formIsDirty = false
},
clearRule(){
this.SelectedRule ={}
this.rule = null
},
dirtyForm(){
this.state.formIsDirty =true;
},
onScroll (e) {
this.offsetTop = e.target.scrollTop
},
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vuetify/2.1.1/vuetify.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/2.1.1/vuetify.js"></script>
<div id="app" v-cloak>
<v-app>
<v-container>
<v-row>
<v-col cols="4">
{{msg}}
<v-list
dense
id="scroll-target"
style="max-height: 100%"
class="overflow-y-auto"
>
<v-subheader>Rules</v-subheader>
<v-list-item-group v-model='rule'
color="warning"
dense
>
<v-list-item
v-for="rule in rules"
:key="rule.id"
@click="editRule(rule)"
>
{{rule.name}}
</v-list-item>
</v-list-item-group>
</v-list>
</v-col>
<v-col cols="8">
<v-form fixed >
<v-text-field label="Rule Name" v-model="SelectedRule.name" @change="dirtyForm"></v-text-field>
<v-text-field label="Conversion Rate" v-model="SelectedRule.conversion_rate" @change="dirtyForm"></v-text-field>
<v-text-field label="Round To Nearest" v-model="SelectedRule.round_to_nearest" @change="dirtyForm"></v-text-field>
<v-checkbox label="is Brand RRP" v-model="SelectedRule.isRRP" checked @change="dirtyForm"></v-checkbox>
<v-btn color="primary" :disabled="!state.formIsDirty">Save</v-btn>
<v-btn color="info" @click="clearRule()">Clear</v-btn>
</v-form>
</v-col>
</v-row>
</v-container>
</v-app>
</div>
Upvotes: 3
Reputation: 1666
You can check the rule if it was already selected (as stored in the SelectedRule
variable, and in your edit rule method, simply set the SelectedRule value to the empty object.
editRule(rule){
if (this.SelectedRule.id === rule.id) {
this.SelectedRule = {}
} else {
this.SelectedRule = Object.assign({},rule);
this.state.formIsDirty = false
}
}
I've tested this code on the Codepen you have provided.
Upvotes: 1