Skip to content
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

Dynamically changing minDate/maxDate (date range picker) #20

Closed
RaZeR-RBI opened this issue Aug 29, 2017 · 24 comments
Closed

Dynamically changing minDate/maxDate (date range picker) #20

RaZeR-RBI opened this issue Aug 29, 2017 · 24 comments
Assignees

Comments

@RaZeR-RBI
Copy link

[x] Other, please describe
Not sure if it's a bug or I am using it wrong (sorry for that).

Tell about your platform

  • flatPickr version : 3.0.0 (from unpkg)
  • Vue.js version : 2.4.2 (from unpkg)
  • Browser name and version : Chrome 55.0

Current behavior
Changing minDate and maxDate in the config objects does not trigger component redraw.

Expected behavior
Changing the dates in the fiddle below should update both pickers accordingly to allow proper date range selection (startDate < endDate).

Minimal reproduction of the problem with instructions
JSFiddle

  1. Change date in any picker from the example
  2. The other should update it's bounds accordingly (but it doesn't, so I can select an invalid date range with endDate before startDate like 2017-08-29 ~ 2017-08-10, for example)

P.S.: Thank you for creating this component. I was searching for a long time for a good-looking date picker, now the only thing left is getting it to work for me 😃

@ankurk91 ankurk91 added the bug label Aug 30, 2017
@ankurk91 ankurk91 self-assigned this Aug 30, 2017
@ankurk91
Copy link
Owner

@RaZeR-RBI
I suspect this is Vue.js reactivity issue. Your new configs are not being detected by component and date picker not updated.

Till we get a fix you may try range mode -
https://chmln.github.io/flatpickr/examples/#range-calendar

@Dahje
Copy link

Dahje commented Aug 31, 2017

For some reason I had to put it into the actual html for it to work, but is this what you want @RaZeR-RBI? https://jsfiddle.net/cchejb3p/4/

@ankurk91
Copy link
Owner

Thanks @Dahje

According to vue js API docs

Note: when mutating (rather than replacing) an Object or an Array, the old value will be the same as new value because they reference the same Object/Array. Vue doesn’t keep a copy of the pre-mutate value.

https://vuejs.org/v2/api/

It means the only way to detect change in object properties is to overwrite it.

Still need to try with deep flag.

I will dig it more and will add a note.

@TheDiehard22
Copy link

Hi there,

I'm experiencing this very same problem. It would be very nice to see it fixed soon :)
Liking this component so far!

@ankurk91
Copy link
Owner

ankurk91 commented Sep 2, 2017

As said; Vue.js can not detect changes in Object like this -

this.config.minDate = new Date();

One way to do this by overwriting the whole config object

this.config = { minDate:new Date() }

But this way you will loose existing config properties.

The preferred way to to this via this.$set

this.$set(this.config,'minDate', new Date())

This will just update the minDate value in config object while preserving old properties.
This will also cause component to detect changes and update itself.

One thing to notice here is that -
Vue.set will not preserve method callback inside Object. so if you have a callback like this -

data () {
return {
config : {
onChange: function() {
  // i will be lost
    }
  }
}}

then if you do something like this

Vue.set(this.config,'minDate', new Date())

you will loose that callback method.
If you know how to preserve methods, let me know.

@TheDiehard22
Copy link

Thanks for your feedback!

Wouldn't it be an idea though to add custom event listeners?
If so, this preserves methods if I'm right and we can call event listeners in the 'html' code.

@ankurk91
Copy link
Owner

ankurk91 commented Sep 5, 2017

@TheDiehard22
Great idea, i can $emit the onChange event and parent component can listen it.
I will give it a try soon.

P.S.
See WIP on dev branch

ankurk91 added a commit that referenced this issue Sep 5, 2017
@ankurk91 ankurk91 mentioned this issue Sep 16, 2017
ankurk91 added a commit that referenced this issue Sep 22, 2017
@Minasokoni
Copy link

Minasokoni commented Oct 6, 2017

@ankurk91 Similar question to this one. Is it possible to update the preloaded multiple dates? Lets say I have a dropdown that has a range of days and I want the input to update when a value is selected?

ie: Last 7 Days
the datepicker input shows:
Sept 29 - Oct 6

this.$set(this.config, 'defaultDate', [moment().subtract(7, 'days').format('MMM DD, Y'), moment().format('MMM DD, Y')])

@ankurk91
Copy link
Owner

ankurk91 commented Oct 7, 2017

@Minasokoni
You should be changing v-model directly.

this.yourModel = '2016-10-10 to 2016-10-20';

@Minasokoni
Copy link

@ankurk91 lol it was a long day at work. I don't know what I was thinking... Thanks

@tychenjiajun
Copy link

i tried to use configs as computed properties but that's not a good idea.

@krisnaw
Copy link

krisnaw commented Jan 25, 2018

Hi, any solution to this issue? I just faced a similar problem.

I have 2 dates picker, one for StartDate and one for EndDate. So after pick a date and time on Start Date picker, the value will be used as minDate on EndDate Flatpickr. Is that possible?

@ankurk91
Copy link
Owner

@krisnaw
You can achieve this by events

<flatpickr v-model="startDate" @on-change="onStartChange">
<flatpickr v-model="endDate" @on-change="onEndChange">

Try this, otherwise i will add example for you.

@krisnaw
Copy link

krisnaw commented Jan 25, 2018

Hi @ankurk91,
Thanks for swift response 👍

I've tried using an event and changing the config: { minDate: startDate } value of endDate, but I keep getting this error
TypeError: self.config.minDate.getFullYear is not a function

This is my onStartChange method looks like
onStartChange() { this.configEndDate = { minDate: this.startDate } }
Another information, I use difrrent config data between the StartDate and EndDate flatpickr

@ankurk91
Copy link
Owner

      onStartChange(selectedDates, dateStr, instance) {
        this.$set(this.configs.end, 'minDate', dateStr);
      },
      onEndChange(selectedDates, dateStr, instance) {
        this.$set(this.configs.start, 'maxDate', dateStr);
      }

You should do like this.

@krisnaw
Copy link

krisnaw commented Jan 25, 2018

hi @ankurk91,
thanks for the example

I still didn't get it working

This is my current code looks like

<flat-pickr class="form-control" :config="configStartDate"  v-model="startDate"  @on-change="onStartChange(startDate)"></flat-pickr>
<flat-pickr class="form-control" :config="configEndDate"  v-model="endDate"></flat-pickr>
                configStartDate: {
                    enableTime: true,
                    time_24hr: true,
                    minDate: new Date(),
                },
                configEndDate: {
                    enableTime: true,
                    time_24hr: true,
                    minDate: new Date(),
                },
            onStartChange(selectedDates) {
                this.$set(this.configEndDate, 'minDate', selectedDates);
            },

@tychenjiajun
Copy link

tychenjiajun commented Jan 25, 2018

@krisnaw

<flat-pickr class="form-control" :config="configStartDate"  v-model="startDate"  @on-change="onStartChange"></flat-pickr>
<flat-pickr class="form-control" :config="configEndDate"  v-model="endDate"></flat-pickr>
onStartChange(dates, startDate) {
    this.$set(this.configEndDate, 'minDate', startDate);
}

@krisnaw
Copy link

krisnaw commented Jan 25, 2018

Hi @tychenjiajun
Thanks for the response,

I've tried your solution.

if I use 'startDate' it will make an error
[Vue warn]: Error in event handler for "on-change": "ReferenceError: startDate is not defined"

And when I tried using 'this.startDate' referring to v-model data, it doesn't work. I mean the minDate on EndDate flatpickr is not set.

Additional information, I'm using

  • vue-flatpickr-component: ^5.0.0
  • vue: ^2.1.10
  • Browser: Chrome Version 63

@ankurk91
Copy link
Owner

@krisnaw
I am running out of time today, i will add examples tomorrow.

ankurk91 added a commit that referenced this issue Jan 25, 2018
@ankurk91
Copy link
Owner

ankurk91 commented Jan 25, 2018

@krisnaw
Your example is ready,
check 3c14c78

@krisnaw
Copy link

krisnaw commented Jan 25, 2018

Wow, thank you very munch @ankurk91. I'll try it now.

@krisnaw
Copy link

krisnaw commented Jan 25, 2018

Hi @ankurk91, please respond this tomorrow

I've tried the example, but still not working.

Here is the full code.

<template>
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <flat-pickr class="form-control" :config="configs.start" v-model="form.dateStart"
                            @on-change="onStartChange"></flat-pickr>
            </div>
            <div class="col-md-8 col-md-offset-2">
                <flat-pickr class="form-control" :config="configs.end" v-model="form.dateEnd"
                            @on-change="onEndChange"></flat-pickr>
            </div>
        </div>
    </div>
</template>

<script>
    import flatPickr from 'vue-flatpickr-component';
    import 'flatpickr/dist/flatpickr.css';
    import rangePlugin from 'flatpickr/dist/plugins/rangePlugin';
    export default {
        components: {
            flatPickr,
        },
        data() {
            return {
                form: {
                    dateBasic: null,
                    dateTime: null,
                    time: null,
                    date: '2018-01-01',
                    dateLocale: null,
                    dateInline: +new Date(),
                    dateModal: '',
                    dateValidate: null,
                    dateConfirm: null,
                    allowInput: null,
                    dateStart: null,
                    dateEnd: null,
                },
                configs: {
                    start: {
                        minDate: new Date(),
                        maxDate: null
                    },
                    end: {
                        minDate: null
                    }
                }
            }
        },
        methods: {
            onStartChange(selectedDates, dateStr, instance) {
                this.$set(this.configs.end, 'minDate', dateStr);
            },
            onEndChange(selectedDates, dateStr, instance) {
                this.$set(this.configs.start, 'maxDate', dateStr);
            }
        },
        mounted() {
            console.log('Component mounted.')
        }
    }
</script>

@ankurk91
Copy link
Owner

@krisnaw
i can not help in that way.
U can clone this repo and play around the examples.

@mahajan1217
Copy link

it doesnt show end date when i select start date and enddate as equal in mode range

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants