• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gregnb / mui-datatables / #1869

17 Dec 2018 07:23PM UTC coverage: 78.18% (+0.06%) from 78.118%
#1869

push

gregnb
Fix issue with sort not taking into account on re-render (#316)

271 of 377 branches covered (71.88%)

Branch coverage included in aggregate %.

5 of 9 new or added lines in 1 file covered. (55.56%)

42 existing lines in 3 files now uncovered.

442 of 535 relevant lines covered (82.62%)

42.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.0
/src/MUIDataTableFilter.js
1
import React from "react";
2
import PropTypes from "prop-types";
3
import classNames from "classnames";
4
import Typography from "@material-ui/core/Typography";
5
import FormControl from "@material-ui/core/FormControl";
6
import FormGroup from "@material-ui/core/FormGroup";
7
import FormControlLabel from "@material-ui/core/FormControlLabel";
8
import InputLabel from "@material-ui/core/InputLabel";
9
import Input from "@material-ui/core/Input";
10
import MenuItem from "@material-ui/core/MenuItem";
11
import Select from "@material-ui/core/Select";
12
import Checkbox from "@material-ui/core/Checkbox";
13
import ListItemText from "@material-ui/core/ListItemText";
14
import { withStyles } from "@material-ui/core/styles";
15

16
export const defaultFilterStyles = {
1✔
17
  root: {
18
    padding: "16px 24px 16px 24px",
19
    fontFamily: "Roboto",
20
  },
21
  header: {
22
    flex: "0 0 auto",
23
    marginBottom: "16px",
24
    width: "100%",
25
    display: "flex",
26
    justifyContent: "space-between",
27
  },
28
  title: {
29
    display: "inline-block",
30
    marginLeft: "7px",
31
    color: "#424242",
32
    fontSize: "14px",
33
    fontWeight: 500,
34
  },
35
  noMargin: {
36
    marginLeft: "0px",
37
  },
38
  reset: {
39
    alignSelf: "left",
40
  },
41
  resetLink: {
42
    color: "#027cb5",
43
    backgroundColor: "#FFF",
44
    display: "inline-block",
45
    marginLeft: "24px",
46
    fontSize: "12px",
47
    cursor: "pointer",
48
    border: "none",
49
    "&:hover": {
50
      color: "#FF0000",
51
    },
52
  },
53
  filtersSelected: {
54
    alignSelf: "right",
55
  },
56
  /* checkbox */
57
  checkboxList: {
58
    flex: "1 1 100%",
59
    display: "inline-flex",
60
    marginRight: "24px",
61
  },
62
  checkboxListTitle: {
63
    marginLeft: "7px",
64
    marginBottom: "8px",
65
    fontSize: "14px",
66
    color: "#424242",
67
    textAlign: "left",
68
    fontWeight: 500,
69
  },
70
  checkboxFormGroup: {
71
    marginTop: "8px",
72
  },
73
  checkboxFormControl: {
74
    margin: "0px",
75
  },
76
  checkboxFormControlLabel: {
77
    fontSize: "15px",
78
    marginLeft: "8px",
79
    color: "#4a4a4a",
80
  },
81
  checkboxIcon: {
82
    //color: "#027cb5",
83
    width: "32px",
84
    height: "32px",
85
  },
86
  checkbox: {
87
    "&$checked": {
88
      color: "#027cB5",
89
    },
90
  },
91
  checked: {},
92
  /* selects */
93
  selectRoot: {
94
    display: "flex",
95
    marginTop: "16px",
96
    flexDirection: "row",
97
    flexWrap: "wrap",
98
    width: "100%",
99
    height: "80%",
100
    justifyContent: "space-between",
101
  },
102
  selectFormControl: {
103
    flex: "1 1 calc(50% - 24px)",
104
    marginRight: "24px",
105
    marginBottom: "24px",
106
  },
107
};
108

109
class MUIDataTableFilter extends React.Component {
110
  static propTypes = {
111
    /** Data used to populate filter dropdown/checkbox */
112
    filterData: PropTypes.array.isRequired,
113
    /** Data selected to be filtered against dropdown/checkbox */
114
    filterList: PropTypes.array.isRequired,
115
    /** Options used to describe table */
116
    options: PropTypes.object.isRequired,
117
    /** Callback to trigger filter update */
118
    onFilterUpdate: PropTypes.func,
119
    /** Callback to trigger filter reset */
120
    onFilterRest: PropTypes.func,
121
    /** Extend the style applied to components */
122
    classes: PropTypes.object,
123
  };
124

125
  handleCheckboxChange = (index, column) => {
126
    this.props.onFilterUpdate(index, column, "checkbox");
1✔
127
  };
128

129
  handleDropdownChange = (event, index) => {
130
    const value = event.target.value === "All" ? "" : event.target.value;
2✔
131
    this.props.onFilterUpdate(index, value, "dropdown");
2✔
132
  };
133

134
  handleMultiselectChange = (index, column) => {
135
    this.props.onFilterUpdate(index, column, "multiselect");
×
136
  };
137

138
  renderCheckbox(columns) {
139
    const { classes, filterData, filterList } = this.props;
3✔
140

141
    return columns.map((column, index) =>
3✔
142
      column.filter ? (
12✔
143
        <div className={classes.checkboxList} key={index}>
144
          <FormGroup>
145
            <Typography variant="caption" className={classes.checkboxListTitle}>
146
              {column.name}
147
            </Typography>
148
            {filterData[index].map((filterColumn, filterIndex) => (
149
              <FormControlLabel
26✔
150
                key={filterIndex}
151
                classes={{
152
                  root: classes.checkboxFormControl,
153
                  label: classes.checkboxFormControlLabel,
154
                }}
155
                control={
156
                  <Checkbox
157
                    className={classes.checkboxIcon}
158
                    onChange={this.handleCheckboxChange.bind(null, index, filterColumn)}
159
                    checked={filterList[index].indexOf(filterColumn) >= 0 ? true : false}
26!
160
                    classes={{
161
                      root: classes.checkbox,
162
                      checked: classes.checked,
163
                    }}
164
                    value={filterColumn !== null ? filterColumn.toString() : ""}
26!
165
                  />
166
                }
167
                label={filterColumn}
168
              />
169
            ))}
170
          </FormGroup>
171
        </div>
172
      ) : (
173
        false
174
      ),
175
    );
176
  }
177

178
  renderSelect(columns) {
179
    const { classes, filterData, filterList, options } = this.props;
3✔
180
    const textLabels = options.textLabels.filter;
3✔
181

182
    return (
3✔
183
      <div className={classes.selectRoot}>
184
        {columns.map((column, index) =>
185
          column.filter ? (
12✔
186
            <FormControl className={classes.selectFormControl} key={index}>
187
              <InputLabel htmlFor={column.name}>{column.name}</InputLabel>
188
              <Select
189
                value={filterList[index].toString() || textLabels.all}
15✔
190
                name={column.name}
UNCOV
191
                onChange={event => this.handleDropdownChange(event, index)}
×
192
                input={<Input name={column.name} id={column.name} />}>
193
                <MenuItem value={textLabels.all} key={0}>
194
                  {textLabels.all}
195
                </MenuItem>
196
                {filterData[index].map((filterColumn, filterIndex) => (
197
                  <MenuItem value={filterColumn} key={filterIndex + 1}>
26✔
198
                    {filterColumn !== null ? filterColumn.toString() : ""}
26!
199
                  </MenuItem>
200
                ))}
201
              </Select>
202
            </FormControl>
203
          ) : (
204
            false
205
          ),
206
        )}
207
      </div>
208
    );
209
  }
210

211
  renderMultiselect(columns) {
212
    const { classes, filterData, filterList, options } = this.props;
1✔
213

214
    return (
1✔
215
      <div className={classes.selectRoot}>
216
        {columns.map((column, index) =>
217
          column.filter ? (
4!
218
            <FormControl className={classes.selectFormControl} key={index}>
219
              <InputLabel htmlFor={column.name}>{column.name}</InputLabel>
220
              <Select
221
                multiple
222
                value={filterList[index] || []}
4!
223
                renderValue={selected => selected.join(", ")}
1✔
224
                name={column.name}
UNCOV
225
                onChange={event => this.handleMultiselectChange(index, event.target.value)}
×
226
                input={<Input name={column.name} id={column.name} />}>
227
                {filterData[index].map((filterColumn, filterIndex) => (
228
                  <MenuItem value={filterColumn} key={filterIndex + 1}>
13✔
229
                    <Checkbox
230
                      checked={filterList[index].indexOf(filterColumn) >= 0 ? true : false}
13✔
231
                      value={filterColumn.toString()}
232
                      className={classes.checkboxIcon}
233
                      classes={{
234
                        root: classes.checkbox,
235
                        checked: classes.checked,
236
                      }}
237
                    />
238
                    <ListItemText primary={filterColumn} />
239
                  </MenuItem>
240
                ))}
241
              </Select>
242
            </FormControl>
243
          ) : (
244
            false
245
          ),
246
        )}
247
      </div>
248
    );
249
  }
250

251
  render() {
252
    const { classes, columns, options, onFilterReset } = this.props;
7✔
253
    const textLabels = options.textLabels.filter;
7✔
254

255
    return (
7✔
256
      <div className={classes.root}>
257
        <div className={classes.header}>
258
          <div className={classes.reset}>
259
            <Typography
260
              variant="caption"
261
              className={classNames({
262
                [classes.title]: true,
263
                [classes.noMargin]: options.filterType !== "checkbox" ? true : false,
7✔
264
              })}>
265
              {textLabels.title}
266
            </Typography>
267
            <button className={classes.resetLink} tabIndex={0} aria-label={textLabels.reset} onClick={onFilterReset}>
268
              {textLabels.reset}
269
            </button>
270
          </div>
271
          <div className={classes.filtersSelected} />
272
        </div>
273
        {options.filterType === "checkbox"
7✔
274
          ? this.renderCheckbox(columns)
275
          : options.filterType === "multiselect"
4✔
276
          ? this.renderMultiselect(columns)
277
          : this.renderSelect(columns)}
278
      </div>
279
    );
280
  }
281
}
282

283
export default withStyles(defaultFilterStyles, { name: "MUIDataTableFilter" })(MUIDataTableFilter);
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc