material table onRowClick and actions button click overlapping - material-table

<MaterialTable
onRowClick={() => openRightDrawer()}
actions={[
{
icon:"Check",
tooltip:"Activate",
onClick: () => activateAccount()
}
]}
components={{
Action: props => <Button onClick={() => props.action.onClick()}>Activate</Button>
}}
/>
when I click a button, onRowClick event also triggering is there any workaround for this?

thanks #mbrn, got it working https://github.com/mbrn/material-table/issues/1362
<MaterialTable
onRowClick={() => openRightDrawer()}
actions={[
{
icon:"Check",
tooltip:"Activate",
onClick: () => activateAccount()
}
]}
components={{
Action: props => <Button onClick={(event) => {
props.action.onClick();
event.stopPropagation();
}
}>Activate</Button>
}}
/>

Related

Hi can anyone explain how to test formik with jest in react native

Hi I created form builder with formik for react native. I'm using jest for testing, but when I test onSubmit is not calling can anyone please explain how to test.
function FormBuilder({data, onSubmit, initialValues, navigation}) {
const formik = useFormik({
enableReinitialize: true,
initialValues: initialValues,
onSubmit: data => {
onSubmit(data);
},
});
return (
<View>
{data.map((item,index) => {
switch (item.type) {
case 'text':
return (
<TextBox
key={index}
onChangeText={formik.handleChange(item.name)}
onBlur={formik.handleBlur(item.name)}
value={formik.values[item.name]}
label={item.name}
touched={formik.touched}
errors={formik.errors}
required={
!!item.validators &&
item.validators.find(valid => valid.type === 'required')
}
{...item}
/>
);
case 'button':
return (
<CustomButton key={index} testID={item.testID} title=
{item.name} onPress={formik.handleSubmit} />
);
}
})}
</View>
)
}
and I call this component like this in my screen. Can anyone explain how can we write test Integration test for this
<FormBuilder
initialValues={initialValues}
data={[
{
type: 'text',
name: 'whatsAppNumber',
testID: 'input',
},
{type: 'button', name: 'login', testID: 'button'},
]}
onSubmit={submitData}
/>
you can test your code by following method, please use msw for creating dummy server for api call.
import {fireEvent, render,} from '#testing-library/react-native';
describe('Login Screen', () => {
it('should validate form', async () => {
const {getByTestId} = render(<Login />);
const numberField = getByTestId('input');
const button = getByTestId('button');
expect(numberField).toBeDefined();
expect(button).toBeDefined();
fireEvent.changeText(numberField, '9876543215');
fireEvent.press(button)
await waitFor(() =>{
//expect your function to be called
})
});
});

The function onLocationChange(visibleLocation,cfi) does not return cfi for each page( flow="paginated") in #sbrighiu/epubjs-rn

I am currently using #sbrighiu/epubjs-rn in react native for epub file reader.
In the documentation the onLocationChange function definition is as follow:
onLocationChange: Function called on every page change, reports current CFI
src: "https://s3.amazonaws.com/epubjs/books/moby-dick.epub",
<Epub
flow="paginated"
ref={(ref) => this.readerRef = ref}
src={this.state.src}
flow={this.state.flow}
location={this.state.location}
onLocationChange={(visibleLocation, cfi) => {
this.onLocationChange(visibleLocation, cfi)
}}
onLocationsReady={(locations) => {
console.log("onLocationsReady", locations);
}}
onReady={(book) => {
this.onReady(book)
}}
onPress={
(cfi, position, rendition) => {
this.toggleBars();
console.log("onPress", cfi);
this.setState({
cuurentLocation: cfi
})
}}
onSelected={(cfiRange, rendition) => {
rendition.highlight(cfiRange, {});
}}
onMarkClicked={(cfiRange, data, rendition) => {
rendition.unhighlight(cfiRange);
}}
origin={this.state.origin}
onError={(message) => {
console.log("EPUBJS-Webview", message);
}}
/>
onLocationChange = (visibleLocation, cfi) => {
console.log("visibleLocation", visibleLocation)
console.log("cfi", cfi)
this.setState({ visibleLocation: visibleLocation });
}
The above console returns:
Unfortunately, as the image above, onLocationChange function doesn't return cfi.
only onPress(), onDlbPress(), onLongPress() functions return cfi:
Is there any other option to get the current page's cfi ?
OR
Can you suggest an option to bookmark a specific page ?

Limit number of checkboxes selected and save value

I am building a food delivery application, and I would like to know how I can limit the number of checkboxes selected. An example is when entering the subsidiary, it displays a list of products. If I select a pizza, there is an extras section that limits the number of extras you can select, if you want to select more than two and your limit is two it should not allow you
all this with react hooks, I attach a fragment of my component
const ExtrasSelector = ({options = [{}], onPress = () => {}, limit = 0}) => {
const [showOptions, setShowOptions] = useState(true);
const [selectedAmount, setSelectedAmount] = useState(0);
const EXTRA = ' extra';
const EXTRAS = ' extras';
const updatedList = options.map(data => ({
id: data.id,
name: data.name,
price: data.price,
selected: false,
}));
const [itemsList, setItemsList] = useState(updatedList);
const toggleOptions = () => setShowOptions(!showOptions);
useEffect(() => {
}, [selectedAmount]);
// onPress for each check-box
const onPressHandler = index => {
setItemsList(state => {
state[index].selected = !state[index].selected;
onPress(state[index], getSelectedExtras(state));
// Increments or decreases the amount of selected extras
if (state[index].selected) {
setSelectedAmount(prevState => prevState + 1);
} else {
setSelectedAmount(prevState => prevState - 1);
}
return state;
});
};
const getSelectedExtras = extrasArr => {
const selectedExsArr = [];
extrasArr.map(item => {
if (item.selected) {
selectedExsArr.push(item);
}
});
return selectedExsArr;
};
return (
<View>
<View style={styles.container}>
<TouchableOpacity style={styles.row} onPress={toggleOptions}>
<Text style={styles.boldTitleSection}>
Extras {'\n'}
<Text style={titleSection}>
Selecciona hasta {limit}
{limit > 1 ? EXTRAS : EXTRA}
</Text>
</Text>
<View style={styles.contentAngle}>
<View style={styles.contentWrapperAngle}>
<Icon
style={styles.angle}
name={showOptions ? 'angle-up' : 'angle-down'}
/>
</View>
</View>
</TouchableOpacity>
{showOptions ? (
itemsList.map((item, index) => (
<View key={index}>
<CheckBox
label={item.name}
price={item.price}
selected={item.selected}
otherAction={item.otherAction}
onPress={() => {
onPressHandler(index, item);
}}
/>
<View style={styles.breakRule} />
</View>
))
) : (
<View style={styles.breakRule} />
)}
</View>
</View>
);
};
This is a simple react implementation of "checkboxes with limit" behaviour with useReducer. This way the business logic (here the limitation but can be any) is implemented outside of the component in a pure js function while the component itself is just a simple reusable checkbox group.
const { useReducer } = React; // --> for inline use
// import React, { useReducer } from 'react'; // --> for real project
const reducer = (state, action) => {
if (state.checkedIds.includes(action.id)) {
return {
...state,
checkedIds: state.checkedIds.filter(id => id !== action.id)
}
}
if (state.checkedIds.length >= 3) {
console.log('Max 3 extras allowed.')
return state;
}
return {
...state,
checkedIds: [
...state.checkedIds,
action.id
]
}
}
const CheckBoxGroup = ({ data }) => {
const initialState = { checkedIds: [] }
const [state, dispatch] = useReducer(reducer, initialState)
return (
<table border="1">
{data.map(({ id, label }) => (
<tr key={id}>
<td>
<input
onClick={() => dispatch({ id })}
checked={state.checkedIds.includes(id)}
type="checkbox"
/>
</td>
<td>
{label}
</td>
</tr>
))}
</table>
)
};
const data = [
{ id: "1", label: "Mashroom" },
{ id: "2", label: "Ham" },
{ id: "3", label: "Egg" },
{ id: "4", label: "Ananas" },
{ id: "5", label: "Parmesan" },
]
ReactDOM.render(<CheckBoxGroup data={data} />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Function inside renderItem in flatlist

I have a flatlist and it's working fine, I'm trying to put a function inside the code that is rendering my item but it gives me an error, and i need to put the function there so i can read the item's properties, here is my code:
_renderItem ({ item, index}) {
_shareText() {
Share.share({
message: item.name,
})
}
return (
<Button title="Share" onPress={this._shareText}/>
);
}
try this, i can see that _shareText is not defined like a function in the component
_shareText(item) {
Share.share({
message: item.name,
})
}
_renderItem({ item, index }) {
return (
<Button title="Share" onPress={() => { this._shareText(item); }} />
);
}

How to disable only the setState message warning on react native

I want to disable the setState message warning
On the layout 1 :
My constructor :
constructor(props){
super(props);
//Constructeur
this.lestachesitemsRef=getDatabase().ref('n0rhl66bifuq3rejl6118k8ppo/lestaches'); this.lestachesitems=[];
this.state={
//Debutdustate
lestachesSource: new ListView.DataSource({rowHasChanged: (row1, row2)=>row1 !== row2}),
Prenom: '',
Nom: '',}
}
My function :
ajouter= () => {
if( (this.state.Nom !== '') && (this.state.Prenom !== '')) { this.lestachesitemsRef.push({ Nom: this.state.Nom , Prenom: this.state.Prenom , }); this.setState({ Nom : '' }) , this.setState({ Prenom : '' }) }
}
My componentDidMount
componentDidMount()
{
//DidMount
this.lestachesitemsRef.on('child_added', (dataSnapshot)=>{ this.lestachesitems.push({id: dataSnapshot.key, text: dataSnapshot.val()}); this.setState({lestachesSource: this.state.lestachesSource.cloneWithRows(this.lestachesitems)}); });
this.lestachesitemsRef.on('child_removed', (dataSnapshot)=>{ this.lestachesitems = this.lestachesitems.filter((x)=>x.id !== dataSnapshot.key); this.setState({ lestachesSource: this.state.lestachesSource.cloneWithRows(this.lestachesitems)});});
}
My vue :
<TextInput style={styles.Dtext} placeholder="Nom" onChangeText={(text) => this.setState({Nom: text})} value={this.state.Nom}/>
<TextInput style={styles.Dtext} placeholder="Prenom" onChangeText={(text) => this.setState({Prenom: text})} value={this.state.Prenom}/>
<Button title='Allerlayout2' onPress={() => this.verl2()} onLongPress={() => this.infol2()} buttonStyle={ styles.View } icon={{name: 'squirrel', type: 'octicon', buttonStyle: styles.View }} />
<Button title='ajouter' onPress={() => this.ajouter()} onLongPress={() => this.infoajout()} buttonStyle={ styles.View } icon={{name: 'squirrel', type: 'octicon', buttonStyle: styles.View }} />
<ListView dataSource={this.state.lestachesSource} renderRow={this.renderRowlestaches.bind(this)} enableEmptySections={true} />
The Layout2 the same thing as Layout1.
Thank you !
Warnings
Warnings will be displayed on screen with a yellow background. These alerts are known as YellowBoxes. Click on the alerts to show more information or to dismiss them.
As with a RedBox, you can use console.warn() to trigger a YellowBox.
YellowBoxes can be disabled during development by using console.disableYellowBox = true;. Specific warnings can be ignored programmatically by setting an array of prefixes that should be ignored: console.ignoredYellowBox = ['Warning: ...'];.
In CI/Xcode, YellowBoxes can also be disabled by setting the IS_TESTING environment variable.
http://facebook.github.io/react-native/docs/debugging.html#yellowbox-redbox