In material table, there is an option to hide/disable action buttons conditionally. Is there a similar option to hide/disable Add button present at the top of the table.
Screenshot
---REVISED ANSWER---
You will have to override the Toolbar component using the components prop for the table. Right below your EditField component, add another component as follows:
Toolbar: props => {
const newProps = { ...props, actions: [] };
return <MTableToolbar {...newProps} />
}
This will do the job.
You can remove the code inside the editable prop corresponding to onRowAdd i.e. lines 53 through 58 of the sandbox link you provided. That will automatically remove the add button completely. Do note that users won't be able to add a row anymore though.
Related
My application is mixed with vanilla JS and React components, and I have a component that I would like to rerender by changing the props from outside the react component. How would I accomplish this? And maybe I need to be using "state" instead?
This component is only shown when a user clicks a dropdown link in a list of items. Because the list can be quite long, I am trying to be efficient with creating only one component and then changing the props (rerendering) depending on which item in the list if clicked.
This is the code the initially creates the component with references to the "root" and "element"
// Render AdjustDateFormulaComponent
let rootContainer = document.getElementById('rc_dateFormulaComponent');
if (rootContainer) {
this.dataFormulaWidgetRoot = createRoot(rootContainer);
this.dataFormulaWidgetElement = createElement(AdjustDateFormulaComponent, {
id: null,
entityType: 'taskTemplateEntry',
onSave: _this._dateFormulaUpdated, // callback method
});
this.dataFormulaWidgetRoot.render(this.dataFormulaWidgetElement);
}
When item is clicked, rerender by changing props (specifically the "id" field) and show/move in the appropriate dropdown div
_this.$widgetDiv.find('.dueDateAdjustDropdown').on('show.bs.dropdown', function () {
// Change props/rerender here with correct id
this.dataFormulaWidgetElement.props = { id: 124 }; // <--- THIS DOESNT WORK OBVIOUSLY
// When dropdown shown, move react component into dropdown div
$(document.getElementById('rc_dateFormulaComponent'))
.detach()
.appendTo($(this).find('.dropdownContent'));
});
Many thanks in advance.
I have a question. I have these code snippets implemented in my class component and while it is working for the most part, I need to actual display the most recent rendered component on top of the list instead of appended to the bottom of the list. How can I do that easily?
Code snippets:
state = {
formCount: 0
}
//click event for button
onAddClicked = () => {
this.setState({formCount: this.state.formCount + 1});
}
//render components based on count
{ [...Array(this.state.formCount)].map((_, i) => <Form key={i}/>)}
So I have form count in state and on clicking on a button, it will increment the count and then depending on the count, it will render the same component whenever I click on the button.
However, right now it is adding the new components to the bottom instead of the top, how do I render the new component that gets rendered when clicking the button to the top of the list instead?
You could use .reverse() along with .keys():
[...Array(this.state.formCount).keys()].reverse().map((i) => <Form key={i}/>)
So you want to render the components in reverse order? With the most "recent" ones at the top? A simple way would be to .reverse() the array of components
Material UI's DataGrid's API shows how to add a sort icon when the direction is ascending and another one when the sort direction is descending. These default to the arrow up and arrow down icons and can easily be changed through props. My design requires to also have an icon when the sorting direction is null (i.e., the user hasn't clicked on that column header yet but the up-and-down arrows indicate that the column is sortable).
I have tried a couple of solutions but I'm not satisfied with any of them. I tried using renderHeader inside the ColDef to implement the icons when SortModel changes but it doesn't look good enough, plus the DataGrid layout gets messed up for some reason when SortModel is changed.
Is there a better way to simply add a sortable icon next to the header titles when no sorting direction is defined?
Material-UI DataGrid does not have an option to set the icon in no-sort state. To do that, you need to get your hands dirty.
I tried using renderHeader inside the ColDef to implement the icons when SortModel changes but it doesn't look good enough
In order to replicate the built-in sort icon, you need to know which components get rendered in the column header when in sorting mode. Having a look at the DataGrid source code, you can see that:
In GridColumnHeaderItem: If you don't provide renderHeader, it will render GridColumnHeaderTitle instead. So we need to use that component to render the header.
In GridColumnHeaderSortIcon: This component is used to render the sort icon, the icon is wrapped inside an IconButton with a small size that itself is wrapped inside a container. Make sure to copy that code when you render your own header icon.
Putting it together, we'll have something like below:
import { GridColumnHeaderTitle } from "#material-ui/x-grid";
{
field: "firstName",
headerName: "First name",
width: 130,
renderHeader: (params) => {
const { field, api, colDef } = params;
const sort = api.state.sorting.sortModel.filter(
(s) => s.field === field
)?.[0]?.sort;
const isSorting = Boolean(sort);
return (
<>
<GridColumnHeaderTitle
label={colDef.headerName || colDef.field}
description={colDef.description}
columnWidth={colDef.width}
/>
{!isSorting && (
<div className="MuiDataGrid-iconButtonContainer">
<IconButton size="small">
<ClearIcon className="MuiDataGrid-sortIcon" />
</IconButton>
</div>
)}
</>
);
}
},
Live Demo
My aim is to delete the button, I have just clicked. I understand there may be numerous ways such as creating a deleteButton component, and setting the state appropriately.
However, my return function in the main App component will also render another button (this I can do), but I think this may add to the complexity.
I'm currently struggling to pin-point the ideal solution, so please help.
Okay, so I've managed to solve my question, although I'm sure there's other ways too.
To further clarify...
I had a form which I wished to render, when clicking on a 'Create' Button.
At the same time, I wished to remove the 'Create' button, once clicked.
The end result is to only display the form and nest a new button in the return function.
1) Set the initial state of the form to false:
this.state = {
displayForm: false,
}
2) Then use setState within the displayForm function to allow for the change in state, once the button is clicked:
displayForm(){
this.setState({
displayForm: !this.state.displayForm {/* true */}
})
}
3) set a style object within the render function, such as:
render() {
const btnStyle = {
display: 'block',
} ...
4) Use an IF statement to change the display style of the button if the form has been rendered
if(this.state.displayForm){
btnStyle.display = 'none'
}
5) Now, within the return function, use your JSX tags appropriately and call the function onClick, as well as the style to be applied.
<Button
style={btnStyle}
onClick={() => {
this.displayForm()
}}>Create</button>
{this.state.displayForm && ([
<Form />,
<br />,
<Button>Add Schema</Button>,
])}
NOTE: the < Form /> and < Button /> components have been imported and added here.
So, once the 'Create' button has been clicked, the form displays (true), and thereby the 'Create' button disappears from the Virtual DOM. I've also nested another (new) button as intended, underneath the form.
Please take a look at my code for Dropdown,
I'm using the semantic ui react dropdown on an EditProfile component. I have pasted a sample code here, https://codesandbox.io/s/m4288nx4z8, but I could not get it to work because I'm not very familiar with functional components in React, I've always used Class component. But you can check the full code for the whole component below in the github gist.
https://gist.github.com/mayordwells/b0cbb7b63af85269091f1f98296fd9bb
Please, I need help on inserting values from multiple select options of a Dropdown into the Database and also a way to display that back upon viewing the profile edit page again.
I'm using semantic-ui-react in react + rails app.
Also when I insert a value using a normal drop down without multiple select, the value gets persisted into the database.
<Dropdown
placeholder='Select Country'
fluid
search
selection
options={countryOptions}
name='country'
defaultValue={this.state.extraInfo.country}
onChange={(e) => this.handleExtraInfoChange('country', e)}
/>
This code handles change for the dropdown elements.
handleExtraInfoChange = (name, event) => {
let value;
if (event.target.value !== undefined) {
value = event.target.value;
} else {
value = event.target.textContent;
}
let newExtraInfo = Object.assign(this.state.extraInfo, { [name]: value })
this.setState({ extraInfo: newExtraInfo});
}
But when I visit the page again, I get a white blank in the input box. Here's a screen pic for that. When I comment out the defaultValue or value property(i have tried with defaultValue and value), the white blank disappears, but the value picked by a user is also not seen.
Please advice what is a possible solution to this misbehavior? And what is the best way to insert multiple values into the Database?
Thanks in advance for your time.
A functional component does not have state, it's used for composition; you want to store state, so you either have to create a Component class or you need an external state container like redux.