Add row in Material Table on button click from outside material table in react js - material-table

How to call add row functionality of the material table when clicking the button from outside of the material table
Add new row in the material table

Import import { forwardRef } from "react";
Call
const addActionRef = React.useRef();
Include this code in the place u want ur button. I am using material ui button here
<Button
color="primary"
variant="contained"
onClick={() => addActionRef.current.click()} //The line you need
>
Add new item
</Button>
and override the action in material table
components = {
{
Action: props => {
//If isn't the add action
if (typeof props.action === typeof Function || props.action.tooltip !== 'Add') {
return <MTableAction { ...props
}
/>
} else {
return <div ref = {
addActionRef
}
onClick = {
props.action.onClick
}
/>;
}
}
}
}
If u have any question please ask.
I have used here react js with material ui.
https://github.com/mbrn/material-table/issues/2133
This link might help u.... this is from where I got the answer

Related

How to Customize just the property pane without building webpart

Does anyone know how can I show the property pane without creating webpart?
I want to show the property pane after clicking the User Management icon, which is created with extension
Taken from this repo which has some of the official samples from the SPFx extensions model and depicts a pretty close use-case to the one that you are searching, there is an element in Fluent UI called Panel.
As it is written in the documentation:
Panels are overlays that contain supplementary content and are used for complex creation, edit, or management experiences. For example, viewing details about an item in a list or editing settings.
Furthermore, scouring the repo we can see that the panel is triggered:
...
import { Panel, PanelType } from "office-ui-fabric-react/lib/Panel";
...
class GraphBot extends React.Component<IGraphBotProps, IGraphBotState> {
....
public render() {
// Be careful, the user Id is mandatory to be able to use the bot state service (i.e privateConversationData)
return (
<div className={ styles.banner }>
<ActionButton onClick= { this._login } checked={ true } iconProps={ { iconName: "Robot", className: styles.banner__chatButtonIcon } } className={ styles.banner__chatButton}>
{ strings.GraphBotButtonLabel }
</ActionButton>
<Panel
isOpen={ this.state.showPanel }
type={ PanelType.medium}
isLightDismiss={ true }
onDismiss={ () => this.setState({ showPanel: false }) }
>
{ this.state.isBotInitializing ?
....
}
</Panel>
</div>
);
}
There is an <ActionButton> with an OnClick Eventhandler to execute the below function :
private async _login() {
this.setState({
isBotInitializing :true,
showPanel: true,
});
....
The above function sets the showPanel prop to true and this prop is used in the Panel Component, where it checks when set to true to open the Panel and move on with the Business Logic of the application extension.
The same can be seen in the Fluent UI Documentation here, in the basic example.
import * as React from 'react';
import { DefaultButton } from '#fluentui/react/lib/Button';
import { Panel } from '#fluentui/react/lib/Panel';
import { useBoolean } from '#fluentui/react-hooks';
export const PanelBasicExample: React.FunctionComponent = () => {
const [isOpen, { setTrue: openPanel, setFalse: dismissPanel }] = useBoolean(false);
return (
<div>
<DefaultButton text="Open panel" onClick={openPanel} />
<Panel
headerText="Sample panel"
isOpen={isOpen}
onDismiss={dismissPanel}
// You MUST provide this prop! Otherwise screen readers will just say "button" with no label.
closeButtonAriaLabel="Close"
>
<p>Content goes here.</p>
</Panel>
</div>
);
};

use React Hook in multi files?

Senario : I have a dialog, and i use a react-hook to make it disappear ,like const[show,setShow]= useState(false) , this dialog file is a seperate file with main screen file, which contain button to show this dialog
Problem : I don't know how to show this dialog in main screen, for example, my dialog file called Mydialog.js have componet Mydialog, so i tried to put that hook show in props , Mydialog(show), but look like it not work that way, i still can't show the dialog
Question. How can i use react-hook for multi file, like i have hook in dialog file, present the dialog status ( show or not) then i can use it in mainScreen file to set show to true, then i can use that show and set to false when click button in dialog
If I understood it right you're trying to bring up a dialog when you interact with something on the main page and then close it by clicking on the X within the dialog. Would something like this work?
Main.js:
import "./styles.css";
import { useState } from "react";
import MyDialog from "./MyDialog";
export default function App() {
const [showDialog, setShowDialog] = useState(false);
const handleDialog = () => {
setShowDialog(!showDialog);
};
return (
<>
<button onClick={handleDialog}>Show Dialog</button>
Show Dialog: {showDialog?.toString()}
{showDialog && <MyDialog handleDialog={handleDialog} />}
</>
);
}
MyDialog.js:
import "./styles.css";
export default function MyDialog({ handleDialog }) {
return (
<>
<div className="popup">
<div className="popup_open">
<h1>Dialog Content</h1>
<button onClick={handleDialog}>X</button>
</div>
</div>
</>
);
}
Sandbox link if you want to test: https://codesandbox.io/s/admiring-feather-sy1gf
You can use Context to maintain state between multiple components.
const DialogContext = createContext();
const DialogProvider = ({ children }) => {
const [isDialogVisible, setDialogVisible] = useState(false);
const value = {
isDialogVisible,
setDialogVisible,
}
return <DialogContext.Provider value={value}>{children}</DialogContext.Provider>
}
const useDialog = () => {
const context = useContext(DialogContext);
return context;
}
Render the DialogProvider in one of the top-level components, for example in App.js.
// App.js
return (
<DialogProvider>
// ...
</DialogProvider>
)
Then inside of your components you can use your hook and trigger the visibility of the dialog.
MyComponentA:
const { isDialogVisible, setDialogVisible } = useDialog();
const toggleDialogVisibility = () => {
setDialogVisible(!isDialogVisible);
}
return (
<Button title="Toggle" onPress={toggleDialogVisibility} />
)
MyComponentB:
const { isDialogVisible } = useDialog();
if(isDialogVisible) {
return <Text>My Dialog</Text>
}
return null;
A very simple example of usage, here's a Snack for the above.

React-select Clear and Dropdown indicators order

Thank the author for this library, but i have one question:
How to change order of Clear and Dropdown indicators (i want: Dropdown - first, Clear - second)?
I know this indicators are in children prop, but how change order on render?
Or how I can add additional button for clear after Dropdown indicator?
ClearIndicator and DropdownIndicator both are children of the IndicatorsContainer so that would be where the updates would have to be made.
One approach would be to first render a DropdownIndicator, then loop through the IndicatorContainer's children to find the DropdownIndicator, and remove it.
import React, { Children } from "react";
import Select, { components } from "react-select";
const IndicatorsContainer = ({ children, ...props }) => {
const allowedChildren = Children.map(children, (child) => {
return (child && child.type.name !== 'DropdownIndicator') ? child : null;
});
return (
<components.IndicatorsContainer {...props}>
<components.DropdownIndicator />
{allowedChildren}
</components.IndicatorsContainer>
);
};
const CustomSelect = (props) => (
<Select components={{ IndicatorsContainer }} {...props} />
)
export default CustomSelect;
Note: I found this SO question from the react-select issues page here where the user asked to move the DropdownIndicator and IndicatorSeparator to the left of the input which is a bit more complex but has a working codesandbox solution.

firestore document id will be undefined after I update array

I have this flatlist which receive data from firestore and send as props to projectsummery.js
const ProjectList =({projects})=> {
return(
<FlatList
data={projects}
renderItem={(project,index)=>{
return(
<ProjectSummery project={project} key={project.item.id}
//keyExtractor={(item, index) =>item.id}/>
)
} }
/>
)
}
Here I have a button which which sends document id which is something like this
{project.item.id} == CSmet3tRjpjDcJ437M78
ProjectSummery.js
const ProjectSummery =(props)=> {
const {project,auth}=props
return(
<>
<View >
<Text> {project.item.title} </Text>
<Text>likes { project.item.likes.length}</Text>
<Text>{project.item.id}</Text>//document id in in firestore
<View>
<Button title='like' onPress{()=>props.likesPosts(project.item.id)}/>
</View>
</View>
const mapDispatchToProps=(dispatch)=>{
return{
likePosts:(postId)=>dispatch(likePosts(postId))
}
}
When I try to update array in firebase the first time it work but the second time the document id will be undefined. I use React-Native. Thanks for help...
export const likePosts = (postId) => {
return (dispatch,getState,{getFirebase,getFirestore})=>{
const profile=getState().firebase.profile
const authId=getState().firebase.auth.uid
const firestore=getFirestore()
firestore.collection('projects').doc(postId).update({
//this postId will be be undefined in the 2nd time
likes:firestore.FieldValue.arrayUnion({
likedAt:new Date(),
likedBy:authId,
name: profile.firstName
})
})
}}
The fist update postId == CSmet3tRjpjDcJ437M78 in the 2nd time postId will be undefined
What's happening is that when you click a like button the first time, it's working as expected so it gets the proper postId and then continues with the process you have defined. However, when you try the 2nd time it fails to fetch the postId as it's already liked.
The idea is that you'll need to either define an if statement and specify what should happen if it's already clicked and it get's clicked again (possibly storing the postId somewhere the first time and using it from there), or make an initial check that returns a specific message to the user if it's already clicked.
The issue has nothing to do with Firestore itself but with the button and the states of liked/unliked.
Here is one nice interactive example on codepen.io of a proper way of building like buttons using react. React Like Button
HTML
<div id="example"></div>
CSS
.btn-primary {
background-color: #23aa4e;
border-color: #177d37;
}
#example {
margin: 3rem;
}
.customContainer {
border: 1px solid black;
}
JS
class LikeButton extends React.Component {
constructor() {
super();
this.state = {
liked: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
liked: !this.state.liked
});
}
render() {
const text = this.state.liked ? 'liked' : 'haven\'t liked';
const label = this.state.liked ? 'Unlike' : 'Like'
return (
<div className="customContainer">
<button className="btn btn-primary" onClick={this.handleClick}>
{label}</button>
<p>
you {text} this. Click to toggle.
</p>
</div>
);
}
}
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
)

Reacting to a component being scrolled off screen in a react-native ScrollView

Currently I am using a <ScrollView /> component to handle the scrolling for my items, as I will only ever have a maximum of three items I feel this is appropriate instead of introducing a <FlatList />. This component receives a prop called collapsed and onCollapseToggle which is used to modify the collapse prop that is passed to the child. I have also experimented with the child having it's collapsed variable in state, but it seems that modifying the child's state from the parent would be near-impossible.
When scrolling through the <ScrollView /> when a component is passed up (The user scrolls down far enough that the component is no longer displayed on the screen) I want to execute a function that could potentially change the collapsed value that's passed to the item being rendered. This way if a user as expanded an item to view more information about it, and then continues scrolling down the <ScrollView /> the item would be self-collapsing, without the user having the manually close it through some form of input.
I'm not currently sure about any way to go about this, and any help would be greatly appreciated. I will provide an example of the structure that I am working with, which may help someone come up with a solution. I do not mind restructuring my components.
class ContentInformation extends React.Component {
state = { content: [ ... ] };
onCollapseToggle = (index, displayed=true) => {
const { content } = this.state;
const arr = content.slice();
const item = arr[index];
if(!item) return;
if(!displayed) {
if(!item.collapsed) {
item.collapsed = true;
}
} else {
item.collapsed = !item.collapsed;
}
arr[index] = item;
this.setState({ content: arr });
}
render() {
return (
<ScrollView>
{ this.state.content.map((content, index) => (
<Item
key={content._id}
index={index}
onCollapseToggle={this.onCollapseToggle}
{...content} />
); }
</ScrollView>
);
}
}
So basically, as you can see, I only need to figure out when the <Item /> goes off-screen so I can call onCollapseToggle(index, false) to automatically re-collapse the component if it's open.
This is an example of how you can detect when an item is offscreen when scrolling.
state = { toggleDistance: 0 }
_handleScroll({nativeEvent: {contentOffset: {y}}}) {
const {toggleDistance} = this.state;
if (y >= toggleDistance) {
// The item is offscreen
}
}
render() {
<ScrollView
onScroll={this._handleScroll.bind(this)}>
<Item
onLayout={({nativeEvent: {layout: {y, height}}}) => this.setState({toggleDistance: (y + height)})}/>
...
</ScrollView>
}
Seems to me you need a FlatList or a ListView and ScrollView simply doesn't support this use case.
The hint is in the ScrollView description:
FlatList is also handy if you want ... any number of other features it supports out of the box.
I solve the problem improving the answer from ivillamil with some adjusts:
const [toggleDistance, setToggleDistance] = useState(0);
const [showBottom, setShowBottom] = useState(false);
const onScrollMoveFooter = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
const currentOffset = event.nativeEvent.contentOffset.y;
if (event.nativeEvent.layoutMeasurement.height - currentOffset <
toggleDistance) {
setShowBottom(true);
} else {
setShowBottom(false);
}
};
And in the another component:
<Component
onLayout={({
nativeEvent: {
layout: { y, height },
},
}) => setToggleDistance(y + height)}
/>
and so I can conditionally hide what I wanted:
{showBottom && (<AnotherComponent/>)}