React with Material UI Table Pagination show all entries - javascript

I have a react data table where I recently added pagination for when you have many entries. I wanted the option to show all entries in the table by selecting "all" in the rowsPerPageOptions dropdown menu. So far I managed to get the count of all entries to show up in the menu.
What I need now is to label the entries.length object with the string "all" and get that to show up in the menu. Is that possible?
When I try something like all.push({label: this.state.entries.length}); I get the error:
Objects are not valid as a React child (found: object with keys {label}). If you meant to render a collection of children, use an array instead.
That made me think that I can not use arrays with keys for the menu, so I have to show that value in a different way.
Code:
Edit: Moved the all variable into the render function after morteza ataiy commented and pointed out an error.
render() {
return (
let all = [5,10,25,50,(this.state.entries.length)];
<div>
<Table>
</Table>
</div>
<TablePagination
component="div"
count={this.state.entries.length}
rowsPerPage={this.state.rowsPerPage}
page={this.state.page}
backIconButtonProps={{
'aria-label': 'Previous Page',
}}
nextIconButtonProps={{
'aria-label': 'Next Page',
}}
onChangePage={this.handleChangePage}
onChangeRowsPerPage={this.handleChangeRowsPerPage}
labelRowsPerPage="Reihen pro Seite:"
rowsPerPageOptions={all}
);
}
Image: The last entry is what I want to change
Please keep in mind that I am new to React and JavaScript, thanks in advance!

You can use label . plz refer the code
<TablePagination rowsPerPageOptions={[10, 50, { value: -1, label: 'All' }]} />
You can pass -1 to the backend and write query with respect to this.

just use it in render method:
render() {
let all = [5,10,25,50,(this.state.entries.length)];
return (
<div>
<Table>
</Table>
</div>
<TablePagination
component="div"
count={this.state.entries.length}
rowsPerPage={this.state.rowsPerPage}
page={this.state.page}
backIconButtonProps={{
'aria-label': 'Previous Page',
}}
nextIconButtonProps={{
'aria-label': 'Next Page',
}}
onChangePage={this.handleChangePage}
onChangeRowsPerPage={this.handleChangeRowsPerPage}
labelRowsPerPage="Reihen pro Seite:"
rowsPerPageOptions={all}
}

Related

Attribute is not saved in Gutenberg

I am trying to create a custom block for Wordpress Gutenberg.
I have the following attributes:
"icon": {
"type": "object",
"source": "html",
"selector": ".jig_defbox-icon"
},
"color": {
"type": "string",
"default": "#919191"
}
In my EditJS I try to store values from a color-picker and a radiogroup into these attributes.
const [ toggled, setToggled ] = useState( );
return(
<InspectorControls>
<ColorPalette
colors={[
{name: 'lightgray', color: '#d8d8d8'},
{name: 'darkgray', color: '#919191'},
{name: 'red', color: '#dc1a22'}
]}
disableCustomColors={true}
onChange={(value) => {props.setAttributes({color: value});}}
value={props.attributes.color}
clearable={false}
/>
<RadioGroup
onChange={ (value) => {setToggled(value);props.setAttributes({icon: value});} }
checked={props.attributes.icon}
>
{
str_array.map(
item => ( <Radio value={item}><Icon icon={icon_getter(item);}/></Radio>)
)
}
</RadioGroup>
</InspectorControls>
)
In my SaveJS I try to render my markup according to these attributes:
const {attributes} = props
<div style={{"fill": attributes.color}}>
<Icon icon={icon_getter(attributes.icon)}/>
</div>
The goal is to render an svg-icon according to the selection on my radiogroup.
Issue 1: Every new edit-session in backend, the selection of my radiogroup is gone, even with useState (tried without useState first)
Issue 2: Every new edit-session, a console error is logged, that says that the post-body markup does not match the markup returned by the save function, because the save-markup does not contain the icon attribute content
As far as I was able to enclose the problem, the icon attribute is not correctly saved. I tried to save the "key" for the icon as a string and object. If I log the value in the save function, it is empty, while the selected color works as expected, both in frontend and backend.
I was able to fix it via rethinking my concept of fetching the icon.
Apparently, Gutenberg tried to store the code of the icon into the database, but not the key. When loading the backend editor, the icon_getter function received a null value, therefore, the difference between post body and save function code.
I changed my editJS:
<RadioGroup
onChange={ (value) => {props.setAttributes({icon: value});} }
checked={props.attributes.icon}
>
{
my_icons_as_list.map(
item => ( <Radio value={item}><Icon icon={my_icons[props.attributes.icon];}/></Radio>)
)
}
</RadioGroup>
and my saveJS:
<Icon icon={ my_icons[ attributes.icon ] } />

How to exclude certain item in a map with a certain condition?

I'm developing a menu page, where users can see the menu's items based on their roles.
Currently, I have 3 pages: Bulletin Board, Info Hub and Settings
So naturally, I have 3 roles: Admin Role (can access all 3 of the pages), Bulletin Board (can only access Bulletin Board), Info Hub (can only access Info Hub)
So users can have a different roles, for example, if they have Bulletin Board and Info Hub, then they can access both of them, but not the Settings page (only "Admin Role" can see Settings), so I want to hide the Settings in this menu that I've already developed and rendered using map.
Or if the user has all 3 roles including Admin Role, then they can see everything as well.
I'm taking the loginList prop from an API and passing it into the AllAppsCentre.js to determine which menu items to show, but I just can't figure out the logic to do a filter or indexOf at the map.
In the codesandbox that I've created, the user has all 3 roles.
AllAppsCentre.js(map function to display the menu items)
useEffect(() => {
const loginListFromParent = loginList;
const showAll = loginListFromParent.some(
(item) =>
item.permissionName.includes("Admin Role") &&
item.permissionType.includes("view")
);
const showBulletin = loginListFromParent.some(
(item) =>
item.permissionName.includes("Bulletin Board") &&
item.permissionType.includes("view")
);
const showInfoHub = loginListFromParent.some(
(item) =>
item.permissionName.includes("Info Hub") &&
item.permissionType.includes("view")
);
if (loginListFromParent) {
setShowAll(showAll);
setShowBulletin(showBulletin);
setShowInfoHub(showInfoHub);
}
}, [loginList]);
return (
{AllAppsCentreData
.filter((item) => {
.map((item, index) => {
return (
<Col key={index} xs={6} md={3}>
<div className={item.className}>
<Link to={item.path}>
{item.icon}
<Row>
<span className='apps-title'>
{item.title}
</span>
</Row>
</Link>
</div>
</Col>
)
})}
)
AllAppsCentreData.js
import * as IoIcons from 'react-icons/io'
import * as MdIcons from 'react-icons/md'
export const AllAppsCentreData = [
{
title: 'Bulletin Board',
path: '/bulletinboard',
icon: <IoIcons.IoIosPaper size={80} />,
className: 'row text-center apps-centre-icon'
},
{
title: 'Info Hub',
path: '/infohub',
icon: <MdIcons.MdDeviceHub size={80} />,
className: 'row text-center apps-centre-icon'
},
{
title: 'Settings',
path: '/settings',
icon: <IoIcons.IoMdSettings size={80} />,
className: 'row text-center apps-centre-icon'
},
]
I've been trying to figure out how to deal with this but I just couldn't think of a solution, if all else fails, I might just remove the map method and just copy and paste my AllAppsCentreData's items and move it directly into the AllAppsCentre page instead so I can do ternary operations at the menu items.
If there is any better way to do this menu with the role-based display, feel free to let me know as I also want to learn the optimal way to do something like this.
To start off, there is no variable in your code that is responsible for holding current user's permissions (or I can't see one). So I made it up:
const currentUsersPermissions = useGetPermissions() // get users permissions
// the above can be "admin", "bulletin" or "info-hub"
Then, you need to first filter your array and then map it (currently, you are using map inside of filter). To do it easier and correctly, you could add a property called requiredPermission (or something simillar) to your AllAppsCentreData objects:
{
title: 'Bulletin Board',
path: '/bulletinboard',
icon: <IoIcons.IoIosPaper size={80} />,
className: 'row text-center apps-centre-icon',
requiredPermission: "bulletin" // and info-hub for Info Hub
},
Then, while rendering and mapping, you can do it like this:
return (
{AllAppsCentreData
.filter(
// below, you return true if permission is admin because he can see everything
// and true or false depending if permissions are other than that but
// the same as required by AllAppsCentreData array objects
(item) => currentUsersPermissions === "admin" ? true : currentUsersPermissions === item.requiredPermission
).map((item, index) => {
return (
<Col key={index} xs={6} md={3}>
<div className={item.className}>
<Link to={item.path}>
{item.icon}
<Row>
<span className='apps-title'>
{item.title}
</span>
</Row>
</Link>
</div>
</Col>
)
)
So, to sum up:
I have created a variable to hold current users' permission
I have added a property to each AllAppsCentreData's objects, which contains info about permission required to show it
I have filtered the array right before mapping it and rendering, so it contains only the data I want to render
Also, I think you are lost in using filter method, so perhaps read this and try doing some easier excercises to get a feeling how it works: MDN on Array.filter method. The thing you need to pay attention is that you pass a function into filter, and this function should return true or false depending on whether you want your item included in the output array.

Loading a name based on Value from Parent Component Dynamically

Have a Parent Component which certain props such as name, queryValue and image to my Child Component which is a Custom Dropdown where as of now i am displaying the names based on a condition check for the default display in the dropdown, but now more data will be shown along with flags. I need to show the name based on the value from the parent .
Parent.jsx
<SelectCountry
options={[
{
name: 'English (USA)',
queryValue: 'en',
flagIcon: USA,
},
{
name: 'Bahasa Indonesia',
queryValue: 'id',
flagIcon: ID,
},
]}
value={localStorage.getItem('locale')} />
SelectCountry.jsx
<div className={`${baseClassName}__selected-flag-container`}>
<img
src={require(value === "en" ? '../../assets/USA.svg' : '../../assets/indonesia.svg')}
alt='desc'
/>
{value === "en" ? options[0].name : options[1].name}
</div>
//COde for the Custom DropDown will be here
As above, HAve put the condition check and its working since there were only two languages, now when more languages are added, not sure how to pick the name and also setting the src in img tag dynamically.
You are doing all in a bit of wrong way your Parent.jsx is the container component so it should hold all your logic so why not pass the appropriate data.
<SelectCountry
options={[
{
name: 'English (USA)',
queryValue: 'en',
flagIcon: USA,
src: '../../assets/USA.svg'
},
{
name: 'Bahasa Indonesia',
queryValue: 'id',
flagIcon: ID,
src: '../../assets/indonesia.svg'
},
]}
value={localStorage.getItem('locale')}
/>
& in your presentation component SelectCountry.jsx you just present.
const { options } = require('joi');
options.map((option) => {
<div className={`${baseClassName}__selected-flag-container`}>
<img src={option.src} alt='desc' />
{option.name}
</div>;
});
I haven't tested so you might need to adjust the code. Dan has some fantastic free courses on Redux where he teaches more about container & presentation component you can check it out here https://egghead.io/instructors/dan-abramov. Hope this will help you 🙂️🙂️

react tips not appearing?

I am working on a component right now that is a mapped stack of divs. Each one should have a tooltip but for the life of me I can't get the tooltip to appear
class App extends Component {
constructor() {
super();
this.state = {
options: [
{
id: '1',
label: 'Industrial Truck and Tractor Operators',
value: '53-7051',
tooltip_text: 'Operate industrial trucks or tractors equipped to move materials around a warehouse, storage yard, factory, construction site, or similar location. Excludes “Logging Equipment Operators" (45-4022).',
},
{
id: '2',
label: 'Order Clerks',
value: '43-4151',
tooltip_text: 'Receive and process incoming orders for materials, merchandise, classified ads, or services such as repairs, installations, or rental of facilities. Generally receives orders via mail, phone, fax, or other electronic means. Duties include informing customers of receipt, prices, shipping dates, and delays; preparing contracts; and handling complaints. Excludes "Dispatchers, Except Police, Fire, and Ambulance" (43-5032) who both dispatch and take orders for services.',
},
],
value: null,
className: '',
selectedClassName: '',
loading_State: true, loads
childrenCount: 0
};
this.setProps = this.setProps.bind(this);
}
setProps(newProps) { //this is going to update the state
this.setState(newProps);
}
render() {
return (
<div>
<DashControlledContainer
setProps={this.setProps}
options = {this.state.options}
value = {this.state.value}
styles = {this.state.styles}
className = {this.state.className}
selectedClassName = {this.state.selectedClassName}
loading_State = {this.state.loading_State}
childrenCount = {this.state.childrenCount}
/>
</div>
)
}
}
export default App;
//the component being returned with the tooltip
render(){
return (
<div style={this.props.styles}>
{this.props.options.map(option => (
<div key = {option} id={option.id} style={option.style}
onClick = {e=>{ //updates the props with the clicked targets value if setProps is accessible
if(this.props.setProps){
this.props.setProps({value: e.target.value})
}else{
this.setState({value:e.target.value})
}
}}
>
<span id={option.id}> {option.label} </span>
<UncontrolledTooltip placement="right" target={option}>
{option.tooltip_text}
</UncontrolledTooltip>
</div>
))}
</div>
);
}
I'm not sure where to set my target for the tooltip maybe thats the issue? I haven't been able to find many resources online. Any help would be appreciated.
I think you should provide id as a target to your UncontrolledTooltip,
<UncontrolledTooltip placement="right" target={option.id}> //set id of span as a target here
hello
</UncontrolledTooltip>
I was able to figure it out, including a string in my id fixed it for some reason?
i made my div contain id={"option"+option.id}
then I referenced it like so:
<UncontrolledTooltip placement="right" target={"option"+option.id}>
{option.tooltip_text}
</UncontrolledTooltip>

Can I specify a Divider or Header in Semantic UI React's options array for the dropdown component?

I am working with ReactJS and using SemanticUI for ReactJS to style the front end,
Is it possible to specify a header or divider from within the options array of objects for a dropdown component?
I get the impression from the documentation that this is not supported yet.
I solved this by changing to object in the options array to have more properties (which allow you to customise the content):
{
text: "YouGov Filters",
value: "yougov-header",
content: <Header content="YouGov Filters" color="teal" size="small" />,
disabled: true
},
It's probably not the ideal way to achieve what I want because I have to set disabled to true (I don't want it to be a selectable option) which means it adopts the greyed out 'disabled' style. I tried to counter this by specifying a color for the header which resulted in the disabled style being applied over the teal colour, not perfect but it will do for now.
Another workaround is to do it by map array:
const options = [
{
text: "note",
icon: 'sticky note outline',
description: 'test',
},
{
divider: true
},
{
text: "task",
icon: 'calendar check outline',
description: 'test',
},
];
return (
<Dropdown className='multicontent__button' text='add new' button>
<Dropdown.Menu>
<Dropdown.Header icon='tags' content='Tag Label' />
{options.map((option, i) => {
if (option.divider === true) return (<Dropdown.Divider key={i}/>);
return (
<Dropdown.Item
key={i}
text={option.text}
icon={option.icon}
description={option.description}
action={option.action}
onClick={this.handleOption}
/>
);
})}
</Dropdown.Menu>
</Dropdown>
);
Mr B's solution is genius. And it can be cleaner with a little modification of his:
function FragmentWithoutWarning({key, children}) {
// to get rid of the warning:
// "React.Fragment can only have `key` and `children` props."
return <React.Fragment key={key}>{children}</React.Fragment>;
}
// then just:
{
as: FragmentWithoutWarning,
content: <Header content="YouGov Filters" color="teal" size="small" />
}
Since <React.Fragment /> is not able to capture any event, you even don't have to disable the item.

Categories

Resources