-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Slider] Add example showing how to access value #3892
Conversation
Will withdraw and make changes to get Travis linter to pass. |
<Slider | ||
defaultValue={0.5} | ||
value={this.state.value1} | ||
onChange={(event, value) => this.setState({value1: value})} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you create an handler method for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought I could originally, but no - I really can't.
Key point: I submitted this request to change the documentation because it wasn't clear to me how to even get the value from the slider in the first place.
The only way I can see to do it is to use that arrow notation to create a function which contains value was the only way I could do it myself.
That said, I might be able to do something... is this what you're looking for?
handleSlider (name, value) {
var stateChange = {}
stateChange[name] = value;
this.setState(stateChange);
}
// ...
onChange={(event, value) => this.handleSlider('value1', value)}
@brianboyko Yes indeed, we need to standardize the callbacks of Material-UI. |
I don't know if this is what you want (especially since I can't figure out how to work that handler without an arrow function) but here you go |
<Slider | ||
defaultValue={0.5} | ||
value={this.state.firstSlider} | ||
onChange={(event, value) => this.handleSlider('firstSlider', value)} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the idea is to prevent the creating of a function in the render method and, in some aspect, increase readability / reduce the cost of changes.
Here is an example.
handleOpen = () => {
this.setState({open: true});
};
...
<RaisedButton label="Dialog" onTouchTap={this.handleOpen} />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I made this pull request because it was unclear how to get the value from the slider.
So far as I can tell, there's no way to actually get the value without putting a function in the render method. This may be a problem that has to be resolved in the source of Slider.js, but that's not applicable here, this is just documenting how to get a value out of a slider.
If there's a better way to do this, please let me know, because this method is the one I came up with after a half-day of beating myself over the head.
If there's a better way to get the value, of course, that should replace this pull request.
Here's the code from material-ui/src/Slider/Slider.js:
//line 366
// We need to use toFixed() because of float point errors.
// For example, 0.01 + 0.06 = 0.06999999999999999
if (this.state.value !== newValue) {
this.setState({
percent: newPercent,
value: parseFloat(newValue.toFixed(5)),
}, () => {
if (this.props.onChange) this.props.onChange(event, this.state.value);
});
}
As far as I can tell, the only way to pass this.state.value to the handleChange method is via some sort of function.
Perhaps a change like this may be needed to Slider.js:
if (this.state.value !== newValue) {
this.setState({
percent: newPercent,
value: parseFloat(newValue.toFixed(5)),
}, () => {
if (this.props.onChange) this.props.onChange(Object.assign({}, event, {value: this.state.value}, value);
});
}
so as to not break backwards compatibility, but allow you to just simply bind the event, like so:
handleSlider1(event) {
this.setState({'slider1': event.value});
}
// ...
onChange={this.handleSlider1.bind(event)}
So, basically, what I'm saying is, so far as I can tell, there's actually no way to get the value from the slider without putting a function in the render method. :( If I'm wrong, I'd be pleasantly surprised! :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no way to actually get the value without putting a function in the render method
It depends of what you mean but putting
.
We do need to give a function for the onChange
property. However, we don't have to create a new function at each render with a bind
.
Look at the example I have linked in the previous comment. That's working fine with an arrow function as a class property.
Well, you will need two handlers here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I think I gotcha. Making an update.
handleFirstSlider(event, value) {
this.setState({firstSlider: value});
}
handleSecondSlider(event, value) {
this.setState({secondSlider: value});
}
render() {
return (
<div>
<Slider
defaultValue={0.5}
value={this.state.firstSlider}
onChange={this.handleFirstSlider.bind(this)}
Figured out what you meant, and learned something in the process! |
import sliderCode from '!raw!material-ui/lib/Slider/Slider'; | ||
|
||
const descriptions = { | ||
simple: 'The `defaultValue` property sets the initial position of the slider. The slider appearance changes when ' + | ||
'not at the starting position.', | ||
stepped: 'By default, the slider is continuous. The `step` property causes the slider to move in discrete ' + | ||
'increments.', | ||
value: 'The slider bar can have a set minimum and maximum, and the value can be ' + | ||
'obtained through the value parameter fired on an onChange event', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing dot at the end.
I'm glad and thanks, this example is going to be helpful for others. |
Made those changes, have you checked? |
@brianboyko Thanks. That looks good. Could you squash down the commits? |
@brianboyko - When you squash, please also reword the commit description to match the current PR title. Thanks! |
Squishied! |
@brianboyko Thanks! |
tests/ docs demo, and is linted.Issue: It was not clear from the documentation how, exactly, to grab the value from the Slider component, as this was not mentioned on the component page. As Standardization of Callback Signatures #2957 states, the way to handle this is onChange={(event, value) => /use 'value' here/} in most cases. I had erroneously tried (event) => event.target.value and (value) => value, and it caused me enough frustration that I felt that when I figured it out I should make a PR and add it to the docs.
The main thing that would have helped me, I think, was to have examples which clearly show how to get the value from the slider element and use it (usually in the component state).
I created a new file in /docs/src/app/components/pages/Slider/ExampleValue.js and amended /docs/src/app/components/pages/Slider/Page.js to include two examples, where moving the slider also alters the slider's value in the state, and re-renders it on the page. As a bonus, I also amended Page.js to make it clear that you can assign values outside the range of 0 and 1 (such as 1-100) to "min" and "max" props.