Create your own multi date picker using JQuery/Javascript
Tags: jquery, javascript, html
Published: 2019-07-25 06:13:42

---
title: Create your own multi date picker using JQuery/Javascript
published: true
description: Create your own multi dates picker and customize at your will
tags: #jquery, #javascript, #html
---

I know this is the era of Vue, Angular, React etc, but there are still applications running on old JQuery and javascript code. Recently I had a task to create or use a multidates picker from JQuery. I ran into the JQuery UI's multidatepicker and it was pretty nice. But I had a lot of issues and challanges customizing it. I then thought of why not creating one like I want.

Well I am no expert in front-end or scripting, but I still thought it was worth a try.

Though I was thinking to convert it to a plugin, here is a pure html and jquery code that I did for the multidatepicker. Here is my attempt: 

### Use bootstrap to create a HTML Skeleton
I have used bootstrap to create a HTML skeleton for the calendar that I will build dynamically.

```
<input type="text" id="selectedValues" class="date-values" readonly/>
        <div id="parent" class="container" style="display:none;">
            <div class="row header-row">
                <div class="col-xs previous">
                    <a href="#" id="previous" onclick="previous()">
                        <i class="fa fa-arrow-left" aria-hidden="true"></i>
                    </a>
                </div>
                <div class="card-header month-selected col-sm" id="monthAndYear">
                </div>
                <div class="col-sm">
                    <select class="form-control col-xs-6" name="month" id="month" onchange="change()"></select>
                </div>
                <div class="col-sm">
                    <select class="form-control col-xs-6" name="year" id="year" onchange="change()"></select>
                </div>
                <div class="col-xs next">
                    <a href="#" id="next" onclick="next()">
                        <i class="fa fa-arrow-right" aria-hidden="true"></i>
                    </a>
                </div>
            </div>
            <table id="calendar">
                <thead>
                    <tr>
                        <th>S</th>
                        <th>M</th>
                        <th>T</th>
                        <th>W</th>
                        <th>T</th>
                        <th>F</th>
                        <th>S</th>
                    </tr>
                </thead>
                <tbody id="calendarBody"></tbody>
            </table>
        </div>

```
I have added the Bootstrap, Font-awesome(for the previous and next arrows) and JQuery in my html.

I have added some styles as well to this. The css file can be accessed from [here](https://github.com/praneetnadkar/multidatepicker/blob/master/multidatepicker/styles.css)

Now the crux of the script is generating the dates based on the days. Here is my attempt on it:

### Script to load the calendar

```
function loadControl(month, year) {
    
    addMonths(month);
    addYears(year);

    let firstDay = (new Date(year, month)).getDay();

     // body of the calendar
    var tbl = document.querySelector("#calendarBody");
    // clearing all previous cells
    tbl.innerHTML = "";


    var monthAndYear = document.getElementById("monthAndYear");
    // filing data about month and in the page via DOM.
    monthAndYear.innerHTML = months[month] + " " + year;


    selectYear.value = year;
    selectMonth.value = month;
    
    // creating the date cells here
    let date = 1;

    selectedDates.push((month + 1).toString() + '/' + date.toString() + '/' + year.toString());

    // there will be maximum 6 rows for any month
    for (let rowIterator = 0; rowIterator < 6; rowIterator++) {

        // creates a new table row and adds it to the table body
        let row = document.createElement("tr");

        //creating individual cells, filing them up with data.
        for (let cellIterated = 0; cellIterated < 7 && date <= daysInMonth(month, year); cellIterated++) {

            // create a table data cell
            cell = document.createElement("td");
            let textNode = "";

            // check if this is the valid date for the month
            if (rowIterator !== 0 || cellIterated >= firstDay) {
                cell.id = (month + 1).toString() + '/' + date.toString() + '/' + year.toString();
                cell.class = "clickable";
                textNode = date;

                // this means that highlightToday is set to true and the date being iterated it todays date,
                // in such a scenario we will give it a background color
                if (highlightToday
                    && date === today.getDate() && year === today.getFullYear() && month === today.getMonth()) {
                    cell.classList.add("today-color");
                }

                // set the previous dates to be selected
                // if the selectedDates array has the dates, it means they were selected earlier. 
                // add the background to it.
                if (selectedDates.indexOf((month + 1).toString() + '/' + date.toString() + '/' + year.toString()) >= 0) {
                    cell.classList.add(highlightClass);
                }

                date++;
            }

            cellText = document.createTextNode(textNode);
            cell.appendChild(cellText);
            row.appendChild(cell);
        }

        tbl.appendChild(row); // appending each row into calendar body.
    }

    // this adds the button panel at the bottom of the calendar
    addButtonPanel(tbl);

    // function when the date cells are clicked
    $("#calendarBody tr td").click(function (e) {
        var id = $(this).attr('id');
        // check the if cell clicked has a date
        // those with an id, have the date
        if (typeof id !== typeof undefined) {
            var classes = $(this).attr('class');
            if (typeof classes === typeof undefined || !classes.includes(highlightClass)) {
                var selectedDate = new Date(id);
                selectedDates.push((selectedDate.getMonth() + 1).toString() + '/' + selectedDate.getDate().toString() + '/' + selectedDate.getFullYear());
            }
            else {
                var index = selectedDates.indexOf(id);
                if (index > -1) {
                    selectedDates.splice(index, 1);
                }
            }

            $(this).toggleClass(highlightClass);
        }

        // sort the selected dates array based on the latest date first
        var sortedArray = selectedDates.sort((a, b) => {
            return new Date(a) - new Date(b);
        });

        // update the selectedValues text input
        document.getElementById('selectedValues').value = datesToString(sortedArray);
    });


    var $search = $('#selectedValues');
    var $dropBox = $('#parent');
    
    $search.on('blur', function (event) {
        //$dropBox.hide();
    }).on('focus', function () {
        $dropBox.show();
    });
}

```

I have added a button panel to the bottom of the dates panel. It has two buttons, Reset and Done. 

Also, to set the dates to be pre-selected on load, add your dates to the selectedDates array.

This is how the control looks:
![multi_dates_picker](https://thepracticaldev.s3.amazonaws.com/i/23kg7q9st8eozbnb1bwp.gif)


I have been trying to improve my code here as I am not a JS or a frontend expert.

You can download the whole working sample from [here] (https://github.com/praneetnadkar/multidatepicker)

It is extremely easy to create your own controls and use them using simple HTML and JQuery/Javascript codes.