Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add option to select one row at a time in data tables #2973

Closed
wants to merge 6 commits into from
Closed

[Feature] Add option to select one row at a time in data tables #2973

wants to merge 6 commits into from

Conversation

jim0thy
Copy link

@jim0thy jim0thy commented Jan 9, 2018

Description

Option to select one row at a time in a data table, radio-button style. Selecting a new row will clear the previous selection.
Adds radioSelect boolean prop to v-data-table, plus code to clear previous selection if the prop is true.

Motivation and Context

Allows the user to provide extra functionality in custom components based on a guaranteed single-row selection in the data table; a preview pane, for example.

Resolves #2960

How Has This Been Tested?

Jest.
No new test, as modified code ondata-iterable isn't currently subject to unit testing

Markup:

<template>
  <v-data-table
    v-bind:headers="headers"
    v-bind:items="items"
    v-bind:search="search"
    v-model="selected"
    item-key="name"
    radio-select
    class="elevation-1"
  >
    <template slot="headerCell" slot-scope="props">
      <v-tooltip bottom>
        <span slot="activator">
          {{ props.header.text }}
        </span>
        <span>
          {{ props.header.text }}
        </span>
      </v-tooltip>
    </template>
    <template slot="items" slot-scope="props">
      <td>
        <v-checkbox
          primary
          hide-details
          v-model="props.selected"
        ></v-checkbox>
      </td>
      <td>{{ props.item.name }}</td>
      <td class="text-xs-right">{{ props.item.calories }}</td>
      <td class="text-xs-right">{{ props.item.fat }}</td>
      <td class="text-xs-right">{{ props.item.carbs }}</td>
      <td class="text-xs-right">{{ props.item.protein }}</td>
      <td class="text-xs-right">{{ props.item.sodium }}</td>
      <td class="text-xs-right">{{ props.item.calcium }}</td>
      <td class="text-xs-right">{{ props.item.iron }}</td>
    </template>
  </v-data-table>
</template>

<script>
  export default {
    data () {
      return {
        search: '',
        selected: [],
        headers: [
          {
            text: 'Dessert (100g serving)',
            align: 'left',
            sortable: false,
            value: 'name'
          },
          { text: 'Calories', value: 'calories' },
          { text: 'Fat (g)', value: 'fat' },
          { text: 'Carbs (g)', value: 'carbs' },
          { text: 'Protein (g)', value: 'protein' },
          { text: 'Sodium (mg)', value: 'sodium' },
          { text: 'Calcium (%)', value: 'calcium' },
          { text: 'Iron (%)', value: 'iron' }
        ],
        items: [...]
      }
    }
  }
</script>

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Improvement/refactoring (non-breaking change that doesn't add any feature but make things better)

Checklist:

  • The PR title is no longer than 64 characters.
  • The PR is submitted to the correct branch (master for bug fixes, dev for new features and breaking changes).
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have created a PR in the documentation with the necessary changes.

@codecov
Copy link

codecov bot commented Jan 9, 2018

Codecov Report

Merging #2973 into dev will increase coverage by 0.92%.
The diff coverage is 58.33%.

Impacted file tree graph

@@            Coverage Diff             @@
##              dev    #2973      +/-   ##
==========================================
+ Coverage   83.66%   84.58%   +0.92%     
==========================================
  Files         145      143       -2     
  Lines        3348     3348              
  Branches     1057     1028      -29     
==========================================
+ Hits         2801     2832      +31     
+ Misses        398      374      -24     
+ Partials      149      142       -7
Impacted Files Coverage Δ
src/mixins/data-iterable.js 73.33% <58.33%> (-1.47%) ⬇️
src/util/colorUtils.js 57.14% <0%> (-42.86%) ⬇️
...components/VDatePicker/mixins/date-picker-table.js 90% <0%> (-10%) ⬇️
src/directives/click-outside.js 45.45% <0%> (-6.72%) ⬇️
src/components/VDataTable/mixins/body.js 61.9% <0%> (-6.1%) ⬇️
src/components/VBtnToggle/VBtnToggle.js 95% <0%> (-5%) ⬇️
src/components/VSelect/mixins/select-watchers.js 91.11% <0%> (-2.23%) ⬇️
src/components/VTimePicker/VTimePicker.js 94.73% <0%> (-0.35%) ⬇️
src/mixins/button-group.js 93.54% <0%> (-0.21%) ⬇️
... and 64 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5e4017f...2ad2286. Read the comment docs.

Copy link
Member

@nekosaur nekosaur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution. Personally I like the functionality, what about @vuetifyjs/collaborators ? I'm not sure about the name though. Radio implies that it will be using a radio button. Perhaps single-select? Or do we have an existing name for this in another component?

Also, please add one or more tests.

@@ -275,7 +276,7 @@ export default {
)

return this.hideActions &&
!this.hasPagination
!this.hasPagination
Copy link
Member

@nekosaur nekosaur Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert this

else selected = selected.filter(i => i[keyProp] !== itemKey)
if (value) {
if (this.radioSelect) {
selected.length = 0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be simplified to selected = [item]

@Dylan-Chapman
Copy link

Faced this issue recently. Got around it by having selected be a number instead of an array, and having <v-checkbox :input-value="value" :value="props.item.id"></v-checkbox>. Would love to have a built-in solution to it.

@jim0thy
Copy link
Author

jim0thy commented Jan 9, 2018

@nekosaur single-select makes more sense given the context. I'll update the prop name.

I'm working on some tests at the moment; trying to decide whether to run them against the v-data-table component or the data-iterable mixin.

@jim0thy
Copy link
Author

jim0thy commented Jan 10, 2018

@nekosaur I'm not sure this can be tested properly using the current version of vue-test-utils. A full test requires the v-data-table component to be mounted with a scoped slot, which vue-test-utils can't currently handle.

There's an open issue here discussing the problem: vuejs/vue-test-utils#156

@jacekkarczmarczyk
Copy link
Member

We're using avoriaz now, not vue-test-utils (althouh there are plans to switch to it), and we're testing scoped slots, for example: https://github.com/vuetifyjs/vuetify/blob/dev/src/components/VDataTable/VDataTable.spec.js#L97

@johnleider
Copy link
Member

Closing due to inactivity.

@johnleider johnleider closed this Feb 2, 2018
@lock
Copy link

lock bot commented Apr 15, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. Please direct any non-bug questions to our Discord

@lock lock bot locked as resolved and limited conversation to collaborators Apr 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants