Monday, 6 February 2023

how to stop litepicker from creating multiple instances

I am creating a simple scheduler and am using litepicker for the date picker. I successfully have the litepicker loading. However having issues when trying to update the dates from an external source causing multiple instances of the litepicker to appear.

General Functionality:

  • There is a location to select a department
  • some of these departments have an open-date connected to it.(department 2 for testing purposes)
  • when selecting a department with open date the litepicker updates the start date to the open date however its been added to a new litepicker instead of the current one showing 2 litepickers in total.

How can I pass the date to litepicker without creating a new litepicker?

I have dropped where I am at in a codepen for code review at https://codepen.io/DigitalDesigner/pen/VwBqRBb

/* Ready Function */
$(function(){
    $('.scheduler').each(function(){
        let bn = new Scheduler($(this));
    });
});
const Scheduler = function(this$obj){
    this.$obj = this$obj;
    this.init();
};
Scheduler.prototype.init = function init(){
    this.location_check();
    this.modal_onclick();
    this.dept_picker();
    //this.createToday();
    this.litepicker_modal();
};
Scheduler.prototype.location_check = function location_check(){
    let $scheduler_form = this.$obj.find('.scheduler-form');
    let $location_field = this.$obj.find('.scheduler-input-department');
    let $error_text = this.$obj.find('.submission-error');
    $scheduler_form.submit(function(){
        if($location_field.val().length == 0){
            $error_text.text('Please select a location before submitting');
            return false;
        }
    });
};
Scheduler.prototype.modal_onclick = function modal_onclick(){
    let _this = this;
    $('.modal-trigger').each(function(){
        let target = $(this);
        target.on('click',function(){
            _this.modal_target(target.attr('rel'));
        });
    });
    this.$obj.find('.close-modal').each(function() {
        $(this).on('click', function() {
            _this.close_modal();
        });
    });
};
Scheduler.prototype.modal_target = function modal_target(target){
    let _this = this;
    let modal_el = this.$obj.find('.scheduler__modal[data-modal="'+target+'"]');
    let modal_el_height = this.$obj.find('.scheduler__height',modal_el);
    let open_modal = !modal_el.hasClass('scheduler__modal--active');
    this.close_modal();
    if (open_modal) {
        setTimeout(function() {
            let extra = 10;
            modal_el.show().height(modal_el_height.outerHeight()+ extra);
            modal_el.addClass('scheduler__modal--active').height('auto').find('.close-modal').focus();
        }, 10);
    }
};
Scheduler.prototype.close_modal = function closeModal() {
    this.$obj.find('.scheduler__modal--active').each(function () {
        $(this).height(0).removeClass('scheduler__modal--active').hide();
    });
};
Scheduler.prototype.createToday = function createToday(){
    let _this = this;
    let today= '';
    let checkDateValue = _this.$obj.find('.scheduler-arrival');
    checkDateValue.on('change', function(){
        if (checkDateValue !== ''){
            console.log('date found');
            today = checkDateValue.val();
        }else {
            console.log('no date found');
            today = new Date();
        }
        _this.litepicker_modal(today);
    });
};
Scheduler.prototype.litepicker_modal = function litepicker_modal(today) {
    let _this = this;
    let toDate = new Date();
    toDate.setDate(toDate.getDate() + 2);
    let nextDay = new Date();
    nextDay.setDate(nextDay.getDate() + 2);
    let width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    const pickerTriggers = document.getElementsByClassName('scheduler__litepicker');
    for (let i = 0; i < pickerTriggers.length; i++) {
        let months = 2;
        let columns = 2;

        //modalpicker.destroy();
        //modalpicker.hide();
        let modalpicker = new Litepicker({
            element: pickerTriggers[i],
            inlineMode: true,
            format: 'YYYY MM DD',
            singleMode: false,
            numberOfMonths: months,
            numberOfColumns: columns,
            showTooltip: true,
            scrollToDate: true,
            minDate: today,
            startDate: (!today ? new Date():today),
            endDate: toDate,
            tooltipText: {
                one: 'night',
                other: 'nights'
            },
            tooltipNumber: (totalDays) => {
                return totalDays - 1;
            },
            setup: (modalpicker) => {
                // modalpicker.on('before:render', (ui) => {
                //     destroy(ui);
                //     show(ui);
                // });
                modalpicker.on('selected', (startDate, endDate) => {
                    // Update form fields
                    let startDateValue = _this.$obj.find('.scheduler-arrival')[0];
                    let endDateValue = _this.$obj.find('.scheduler-depart')[0];
                    startDateValue.setAttribute('value', startDate.format('YYYY-MM-DD'));
                    endDateValue.setAttribute('value', endDate.format('YYYY-MM-DD'));
                    _this.$obj.find('.checkin').text(startDate.format('MM/DD/YYYY'));
                    _this.$obj.find('.checkout').text(endDate.format('MM/DD/YYYY'));
                    // Hide Litepicker
                    _this.close_modal();
                });
            }
        });
    }
};
Scheduler.prototype.dept_picker = function dept_picker(){
    let _this = this;
    $('.dept').each(function(){
        let dept = $(this);
        dept.on('click',function(){
            // Department Data
            let date = $(this).find('.open-date').text();
            let name = $(this).find('.dept-name').text();

            // Form Fields
            let dept_value = $('.department-value');
            let arrival_input = $('.scheduler-arrival');

            // Update Form & Fields, Close Modal
            dept_value.text(name);
            if (date != ''){
                _this.$obj.find('.checkin').text(date);
                _this.$obj.find('.checkout').text('');
                _this.createToday();
                arrival_input.val(date).change();

            } else {
                let $error_text = _this.$obj.find('.submission-error');
                _this.$obj.find('.checkin').text('Add start date');
                arrival_input.val('');
                _this.$obj.find('.datepicker').attr('rel','date-modal');
                $error_text.text('');
            }
            if(this.closest('.modal-accordion__item')){
                $(".modal-accordion__item").hide();
            }
            if(this.closest('.department-modal')){
                _this.close_modal();
            }
        });
    });
};
/* Layout Styling */
    /* Hero Widget */
.scheduler{
    box-shadow: 2px 2px 9px rgba(0, 0, 0, 0.15);
    margin:0 auto;
    padding:24px 40px;
    position:relative;
    visibility:visible;
  padding-top:300px;
}
.submission-error{
    text-align:center;
    color:#aa0000;
    font-family: "Gotham Bold", sans serif;
    padding-bottom:24px;

}
.scheduler__fields{
    display:grid;
    grid-template-columns: repeat(2, 1fr);
    grid-column-gap: 20px;
    grid-row-gap:28px;
    position:relative;
}
.field-block{
    display:flex;
    gap:20px;
    flex:1;
}
.field-block:nth-child(2){
    grid-column: span 2;
}
.field-block__inner{
    width:100%;
    border-bottom:1px solid #000;
}

/* Element Styling */

.bw-mobile-toggle{
    background-color: #000;
    border:none;
    color:#fff;
    font-family: "Gotham Bold", sans serif;
    font-size: 18px;
    letter-spacing:0.06em;
    padding:26px 40px;
    position:fixed;
    bottom:0;
    left:0;
    text-transform: uppercase;
    width:100%;
}
.field-block__title, .modal-accordion__title{
    font-family:"Gotham Bold";
    font-size:14px;
    font-weight:400;
    line-height:17px;
    letter-spacing: 0.02em;
    margin-bottom:8px;
    text-transform:uppercase;
}
.bw-icon{
    margin-top:-4px;
    margin-right:12px;
}
/* promo code styling */
.modal-accordion__value input[type=text]{
    border:none;
    background:none;
    height:unset!important;
    padding:0;
    width:calc(100% - 42px);
}
.field-block__value, .modal-accordion__value{
    font-family:"Gotham Book Regular";
    font-weight:500;
    font-size:14px;
    line-height:15px;
}
.field-block__value input[type=text], .promo-value  input[type=text]{
    font-family:"Gotham Book Regular";
    font-weight:500;
    font-size:14px;
    line-height:15px;
    border: none;
    background: none;
    height: unset!important;
    padding: 0;
    width: calc(100% - 42px);
}
.field-block__value input:-webkit-autofill,
.field-block__value input:-webkit-autofill:hover,
.field-block__value input:-webkit-autofill:focus,
.promo-value input:-webkit-autofill,
.promo-value input:-webkit-autofill:hover,
.promo-value input:-webkit-autofill:focus

{
    -webkit-box-shadow: 0 0 0px 1000px #ffffff inset !important;
}
.scheduler__submit{
    background:#000;
    border:none;
    color:#fff;
    font-family:"Gotham Bold", serif;
    font-size: 14px;
    font-weight:400;
    line-height: 17px;
    letter-spacing: -0.01em;
    height:51px;
    text-transform: uppercase;
    width:100%;
}
.submit-container .scheduler__submit{
    position:absolute;
    bottom:25px;
    left:32px;
    width:calc(100% - 64px);
}

    /* Menu Widget */

    /* Modal Styling */
.scheduler__modal {
    box-shadow: 2px 2px 9px rgba(0, 0, 0, 0.15);
    height: 0;
    display: none;
    opacity: 0;
    transition: opacity 0.35s linear;
    padding: 16px 28px;
    position: relative;
    overflow: visible;
}
.scheduler__modal--active {
     position:absolute;
    bottom: 100px;
     background: #fff;
     height: 368px;
     opacity: 1;
     z-index: 9999999;
}
.close-modal{
    background:#fff;
    box-shadow: 2px 2px 9px rgba(0, 0, 0, 0.15);
    border:none;
    border-radius:50% / 50%;
    height:26px;
    width:26px;
    font-size:17px;
    font-family: "Gotham Book", sans-serif;
    position:absolute;
    right:-11px;
    text-transform: uppercase;
    top:-11px;
    z-index:2;
}

.close-icon{
    height:22px;
    width:22px;
}
.accordion-container{
    display:flex;
    flex-direction: column;
    gap:45px;
}
.checkin-accordion{
    margin-bottom:45px;
}
.modal-accordion{
    border-bottom:1px solid #000;
    background:#fff;
}
.modal-accordion .dept, .modal-accordion .department-selection{
    width:100%;
}
/* Modal Positions */
.header-modal{
    height:100vh !important;
    position:fixed;
    padding: 86px 28px 16px 28px;
    left:0;
    top:0;
    visibility: visible !important;
    width:100%;
}
.header-modal__container{
    overflow-y: auto;
    height:90%;
}
.department-modal{
    bottom:176px;
    left: 36px;
}
@media screen and (min-width:768px) {

}

@media screen and (min-width:1920px) {

}
.department-selection{
    max-height:350px;
    width:230px;
    overflow-y: scroll;
}

.department-selection::-webkit-scrollbar-track
{
    -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
    background-color: #F5F5F5;
}

.department-selection::-webkit-scrollbar
{
    width: 6px;
    background-color: #F5F5F5;
}

.department-selection::-webkit-scrollbar-thumb
{
    background-color: #000000;
}
.dept > .open-date{
    display:none;
}
.date-modal{
    left: calc(50% - 304px);
    bottom:176px;
}
@media screen and (min-width:1280px) {
    .department-modal{
        bottom:102px;
        left: 36px;
    }
    .date-modal{
        left:234px;
        bottom:102px;
    }
}
.dept{
    border:0;
    border-bottom:1px solid #000;
    background:none;
    display:block;
    padding:12px 8px;
    width:214px;
}


.dept:hover, .dept:focus{
    background:#000;
    color:#fff;
}.dept:last-of-type{
    border-bottom:none;
 }
/* Litepicker Styling */
.scheduler__litepicker{
    display:none;
    visibility:hidden;
}
.litepicker-center {
    text-align:center;
}
.litepicker .container__months{
    border-radius:0;
    box-shadow:none;
}
.litepicker .container__months .month-item-header .button-next-month>svg{
    fill:#000;
}
.month-item:nth-of-type(odd) .month-item-header .button-previous-month{
    width:22px;
    height:22px;
    background-image:url('../images/chevron.svg');
    visibility:visible;
    cursor: pointer;
}
.litepicker .container__days .day-item:hover{
    color:#000;
    box-shadow: inset 0 0 0 1px #000;
}
.litepicker .container__days .day-item.is-start-date{
    border-top-left-radius: 12px;
    border-bottom-left-radius: 12px;
}
.litepicker .container__days .day-item.is-end-date{
    border-top-right-radius: 12px;
    border-bottom-right-radius: 12px;
}
.litepicker .container__days .day-item.is-start-date, .litepicker .container__days .day-item.is-end-date, .litepicker .container__days .day-item.is-in-range{
    background-color: #000;
    color:#fff;
}

@media screen and (min-width:768px) {

    .scheduler{
        visibility:visible;
    }
}
@media screen and (min-width:1280px) {
    .scheduler__fields{
        grid-template-columns: repeat(4, 1fr)!important;
    }
}
@media screen and (min-width:1920px) {

}
<script src="https://cdn.jsdelivr.net/npm/litepicker/dist/litepicker.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="scheduler">
    <div class="scheduler__inner">
        <div class="scheduler__form">
            <form action="" method="GET" target="_blank" class="scheduler-form" name="scheduler">
                <div class="submission-error"></div>
                <input type="hidden" class="scheduler-input-department" name="department" value=""/>
                <input type="hidden" class="scheduler-arrival" id="arrivalDate" name="arrive" value="" />
                <input type="hidden" class="scheduler-depart" id="departDate" name="depart" value="" />
                <div class="scheduler__fields">
                    <div class="field-block modal-trigger" rel="department-modal">
                        <div class="field-block__inner">
                            <div class="field-block__title">
                                Select A Department
                            </div>
                            <div class="field-block__value">
                                <span class="department-value">Pick a department</span>
                            </div>
                        </div>
                    </div>
                    <div class="field-block datepicker modal-trigger" rel="date-modal">
                        <div class="field-block__inner">
                            <div class="field-block__title">
                                Start Date
                            </div>
                            <div class="field-block__value">
                                <span class="checkin">Add start date</span>
                            </div>
                        </div>
                        <div class="field-block__inner">
                            <div class="field-block__title">
                                End Date
                            </div>
                            <div class="field-block__value">
                                <span class="checkout">Add end date</span>
                            </div>
                        </div>
                    </div>
                    <div class="field-block">
                        <div class="field-block__inner">
                            <button type="submit" class="scheduler__submit">Submit Schedule</button>
                        </div>
                    </div>
                </div>
            </form>
        </div>
        <!-- Modals -->
        <div class="scheduler__modal department-modal" data-modal="department-modal">
            <button class="close-modal">X</button>
          <div class="department-selection" name="department"></div>
          <button class="dept" type="button">
                <span class="dept-name">Department 1</span>
                <span class="open-date"></span>
            </button>
            <button class="dept" type="button">
                <span class="dept-name">Department 2</span>
                <span class="open-date">March 31, 2023</span>
            </button>
            <button class="dept" type="button">
                <span class="dept-name">Department 3</span>
                <span class="open-date"></span>
            </button>
        </div>
      
        <div class="scheduler__modal date-modal" data-modal="date-modal">
            <button class="close-modal">X</button>
            <div class="scheduler__height">
                <input class="scheduler__litepicker">
            </div>
        </div>
    </div>
</section>


from how to stop litepicker from creating multiple instances

No comments:

Post a Comment