How to make a certain column editable in material-table? - reactjs

I am trying to make a certain column editable( name column ) in material table but it doesn't seem to work. the documentation aren't also that helpful. this is what I tried:
My columns array:
const headers=[
{
title:"id",
field:"id",
},
{
title:"name",
field:"name",
editable:'always', //as per documentation its 'always' by default but still..
editComponent:props=>( //trying to create custom edit component
<input
type="text"
value={props.value}
onChange={e => props.onChange(e.target.value)}/>
)
},
{
title:"email",field:"email"
}
]
my material table component:
<MaterialTable
columns={headers}
data={rows}
icons={tableIcons}
editable={{}}
options={{
search:false,
//padding:"dense",
paging:false,
// addRowPosition:"first",
// actionsColumnIndex:-1,
sorting:false,
exportButton:false,
rowStyle:{
fontSize:"10px",
padding:0,
textAlign:"center"
}
}}
/>
my output:
any help is appreciated.

You need to set the rest of the columns as "uneditable"
{
title:"id",
field:"id",
editable:'never'
}
Don't forget to add cellEditable to your material table tag
cellEditable={{
onCellEditApproved: onCellUpdate,
isCellEditable: () => true,
}}
If you have many columns and you only want a single editable column you can also use the column's field name for specifying which column is editable :
cellEditable={{
onCellEditApproved: onCellUpdate,
isCellEditable: (rowData, columnDef) =>
columnDef.field === "name",
}}

Related

React Datagrid with cards instead of columns?

We love the DataGrid for its build in sorting and filtering capabilities.
However grid based layouts are troublesome on small screen devices. So we started looking at Card based layouts. There we miss the sorting and filtering we appreciate in the DataGrid.
Now we are wondering if there is an example to use cards as UI layer for the DataGrid, where a column in the grid would become a row in the card. Cards should flow to available columns.
How can we do this?
This is a partial answer, however, there is a renderCell prop in the column configuration that accepts a function that can include a component.
So, to replace a row with a card, I might include a column that renders your components with all of the values you would otherwise express one by one in a series of columns. For instance:
const columns = [
{ field: 'id', headerName: 'ID', hide: true }, // keep this
{ field: 'myCombinedView', hide: false, flex: 1, renderCell: (props) => <Component {...props} /> },
I can imagine including a single, hidden column that represents a concatenation of the values you want to sort on. From here, specify the sort function for the Component column that uses the hidden value.
The following code sample is pulled from the DataGrid storyboard:
() => {
const columns = getColumns();
// compute a new field for purposes of sorting
columns[columns.length] = {
field: 'username',
valueGetter: (params) =>
`${params.getValue('name') || 'unknown'}_${params.getValue('age') || 'x'}`,
sortComparator: (v1, v2, cellParams1, cellParams2) => cellParams1.row.age - cellParams2.row.age,
width: 150,
};
return (
<div className="grid-container">
<XGrid
rows={getRows()}
columns={columns}
// use the field as the sort model
sortModel={[{ field: columns[columns.length - 1].field, sort: 'asc' }]}
/>
</div>
);
}
How to dynamically select/change the sort criteria is not something I can see a clear path for.

Error: filter is not defined while assigning a custom Text filed input as filter to react-bootstrap-table2-filter component

I am trying to customize Input Text field of react-bootstrap-table2-filter similar option available at https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html?selectedKind=Column%20Filter&selectedStory=Programmatically%20Text%20Filter&full=0&addons=1&stories=1&panelRight=0&addonPanel=storybook%2Factions%2Factions-panel
I am trying with below code snippet
let dataFilter;
const handleTextChange = (searchDataText) => {
console.log(searchDataText.target.value);
dataFilter(searchDataText.target.value);
};
// This is static and used to define Table Header properties
const columns = [{
dataField: 'data'
, text: ""
, headerFormatter: (column, colIndex) => (<i className="fa fa-podcast"> Name</i>)
, sort: true
, filter: textFilter({
getFilter: (filter) => {
// dataFilter was assigned once the component has been mounted.
dataFilter = filter;
}
})
, headerStyle: {backgroundColor: '#6495ed'}
, headerAlign: 'center'
, align: 'center'
}]
...
...
<Form.Control type="text" placeholder="Search POD" name="search_data_filter"
onChange={handleTextChange}/>
<BootstrapTable keyField='dataKey' data={this.state.tableRows}
columns={columns} bootstrap4={true}
defaultSorted={defaultSorted} striped
hover filter={filterFactory()}
pagination={paginationFactory()}
filter={filterFactory()}
/>
it is almost exact to the given instruction in the above link. But when I execute the code, In console output, I see typed in text is being captured correctly and when it is trying to pass to filter, error occurs ...
dataFilter is not a function
Any help suggestion, alternative approach to implement a custom Text Input as Filter Box outside of Table area?

How to show option name in Ant Design Select when using setFieldsValue

I'm using a component from Ant Design and recently I added a button to select all options. The functionality is ok but in the field it shows the option keys or ids instead of showing the option names.
My question is, is there any way to show the option names when using setFieldsValue method in a multi-select component?
I have tried pushing an object with different properties (id, name, key, value, title, etc) in this part selecteds.push(kid.id); but none of those works.
My select funtion looks like this
selectAllKids = () => {
const { kids } = this.props;
let selecteds = [];
kids.map(kid => {
selecteds.push(kid.id);
});
this.props.form.setFieldsValue({
kids: selecteds
});
};
and my component:
{getFieldDecorator("kids", {
rules: [
{
required: true,
message: "Selecciona alumnos"
}
]
})(
<Select
size="large"
mode="multiple"
placeholder="Selecciona alumnos"
loading={kidsLoading}
>
{kids.map(kid => (
<Option key={kid.id}>{kid.name}</Option>
))}
</Select>
)}
My current result is:
My expected result is:
Thanks in advance!
You should map to name and not to id:
this.props.form.setFieldsValue({
kids: kids.map(({ name }) => name)
});

Validating the TextField when using inline editable

I'm using material table with inline editing mode, and now I want to all of inline editing fields are required, if the user leaves the input is empty or something like that, material table should display error message and disable the buttons.
At the moment, I have to use the editComponent to override the input. is there anyway to I can do it by material table without overriding?
I made it work like this
{
field: 'name',
title: 'Name',
validate: (rowData) => rowData.name=== "" ? {isValid:false, helperText:'Name is required'}:true,
editComponent: props => { return <TextField value={props.value}
onChange={(event) => {props.onChange(event.target.value)}}
error={props.error} helperText={props.helperText}/>}
}

show certain column for user type

After login I store user type in the local storage. There are types of users who should see last column of react table. I'm having problem in implementing this.
<ReactTable
data={data}
filterable
defaultFilterMethod={(filter, row) =>
String(row[filter.id]) === filter.value}
columns={[
{
Header: "Name",
id: "name",
accessor: "item.name",
filterMethod: (filter, rows) =>
matchSorter(rows, filter.value, { keys: ["name"] }),
filterAll: true
},
{
Header: "Public/Rare",
id: "public_or_rare",
accessor: "item.public_or_rare",
filterMethod: (filter, rows) =>
matchSorter(rows, filter.value, { keys: ["public_or_rare"] }),
filterAll: true
},
{
//I want to show something here if user is local or foreigner
}
]}
defaultPageSize={10}
className="-striped -highlight"
/>
In top of page I retrieved user type as below,
let user_type = localStorage.getItem('user_type');
How can I render last column if user is those type user ?
Columns are defined in a table. You have this definition inlined - defined in place of usage.
You can always define this array earlier and use (pass as property) a reference to the array object.
Define columns content/config conditionally. In this case (the last column) you can define base config and conditionally extend it (array push) with additional column definition.
All these definitions can be done in render method, before JSX part ( return ( ) using normal/valnilla javascript.

Resources