Aaron Reese
Aaron Reese

Reputation: 554

vuetify list-item-group how to unselect the selected record

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

Answers (2)

Lana
Lana

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

Angelo
Angelo

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

Related Questions