Answer a question

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>

Answers

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>
Logo

Vue社区为您提供最前沿的新闻资讯和知识内容

更多推荐