0

I'm trying to wrap flatpickr into a custom Vue component which should then should send dates to an eventHub, however I can't seems to get it to work. Somehow flatpickr can't find the input field (I think)

My wrapper component looks something like this:

<template>
<input type="text" id="flatpickr" placeholder="Select a range" />
</template>

<script>
const Flatpickr = require("flatpickr");

var defaultStart = new Date(new Date().setDate(new Date().getDate() - 10)).toISOString().slice(0, 10)
var defaultEnd = new Date().toISOString().slice(0, 10)

export default {
  name: 'DatePicker',
  props:['startDate', 'endDate'], // I don't really need this but I should pass data to all Children
  mounted() {
    new Flatpickr('#flatpickr', {
      dateFormat: "Y-m-d",
      mode: 'range',
      altInput: true, // Human Readable
      minDate: new Date().fp_incr(-60), // 60 days from today
      maxDate: defaultEnd,
      // defaultDate: [defaultStart, defaultEnd],
      // minDate: '2017-01-01', // 60 days from today
      // maxDate: '2017-05-05',
      // defaultDate: ["2017-02-02", "2017-04-04"],
      locale: { firstDayOfWeek: 1},
      onClose: function(selectedDates, dateStr, instance) {
        let startDate = selectedDates[0].toISOString().slice(0, 10);
        let endDate = selectedDates[1].toISOString().slice(0, 10);
        this.$emit('change', { startDate, endDate });  // emit to eventHub
      }
    })
  }
}
</script>

I've also tried to use .class-name but nothing. What am I doing wrong?

Costantin
  • 2,486
  • 6
  • 31
  • 48
  • How different is this from your last [question about this](https://stackoverflow.com/questions/43682446/how-to-add-vanilla-js-to-a-custom-vue-component/43683190#43683190)? Could you not use that as a base? Here it looks like your $emit will fail because of a `this` issue. – Bert May 30 '17 at 23:49
  • No I know I really did try to use that even with $el, but the thing is not that $emit will fail is that flatpickr can't even find it's instance (it doesn't show) I just see an input element – Costantin May 30 '17 at 23:52
  • You can replace $emit with console.log(startDate) for example, I really spent the whole day trying before posting it here (since its obviously veeeery similar) – Costantin May 30 '17 at 23:54
  • Let me play with your new code using the old example. Ill get back to you. – Bert May 30 '17 at 23:54
  • This seems to work. https://jsfiddle.net/xnaz90uf/1/ – Bert May 30 '17 at 23:59
  • Hi, so I tried to plug this in my code and it loads flatpicker to the whole template, my template is a nav bar where I also have the flatpicker, now the whole navbar is a big input.. – Costantin May 31 '17 at 00:23
  • Ok, then you need to use the $ref approach. – Bert May 31 '17 at 00:24
  • Yes, sorry my question was confusing. The `ref` works. Thanks a lot – Costantin May 31 '17 at 00:28

2 Answers2

1

Try making the following changes:

In the template...

<input type="text" ref="flatpickr" placeholder="Select a range" />

In the mounted() hook...

mounted() {
    var myInput = this.$refs.flatpickr
    new Flatpickr(myInput, { 
Explanation:

The Vue way of identifying elements in the template is by using "ref" (instead of "id") - and it's best to keep Vue happy because it does funky things with the template which may cause unexpected behaviours if you treat it as plain HTML. (It only looks like HTML but don't be fooled... the Vue template isn't HTML, and actually ends up getting compiled into a function.)

So, replace the input's id with a "ref" instead, and in your mounted() hook, get a variable reference to the input, and use that as the first parameter of your Flatpickr() call instead of an "#id".

JSFiddle: https://jsfiddle.net/CookieJon/7stotLrz/2/

Bumpy
  • 1,290
  • 1
  • 22
  • 32
  • He doesn't really need a ref in this case, $el suffices. – Bert May 31 '17 at 00:05
  • Ok. I'm not familiar with Flatpickr, but if he adds more elements to the template, then he'll be forced to use "ref" instead of "el", I'm guessing?? Either way, I suggest the OP reads up on both "$refs" and "$el" in the Vue docs because they're pretty fundamental... $REFS: https://vuejs.org/v2/api/#ref $EL: https://vuejs.org/v2/api/#el Good luck! – Bumpy May 31 '17 at 00:10
  • You're correct and based on his comment, that turns out to be the case here. – Bert May 31 '17 at 00:25
  • Hi @Bumpy, yes this was the problem. Thank You. – Costantin May 31 '17 at 00:29
0

Use this vue component instead.


Installation:

npm install vue-flatpickr-component --save

It is dead simple to use.

Sample:

<template>
  <div>
    <flat-pickr v-model="date"></flat-pickr>
  </div>
</template>

<script>
  import flatPickr from 'vue-flatpickr-component';
  import 'flatpickr/dist/flatpickr.css';

  export default {    
    data () {
      return {
        date: null,       
      }
    },
    components: {
      flatPickr
    }
  }
</script>
Oussama Ben Ghorbel
  • 2,132
  • 4
  • 17
  • 34