Search code examples
javascripthtmldatepickermaterialize

How to style Materialize Datepicker by clicking on a day simultaneously


I'm using Materialize Datepicker for toggling holidays in a list. According to my code, when I click on a day, the event is added/removed to/from the list simultaneously. However as for the style in the datepicker, it is updated only when I click another day or restart the datepicker. Here is Materialize Pickers's documentation.

I added 1 and 20 July as an example. You can try to add/remove some other days.

I'd like the style in the datepicker also to be updated simultaneously like the list. Any ideas?

Thanks in advance.

var holidays = [1625086800000, 1626728400000];

var datepicker = document.querySelector('#addHoliday')

var options = {
  showClearBtn: true,
  events : holidays.map ((day) => {return new Date(day).toDateString()}),
  onSelect : (day) => {
    var index = holidays.indexOf(day.valueOf())
    if(index > -1) {
        holidays.splice(index,1)
    } else {
      holidays.push(day.valueOf())
      holidays.sort()
    };
    M.Datepicker.getInstance(document.querySelector('#addHoliday')).options.events = holidays.map ((day) => {return new Date(day).toDateString()})
    
    disposeHolidays()   
  }
}

M.Datepicker.init(datepicker, options)
disposeHolidays()

function disposeHolidays () {
  holidaysList.innerHTML = holidays.map ((day) => {
    return '<li class="collection-item">' + new Date(day).toDateString() + '</li>'}).join('')
}
.has-event {
  background : #FF6666 !important
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

<div class="row">
  <div class="input-field col s6 l3 offset-s1 offset-l1">
    <input type="text" class="datepicker" id="addHoliday">
    <label for="addHoliday">Pick a date</label>
    
    <div class="row">
      <ul class="collection" id="holidaysList">
      </ul>
    </div>
  </div> 
</div>


Solution

  • Had a hunt through the source code. There's an undocumented 'draw' method that updates the HTML. Try this.

    var holidays = [1625086800000, 1626728400000];
    
    var datepicker = document.querySelector('#addHoliday')
    
    var options = {
      showClearBtn: true,
      events: holidays.map((day) => {
        return new Date(day).toDateString()
      }),
      onSelect: (day) => {
        var index = holidays.indexOf(day.valueOf())
        if (index > -1) {
          holidays.splice(index, 1)
        } else {
          holidays.push(day.valueOf())
          holidays.sort()
        };
    
        var instance = M.Datepicker.getInstance(datepicker);
        instance.options.events = holidays.map((day) => {
          return new Date(day).toDateString()
        })
        instance.draw(true);
    
        disposeHolidays()
      }
    }
    
    M.Datepicker.init(datepicker, options)
    disposeHolidays()
    
    function disposeHolidays() {
      holidaysList.innerHTML = holidays.map((day) => {
        return '<li class="collection-item">' + new Date(day).toDateString() + '</li>'
      }).join('')
    }
    .has-event {
      background : #FF6666 !important
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
    
    <div class="row">
      <div class="input-field col s6 l3 offset-s1 offset-l1">
        <input type="text" class="datepicker" id="addHoliday">
        <label for="addHoliday">Pick a date</label>
        
        <div class="row">
          <ul class="collection" id="holidaysList">
          </ul>
        </div>
      </div> 
    </div>