repro: https://codesandbox.io/s/my054m9lkx
a. It looks like "controlled" DayPickerInput input field is not really controlled -
I can pass letters to the field, the onDayChange event won't be fired, but the input field will change (try writing letters in the beginning)
expected: full correlation between input date, calendar selected date and value prop.
b. when passing out-of-scope day to input (e.g. year 208, by erasing 1 from 2018), even though the dayPickerProps limits the month, they will render the out-of-scope month.
expected: only in-scope months will be rendered
c. when passing disabled day to input (e.g. 13/1/18), even though the disabledDays limits this day, it will be chosen.
expected: only in-scope days will be available to select in input
Hey, thanks for the feedback!
I can pass letters to the field, the onDayChange event won't be fired, but the input field will change (try writing letters in the beginning)
This works as intended. You have access to the input field onChange prop if you want to change this behavior.
b. when passing out-of-scope day to input (e.g. year 208, by erasing 1 from 2018), even though the dayPickerProps limits the month, they will render the out-of-scope month.
c. when passing disabled day to input (e.g. 13/1/18), even though the disabledDays limits this day, it will be chosen.
expected: only in-scope days will be available to select in input
These are also by design. It's up to you to decide what to do in this case. The onDayChange method has access to the modifiers, so you can check if the entered day is out of the month. For example here we display a warning.
@gpbl - playing with the example youv'e provided -
if I enter a number too big - it gives a warning, but if I put letters inside the numbers there is no warning at all!
and if value isn't controlling the input (like normal input in react), than I have no way of disabling bad input
it gives a warning, but if I put letters inside the numbers there is no warning at all!
Yes, the example shows the warning only when the input matches a disabled day, not when the input value is an invalid date.
and if value isn't controlling the input (like normal input in react), than I have no way of disabling bad input
You do have, as I wrote above: use the onChange input prop.
Example: https://codesandbox.io/s/2w0658kk4n
ok. I see. thx
Still, Is there a way to block bad input from entering the input field?
usually I do it with value prop to input, and in onChange setting value state only if I want the change - here, even though you have value, it's still uncontrolled.
With onChange you will make the input unusable and that's why it now works like that.
Say the user want to insert December 15th, 2010. Until the string is not parsed as date, your "controlled" component would detect it as a "bad input". What should you do? You can't change the content of the input value because the user is still writing in it.
An alternative is to "reset" the "bad input" when the user stopped editing its value, e.g. on blur or before submitting the form.
I don't understand -
simple react input has two mods - either it is controlled or it is uncontrolled - like described here
when adding value you give full control to the state - and to the developer, to decide what stays in the input and what's not.
I understand the issue you raise - but giving a value prop, (and worse - taking away the option to fully control the input with normal input value prop ) is not the "react way".
so maybe another prop should be added - day- that will be reflected in input text.
any hows, for my needs - I want full control over value, and I don't care if users won't be able to type "december", this is my concern (or I'll add sophisticated logic to handle this. again - my problem).
I don't understand -
simple reactinputhas two mods - either it is controlled or it is uncontrolled - like described here
I think the confusion here is that you think that value refers to the input’s value prop, and onDayChange its change event – they are not. Indeed, value accepts both Strings and Dates and onDayChange is fired when the day changes (not the input’s value).
If you would like to propose an API change and explain the problem it is fixing I’m open to change the current one 👍🏽
I'll come up with something.
simple and critical use case - having read-only input (e.g - ux here)
btw, even the docs are confused:
value: { string | Date } - The value of the input field. (from here)
So I can propose this api -
When no value, input is "un-controlled", meaning - it will have free text, and this text will be over-written when together with onDayChange, similar to current behaviour.
other option, of "controlled" input, will give developer more freedom, but will of course require him for more work. the api will be this
inputValue: string
onInputChange: (text, modifiers, inputChangeEvent) => void
no onDayChange event
now when onInputChange takes place, the user will be able to change inputValue and selectedDays, for example:
// for changes originating in input component.
//if you want read only input (e.g. skyscanner.com ux), just remove this method
handleInputChange(val, modifiers){
if( someRegexUtilToCheckValidDayString(val)) {
//e.g. passing only "DD-MM-YY" strings with any custom logic I need
this.setState({inputValue: val})
const day = textToDayUtil(val)
if( someUtilToCheckValidDate(day, modifiers) ) {
this.setState({selectedDays: [day]})
}
}
}
// for changes originating in calendar component
handleDayClick(day, modifiers) {
if( someUtilToCheckValidDate(day, modifiers) ) {
this.setState({
selectedDays: [day],
inputValue: dayToTextUtil(day) // this will allow custom Input for multiple days selections, that is not supported currently
})
}
}
Behind the hood, I guess you can use the "controlled" approach for "uncontrolled" inputs, with default logic (pass any text so it will feel "free")
While still giving them the "easy option" for uncontrolled-count-on-me component, this api will give developers full control over the input if they need, so they can have complex logic that you cannot cover or forecast.
for example - read only input, selecting multiple days with with dayPickerInput, etc.
plz open the issue again if you think this is relevant so other people can express their thoughts.
and thanks for this cool & needed library!
My 2 cents here is to make it clearer in the docs about passing event handlers as props on the input as you have in the fiddle posted above:
inputProps={{ onChange: this.handleInputChange }}
Most helpful comment
My 2 cents here is to make it clearer in the docs about passing event handlers as props on the input as you have in the fiddle posted above:
inputProps={{ onChange: this.handleInputChange }}