himelbrand / react-native-numeric-input

a stylish numeric input for react native
MIT License
148 stars 102 forks source link

I'm having an issue with onChange no called when value return 0 #37

Closed csanchez24 closed 5 years ago

csanchez24 commented 5 years ago

Describe the bug when the values is 0 not call onChange

Hi Thanks for the lib.

First I'm sorry for my english. I'll try the tell you something.

in the function dec in the file NumericInput.js

dec = () => { let value = this.props.value && (typeof this.props.value === 'number') ? this.props.value : this.state.value if (this.props.minValue === null || (value - this.props.step > this.props.minValue)) { value = (value - this.props.step).toFixed(12) value = this.props.valueType === 'real' ? parseFloat(value) : parseInt(value) this.setState({ value, stringValue: value.toString() }) } else if (this.props.minValue !== null) { this.props.onLimitReached(false, 'Reached Minimum Value!') value = this.props.minValue this.setState({ value, stringValue: value.toString() }) } if (value !== this.props.value) this.props.onChange && this.props.onChange(Number(value)) }

the last if is which one call onChange, But value and this.props.value is equal in that point. value=0 and this.props.value=0 so never call onChange.

Thanks.

himelbrand commented 5 years ago

@csanchez24 I didn't understand what the issue is, can you please add your component with the props you used? because the only time what you speak of will happen, is when you have 0 and also the minimum value is 0 and you try to use dec. more details on your issue will great.

abhinav-official commented 5 years ago

<NumericInput value={this.state.value} onChange={value => { this.setState({ value }); console.log(this.state.value); }} onLimitReached={(isMin, msg) => console.log(isMin, msg)} totalWidth={80} totalHeight={30} iconSize={10} step={1} minValue={0} valueType="real" rounded editable={false} textColor="#B0228C" iconStyle={{ color: "white" }} rightButtonBackgroundColor="#18c2ef" leftButtonBackgroundColor="#ff8080" /> when i descend from 1 it doesnot set the value as 0 @himelbrand

himelbrand commented 5 years ago

@abhinav-official @csanchez24 are you using version 1.8.1? because I added your code snippet, @abhinav-official , to my Example app with version 1.8.1 of the package which is the latest version, and it works fine.

csanchez24 commented 5 years ago

Hi @abhinav-official , Yes I'm using Version 1.8.1 "react-native-numeric-input": "^1.8.1",

maybe is my mistake. I'm going to show you how I'm doing.

this is how I used the component

<NumericInput totalHeight={35} minValue={0} editable={false} value={this.state.cantidades.particulares[index].cantidad} onChange={value => this.actualizaValorCantidad('particular',index,value)} />

Screen Shot 2019-07-20 at 12 52 16 PM Screen Shot 2019-07-20 at 12 58 36 PM

everything work fine when increase and reduce the values.

When the value increase the component call actualizaValorCantidad() when reduce call actualizaValorCantidad() too, excepting: when the value is equal to 1 and the value will reduce to 0 the component don't call actualizaValorCantidad().

Again I'm sorry for my English.

Thank you..!!

abhinav-official commented 5 years ago

@csanchez24 yes same issue with me @himelbrand when the value is equal to 1 and the value will reduce to 0 the component doesn't call onvalueChange() the version is latest.

himelbrand commented 5 years ago

I've made a little adjustment, I hope it helps. available on npm version 1.8.2. if it doesn't, I'll need more information on how to recreate, since I haven't been able to reproduce this bug. maybe a video + versions of react-native you're using or maybe some more of your code, the more information I'll have the easier it will be to solve this issue.

having said that, I hope this little change I made will solve the issue for you.

abhinav-official commented 5 years ago

@himelbrand just check this video when i descend the value unnamed

himelbrand commented 5 years ago

@abhinav-official do you have console.log in these functions? can you try running it with no console.log? sometimes console.log causes some weird issues in react native.

again I see the problem, but when I use your component at my example app it works fine.

so I need more info, otherwise, I can't try and help. you still didn't tell me what react-native version you are using. and maybe show me the function you are calling.

the same for you @csanchez24

thank you.

abhinav-official commented 5 years ago

`import React from "react"; import { StyleSheet, Text, View, FlatList } from "react-native"; import axios from "axios"; import { Button, Avatar, Divider } from "react-native-elements"; import NumericInput from "react-native-numeric-input"; import Global from "../Global";

export default class ManClothList extends React.Component { constructor(props) { super(props); this.state = { value: 0 }; }

renderItem = ({ item: l }) => (

{l.cloth_name} {"₹"} {l.cloth_price} { this.setState({ value }); let z = l.cloth_id; //store to get total price and quantity Global.CLOTH_LIST[z] = value + "," + l.cloth_price * value; //store to send to backend Global.CLOTH_DETAILS[z] = value; var data = Global.CLOTH_DETAILS; var output = Object.entries(data).map(([cloth_id, quantity]) => ({ cloth_id, quantity })); Global.CART_DATA = output; //pass data to parent this.props.onUpdate(Global.CLOTH_LIST); }} onLimitReached={(isMin, msg) => console.log(isMin, msg)} totalWidth={80} totalHeight={30} iconSize={10} step={1} minValue={0} valueType="integer" rounded editable={false} textColor="#B0228C" iconStyle={{ color: "white" }} rightButtonBackgroundColor="#18c2ef" leftButtonBackgroundColor="#ff8080" />

);

render() { let list = this.props.list; // console.log(list); return ( <FlatList data={list} renderItem={this.renderItem} keyExtractor={(item, index) => index.toString()} /> ); } }

const styles = StyleSheet.create({ backgroundContainer: { flex: 1, width: null }, container: { flexDirection: "row", justifyContent: "space-around", // marginHorizontal: 20, marginVertical: 10, borderBottomWidth: 1, borderBottomColor: "#c0c0c0" }, avatarContainer: { marginVertical: 10 }, titleText: { fontSize: 20, fontWeight: "400", color: "#000", textAlign: "left", marginVertical: 10 }, subtitleText: { fontSize: 18, fontWeight: "500", color: "#000", textAlign: "left", marginVertical: 12 }, buttonContainer: { marginVertical: 10 } }); { "main": "node_modules/expo/AppEntry.js", "scripts": { "start": "expo start", "android": "expo start --android", "ios": "expo start --ios", "eject": "expo eject" }, "dependencies": { "axios": "^0.18.0", "expo": "^32.0.0", "moment": "^2.24.0", "qs": "^6.7.0", "react": "16.5.0", "react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz", "react-native-datepicker": "^1.7.2", "react-native-elements": "^1.1.0", "react-native-image-slider-show": "^1.0.3", "react-native-keyboard-aware-scroll-view": "^0.8.0", "react-native-maps": "^0.24.2", "react-native-numeric-input": "^1.8.2", "react-native-paper": "^2.15.2", "react-native-scrollable-tab-view": "^0.10.0", "react-native-super-grid": "^3.0.8", "react-navigation": "^3.11.0" }, "devDependencies": { "babel-preset-expo": "^5.0.0" }, "private": true } `

@himelbrand check this out

himelbrand commented 5 years ago

@abhinav-official if I understand your code correctly, then you have an issue, all of your NumericInputs are connected to the same value, this.state.value I guess that that's one of the reasons that you are having issues. since when I tried your NumericInput components I had a valuie variable just for him, as needed. can you try giving each of the components it's own value var in the state?

abhinav-official commented 5 years ago

its dynamic list how am i supposed to do that @himelbrand

himelbrand commented 5 years ago

use somthing like this: this.state = { ... values: [0,0,...,0,0] //you can create it using your list to get the size and use the correct values ... }

onChange={value => { values = this.state.values values[index] = value this.setState({values}) }

note that the index you can get in the renderItem function, and not only the value of the list item.

hope that this helps. @abhinav-official

abhinav-official commented 5 years ago

@himelbrand help me out with this i am literally confused can you? I am unable to understand the logic

himelbrand commented 5 years ago

import React from "react"; import { StyleSheet, Text, View, FlatList } from "react-native"; import axios from "axios"; import { Button, Avatar, Divider } from "react-native-elements"; import NumericInput from "react-native-numeric-input"; import Global from "../Global";

export default class ManClothList extends React.Component { constructor(props) { super(props); this.state = { values: props.list.map(x=>0) }; }

renderItem = ({ item,index }) => (

<Avatar size={40} source={{ uri: item.cloth_icon }} containerStyle={styles.avatarContainer} />

{item.cloth_name}

{"₹"} {item.cloth_price}

<NumericInput value={this.state.values[index]} onChange={value => { values = this.state.values values[index] = value this.setState({ values }); let z = item.cloth_id; //store to get total price and quantity Global.CLOTH_LIST[z] = value + "," + item.cloth_price * value; //store to send to backend Global.CLOTH_DETAILS[z] = value; var data = Global.CLOTH_DETAILS; var output = Object.entries(data).map(([cloth_id, quantity]) => ({ cloth_id, quantity })); Global.CART_DATA = output; //pass data to parent this.props.onUpdate(Global.CLOTH_LIST); }} onLimitReached={(isMin, msg) => console.log(isMin, msg)} totalWidth={80} totalHeight={30} iconSize={10} step={1} minValue={0} valueType="integer" rounded editable={false} textColor="#B0228C" iconStyle={{ color: "white" }} rightButtonBackgroundColor="#18c2ef" leftButtonBackgroundColor="#ff8080" />

);

render() { let list = this.props.list; // console.log(list); return ( <FlatList data={list} renderItem={this.renderItem} keyExtractor={(item, index) => index.toString()} /> ); } }

I edited the code you posted, I think this will work if there are any small errors I'm sorry, but I did the coding right here in the github post section so I did not run it or tested it and I did "blind" coding.

in words: what I did was create a list of values instead of 1 value, initilaized it all to 0, of course you can set it using one of the properties of the item in the list. I used map to do so. now for each element in the this.props.list has it's own value in the list of values located in state, which correspond to the index of the item. meaning for the item in the 5th index, his value will be in this.state.values[5] when onChange is triggered then we make a copy of the values list, update in the copy the value in the correct location, then we replace the old values list with the updated copy, as to trigger a change in the render function.

I hope now it's clearer. let me know if it fixed your problem since I don't think the issue is with the package itself.

@abhinav-official good luck

himelbrand commented 5 years ago

Hi @abhinav-official , Yes I'm using Version 1.8.1 "react-native-numeric-input": "^1.8.1",

maybe is my mistake. I'm going to show you how I'm doing.

this is how I used the component

<NumericInput totalHeight={35} minValue={0} editable={false} value={this.state.cantidades.particulares[index].cantidad} onChange={value => this.actualizaValorCantidad('particular',index,value)} />

Screen Shot 2019-07-20 at 12 52 16 PM Screen Shot 2019-07-20 at 12 58 36 PM

everything work fine when increase and reduce the values.

When the value increase the component call actualizaValorCantidad() when reduce call actualizaValorCantidad() too, excepting: when the value is equal to 1 and the value will reduce to 0 the component don't call actualizaValorCantidad().

Again I'm sorry for my English.

Thank you..!!

what happens in actualizaValorCantidad? @csanchez24

abhinav-official commented 5 years ago

@himelbrand I really appreciate your effort in correcting my code but I don't see any progress I applied your code but it doesn't affect onChange method from my point of view you code is correct but the OnChange method works when we go from 0 to 1 but it doesnot work vice versa. it works from 4 to 3 but not 1 to zero. even consloe log doesnt show any output when we go from 1 to 0

himelbrand commented 5 years ago

@abhinav-official can you try one more thing please? do this in your render function: render() { let list = this.props.list; const values = this.state.values // console.log(list); return ( <FlatList data={list} renderItem={({item, index}) => this.renderItem(item,index,values)} keyExtractor={(item, index) => index.toString()} /> ); }

and also change: renderItem = ( item,index,vals) => (

<Avatar size={40} source={{ uri: item.cloth_icon }} containerStyle={styles.avatarContainer} />

{item.cloth_name}

{"₹"} {item.cloth_price}

<NumericInput value={vals[index]} onChange={value => { values = this.state.values values[index] = value this.setState({ values }); let z = item.cloth_id; //store to get total price and quantity Global.CLOTH_LIST[z] = value + "," + item.cloth_price * value; //store to send to backend Global.CLOTH_DETAILS[z] = value; var data = Global.CLOTH_DETAILS; var output = Object.entries(data).map(([cloth_id, quantity]) => ({ cloth_id, quantity })); Global.CART_DATA = output; //pass data to parent this.props.onUpdate(Global.CLOTH_LIST); }} onLimitReached={(isMin, msg) => console.log(isMin, msg)} totalWidth={80} totalHeight={30} iconSize={10} step={1} minValue={0} valueType="integer" rounded editable={false} textColor="#B0228C" iconStyle={{ color: "white" }} rightButtonBackgroundColor="#18c2ef" leftButtonBackgroundColor="#ff8080" />

);

let me know if it works. again when I use your component but with one value and not in a dynamic list it all works fine, so I'm guessing that it has somthing to do with the way you use the state and render etc.

abhinav-official commented 5 years ago

no it just doesnt read item data @himelbrand

himelbrand commented 5 years ago

@abhinav-official I didn't understand what you mean by that. anyway, I don't see any reason that the this.props.value will be equal to value before calling the this.props.onChange, except for incorrect coding on your part, im talking about the dec function of the package. you said it doesn't call your onChange function since in the dec function value and this.props.value are 0, but if you dec from 1 to 0 then at this point this.props.value should be 1 until the this.props.onChange is called with 0.

csanchez24 commented 5 years ago

Hi @himelbrand, I just proved the version 1.8.2 "react-native-numeric-input": "^1.8.2",

didn't work.

I taked a picture to my code for show you.

this is how created the inputs

Screen Shot 2019-07-22 at 9 19 29 AM

and this is the function

Screen Shot 2019-07-22 at 9 18 33 AM

and here a video

bug

in the version 1.8.1 only I puted this line in the second if on the function dec. It's a force brute but worked for me if(value==0) this.props.onChange && this.props.onChange(Number(value))

Thank you.

himelbrand commented 5 years ago

@csanchez24 thanks for the extra information, I have one question about actualizaValorCantidad, did you bind the function? did you do this? this.actualizaValorCantidad = this.actualizaValorCantidad.bind(this)

and another question. if you put a console.log before the call to actualizaValorCantidad do you see the console.log print?

csanchez24 commented 5 years ago

@himelbrand I did what you said me.

I bind the function and add console.log before call the function

<NumericInput totalHeight={35} minValue={0} editable={false} value={this.state.cantidades.trabajadores[index].cantidad} onChange={value => {console.log("before call actualizaValorCantidad");this.actualizaValorCantidad('trabajadores',index,value)}} />

the same behavior, don't show the console.log and don't called the function when reduced to 0

thanks you.

himelbrand commented 5 years ago

@himelbrand I did what you said me.

I bind the function and add console.log before call the function

<NumericInput totalHeight={35} minValue={0} editable={false} value={this.state.cantidades.trabajadores[index].cantidad} onChange={value => {console.log("before call actualizaValorCantidad");this.actualizaValorCantidad('trabajadores',index,value)}} />

the same behavior, don't show the console.log and don't called the function when reduced to 0

thanks you.

ok, and if you change the minValue to -1, is it still the same issue? or is it now having trouble when dec from 0 to -1?

csanchez24 commented 5 years ago

@himelbrand I did what you said me. I bind the function and add console.log before call the function <NumericInput totalHeight={35} minValue={0} editable={false} value={this.state.cantidades.trabajadores[index].cantidad} onChange={value => {console.log("before call actualizaValorCantidad");this.actualizaValorCantidad('trabajadores',index,value)}} /> the same behavior, don't show the console.log and don't called the function when reduced to 0 thanks you.

ok, and if you change the minValue to -1, is it still the same issue? or is it now having trouble when dec from 0 to -1?

@himelbrand ,

I did what you said me.

I changed the minvalue to -1.

it's weird call onChange in 1 and -1 but never when is 0.

only when the value is 0 never call onchange.

thank you.

abhinav-official commented 5 years ago

@himelbrand willl you please update that conditional statement in your lib file to support the change when the value guts 0. It will be very helpful

himelbrand commented 5 years ago

yes I'll update it now, cause I don't see any other solution for this weird issue

himelbrand commented 5 years ago

OK, I believe it'll work now. I published a new version v1.8.3 with a fix, available on npm. closing this issue

abhinav-official commented 5 years ago

@csanchez24 did the update work for you? If same issue then use this counter worked absolutely the way we want

csanchez24 commented 5 years ago

Yes it's working, Thank you so much.

have a nice day.

El lun., 22 jul. 2019 a las 22:51, Abhinav Kr. Jha (< notifications@github.com>) escribió:

@csanchez24 https://github.com/csanchez24 did the update work for you?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/himelbrand/react-native-numeric-input/issues/37?email_source=notifications&email_token=AD4OMLJZGY5XSP5KXCTFV23QAZW4LA5CNFSM4IDRCU7KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2RYHZY#issuecomment-514032615, or mute the thread https://github.com/notifications/unsubscribe-auth/AD4OMLMP32HX75J57M6ZGIDQAZW4LANCNFSM4IDRCU7A .

-- Carlos Jose Sanchez Espinosa. 3213521985