- @do_dates_easypick = [] - @accommodation.accommodationprices.each do |avalability| - if avalability.not_available == true and avalability.datefrom != "" and avalability.datefrom != nil - do_dates = avalability.datefrom.to_s, avalability.dateto.to_s - @do_dates_easypick.append(do_dates) %script{src: "https://cdn.jsdelivr.net/npm/@easepick/bundle@1.2.1/dist/index.umd.min.js"} %input#propertyDatePicker :javascript //LISTINGS const listingsDatePicker = document.querySelector("#datepicker"); if (listingsDatePicker) { const currentLang = document.querySelector("html").getAttribute("lang") const translations = { "es" : { zero: "noche", one: "noche", two: "noches", few: "noches", many: "noches", other: "noches", minstay: "Estancia mínima", of : "de", of : "de", nights: "noches", notreached : "Estancia mínima requerida", maxGuests: "Max ocupantes", maxOccupationReached: "Max ocupantes superado" }, "en" : { zero: "night", one: "nights", two: "nights", few: "nights", many: "nights", other: "nights", minstay: "Min stay", of : "of", nights: "nights", notreached : "Min stay not reached", maxGuests: "Max guests", maxOccupationReached: "Max guests reached" }, "nl" : { zero: "nacht", one: "nacht", two: "nachten", few: "nachten", many: "nachten", other: "nachten", minstay: "Minimale verblijfsduur", of: "van", nights: "nachten", notreached: "Minimale verblijfsduur niet bereikt", maxGuests: "Maximaal aantal gasten", maxOccupationReached: "Maximaal aantal gasten bereikt" }, "fr" : { zero: "nuit", one: "nuit", two: "nuits", few: "nuits", many: "nuits", other: "nuits", minstay: "Durée minimale du séjour", of: "de", nights: "nuits", notreached: "Durée minimale du séjour non atteinte", maxGuests: "Nombre maximal d'invités", maxOccupationReached: "Nombre maximal d'invités atteint" }, } const picker = new easepick.create({ element: listingsDatePicker, css: [ "/wp-content/themes/inmobasolidbase/src/css/index.css", "/wp-content/themes/inmobasolidbase/src/css/custom-easepick.css", ], zIndex: 1000, grid: 2, calendars: 2, lang: currentLang, format: "DD-MM-YYYY", header: true, RangePlugin : { delimiter: listingsDatePicker.dataset.separator, locale: translations[currentLang], tooltipNumber(num) { return num - 1; }, }, LockPlugin: { minDate: new Date().toString(), inseparable: true }, plugins: [ "RangePlugin", "LockPlugin" ], header: "", setup(picker) { picker.on( 'render', _ => { document.querySelector(".easepick-wrapper").shadowRoot.querySelector("#picker-clear").addEventListener("click", (e) => { picker.clear(); document.querySelector("[name=gu]").reset(); document.querySelector("[name=gu]").disable(); const dateUnselectedText = document.querySelector("#guestLabels").parentElement.dataset.datesUnselected document.querySelector("input[name=gu] + .vscomp-toggle-button .vscomp-value").innerHTML = dateUnselectedText; document.querySelector("input[name=gu] ~ .vscomp-dropbox-container .vscomp-options .vscomp-option-text").innerHTML = dateUnselectedText; }) } ) picker.on( 'select', _ => { document.querySelector("[name=gu]").enable(); if (document.querySelector("[name=gu]").value == 0) { const dateSelectedText = document.querySelector("#guestLabels").parentElement.dataset.datesSelected document.querySelector("input[name=gu] + .vscomp-toggle-button .vscomp-value").innerHTML = dateSelectedText; document.querySelector("input[name=gu] ~ .vscomp-dropbox-container .vscomp-options .vscomp-option-text").innerHTML = dateSelectedText; } else { document.querySelector("[name=gu]").setValue(document.querySelector("[name=gu]").value); } } ) } }) } //LISTING const datePickerId = "#propertyDatePicker" const listingpicker = document.querySelector(datePickerId); const propGuestsId = "#propGuests" const prePaymentHolder = document.querySelector("[data-prepayment]"); const propGuestsSelector = document.querySelector(propGuestsId) const formIdElement = document.querySelector("#rentform"); const parameters = new URLSearchParams(window.location.search); const responseUrl = "/index.php?rentdata=1&"; //HELPERS const loadPriceChange = async (nightsNumber) => { const form = formIdElement; const formData = new FormData(form); const fetchParams = new URLSearchParams(formData).toString(); const results = await fetch(responseUrl + "?" + fetchParams, { method: "GET", headers: { 'Content-Type': 'application/json' } }) let resultData = {}; await results.json().then( async result => { ["curr","lang","ref","id_rate","from","to","id_room_type","guests","guests_rooms"].forEach ( i => formData.delete(i)); const paramsUrl = new URLSearchParams(formData).toString(); window.history.pushState("", "", window.location.pathname + "?" + paramsUrl); const resultPrice = result.totalPrice; const beConditions = result.beconditions; const reservationAmount = result.reservationAmount; const text = await formatPrice(nightsNumber,resultPrice,form); const maxGuests = result.maxGuests; resultData = {total: resultPrice, html : text, maxGuests: maxGuests, reservationAmount: reservationAmount, beconditions: beConditions}; }) return resultData; } const formatPriceNumber = (price,formElement) => { const formatter = getFormatter(formElement); return formatter.format(price); }; const formatPrice = async (nightsNumber,price,formElement) => { const formatter = getFormatter(formElement); return await nightsNumber + " " + (nightsNumber == 1 ? formElement.dataset.textNight : formElement.dataset.textNights) + " " + formElement.dataset.textFrom + " " + formatter.format(price) + ""; }; const getFormatter = (formElement) => { const currency = formElement.querySelector("[name=curr]") const lang = formElement.querySelector("[name=lang]"); return new Intl.NumberFormat(lang,{style:"currency",currency: currency.value.toLowerCase(),maximumFractionDigits:0, useGrouping: true}) } const formatDate = (dateTime,separator) => { return `${dateTime.getFullYear()}${separator}${dateTime.getMonth() + 1}${separator}${dateTime.getDate()}`; } let selfdisabled = false; let loaded = false; if (listingpicker) { const disabled = propGuestsSelector.dataset.disabled != "disabled" ? false : true; if (propGuestsSelector) { VirtualSelect.init({ ele: propGuestsSelector, hideClearButton: true, search: false, selectedValue: parameters.get("gu") ? parameters.get("gu") : 0, disabled: disabled ? true : false, silentInitialValueSet: true, ariaLabelText: propGuestsSelector.getAttribute("placeholder"), showDropboxAsPopup: false }); document.querySelector(propGuestsId).addEventListener("change", async function(e) { form.querySelector("[type=submit]").setAttribute("disabled",true); form.querySelector("[type=submit]").classList.add("disabled"); const dateSelected = formIdElement.querySelector(datePickerId).value const date1 = new Date(`${dateSelected.slice(6, 10)}-${dateSelected.slice(3, 5)}-${dateSelected.slice(0, 2)}`); const date2 = new Date(`${dateSelected.slice(6+13, 10+13)}-${dateSelected.slice(3+13, 5+13)}-${dateSelected.slice(0+13, 2+13)}`); const timeDifference = date2 - date1; const nightsNumber = timeDifference / (1000 * 60 * 60 * 24); if (nightsNumber) { if (totalpriceHolder) { totalpriceHolder.parentNode.style.opacity = "0.5"; totalpriceHolder.parentNode.classList.remove("fw-bold"); } const priceResult = await loadPriceChange(nightsNumber); if (priceResult.maxGuests >= this.value) { priceHolder.innerHTML = nightsNumber + " " + translations[lang].nights + "
" + formatPriceNumber(priceResult.total,formIdElement) ; priceHolder.setAttribute("data-totalPrice",priceResult.total); let servicePrice = parseFloat(0); document.querySelectorAll("[data-service-price]").forEach( item => { if (!isNaN(item.dataset.servicePrice)) { servicePrice += parseFloat(item.dataset.servicePrice); } }) const text = await formatPrice(nightsNumber,parseInt(priceResult.total)+parseInt(servicePrice),formIdElement); mainpriceHolder.innerHTML = text; if (totalpriceHolder) { totalpriceHolder.innerHTML = formatPriceNumber(parseInt(parseInt(priceResult.total)+parseInt(servicePrice)),formIdElement) totalpriceHolder.parentNode.removeAttribute("style"); totalpriceHolder.parentNode.classList.add("fw-bold"); } priceHolder.setAttribute("data-price",priceResult.total) priceHolder.removeAttribute("style"); form.querySelector("[type=submit]").removeAttribute("disabled"); form.querySelector("[type=submit]").classList.remove("disabled"); form.querySelector("[name=guests]").setAttribute("value",this.value) form.querySelector("[name=guests_rooms]").setAttribute("value",JSON.stringify([{"adults" : this.value, "children":0, "infant":0, "children_age" : [] }])); } else { priceHolder.innerHTML = translations[lang].maxGuests + " " + priceResult.maxGuests; mainpriceHolder.innerHTML = translations[lang].maxOccupationReached; totalpriceHolder.innerHTML = "---"; } } else { priceHolder.innerHTML = ""; priceHolder.style.opacity = 0; } }); } const lang = document.querySelector("html").getAttribute("lang"); const reference = formIdElement.querySelector('[name=ref]').value const roomtypeid = formIdElement.querySelector('[name=id_room_type]').value const translations = { "es" : { zero: "noche", one: "noche", two: "noches", few: "noches", many: "noches", other: "noches", minstay: "Estancia mínima", of : "de", nights: "noches", notreached : "Estancia mínima requerida", maxGuests: "Max ocupantes", maxOccupationReached: "Max ocupantes superado" }, "en" : { zero: "night", one: "nights", two: "nights", few: "nights", many: "nights", other: "nights", minstay: "Min stay", of : "of", nights: "nights", notreached : "Min stay not reached", maxGuests: "Max guests", maxOccupationReached: "Max guests reached" }, "nl" : { zero: "nacht", one: "nacht", two: "nachten", few: "nachten", many: "nachten", other: "nachten", minstay: "Minimale verblijfsduur", of: "van", nights: "nachten", notreached: "Minimale verblijfsduur niet bereikt", maxGuests: "Maximaal aantal gasten", maxOccupationReached: "Maximaal aantal gasten bereikt" }, "fr" : { zero: "nuit", one: "nuit", two: "nuits", few: "nuits", many: "nuits", other: "nuits", minstay: "Durée minimale du séjour", of: "de", nights: "nuits", notreached: "Durée minimale du séjour non atteinte", maxGuests: "Nombre maximal d'invités", maxOccupationReached: "Nombre maximal d'invités atteint" }, } parameters.append("ref",reference) parameters.append("id_room_type",roomtypeid) const fetchParams = parameters.toString(); const priceHolder = document.querySelector("#shortTermPrice"); const totalpriceHolder = document.querySelector("[data-totalpriceholder]"); const mainpriceHolder = document.querySelector("#mainPrice"); const form = formIdElement; const beConditionsHolder = document.querySelector("[data-id=beconditions]"); priceHolder.parentNode.style.opacity = 0.5; mainpriceHolder.style.opacity = 0.5; fetch(responseUrl + fetchParams, { method: "GET", headers: { 'Content-Type': 'application/json' } }).then (results => results.json()) .then( async jsonData => { const fetchResult = await jsonData; const reservationAmount= fetchResult?.reservationAmount; const maxGuests = fetchResult.maxGuests; const selectedGuests = document.querySelector(propGuestsId).value; const bookingprices = fetchResult.prices; const bookedDates = fetchResult.bookedDates; const beConditions = fetchResult.hasOwnProperty("beconditions") && fetchResult.beconditions ? fetchResult.beconditions[lang] : ""; priceHolder.removeAttribute("style"); const resultPrice = await fetchResult.totalPrice; const thisbookedDates = bookedDates.map(d => { if (d instanceof Array) { const start = new Date(d[0], 'YYYY-MM-DD'); const end = new Date(d[1], 'YYYY-MM-DD'); return [start, end]; } return new Date(d,'YYYY-MM-DD'); }); new easepick.create( { element: listingpicker, css: [ "/wp-content/themes/inmobasolidbase/src/css/index.css", "/wp-content/themes/inmobasolidbase/src/css/custom-easepick.css", ], zIndex: 1000, grid: 1, calendars: 1, lang: lang, inline: false, format: "DD-MM-YYYY", RangePlugin : { delimiter: listingpicker.dataset.separator, locale: translations[lang], tooltipNumber(num) { return num - 1; }, }, LockPlugin: { minDate: new Date().toString(), inseparable: true, filter(date, picked) { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2,'0') const day = String(date.getDate()).padStart(2,'0'); let askingprice = bookingprices.filter( item => { return item.date == `${year}-${month}-${day}` }); if (!askingprice.length) { return true; } if (picked.length === 1) { const incl = date.isBefore(picked[0]) ? '[)' : '(]'; return !picked[0].isSame(date, 'day') && date.inArray(thisbookedDates, incl); } return date.inArray(thisbookedDates, '[]'); }, }, plugins: [ "RangePlugin", "LockPlugin" ], header: ``, setup(picker) { picker.on("render", async _ => { document.querySelector(".easepick-wrapper").shadowRoot.querySelector("#picker-clear").addEventListener("click", (e) => { picker.clear(); document.querySelector("[name=gu]").reset(); document.querySelector("[name=gu]").disable(); const dateUnselectedText = document.querySelector("#propGuests").parentElement.dataset.datesUnselected document.querySelector("input[name=gu] + .vscomp-toggle-button .vscomp-value").innerHTML = dateUnselectedText; document.querySelector("input[name=gu] ~ .vscomp-dropbox-container .vscomp-options .vscomp-option-text").innerHTML = dateUnselectedText; }) if (picker.getStartDate() && picker.getEndDate()) { const startDate = picker.getStartDate(); const year = startDate.getFullYear(); const month = String(startDate.getMonth() + 1).padStart(2,'0') const day = String(startDate.getDate()).padStart(2,'0'); const minStay = bookingprices.filter( item => { return item.date == `${year}-${month}-${day}` }); const endDate = picker.getEndDate(); const nightsNumber = Math.round((endDate.getTime() - startDate.getTime()) / (60*60*24*1000)); if (!parameters.get("gu")) { document.querySelector("[name=gu] .vscomp-value").innerHTML = document.querySelector("[name=gu]").parentNode.dataset.datesSelected; } const loadHtml = async () => { if (maxGuests < parameters.get("gu")) { mainpriceHolder.innerHTML = translations[lang].maxOccupationReached totalpriceHolder.innerHTML = translations[lang].maxOccupationReached } else if (!parseInt(minStay[0].minstay) || parseInt(minStay[0].minstay) <= parseInt(nightsNumber)) { priceHolder.innerHTML = nightsNumber + " " + translations[lang].nights + "
" + formatPriceNumber(resultPrice,formIdElement) ; priceHolder.setAttribute("data-totalPrice",resultPrice ? resultPrice : 0); let servicePrice = parseFloat(0); document.querySelectorAll("[data-service-price]").forEach( item => { if (!isNaN(item.dataset.servicePrice)) { servicePrice += parseFloat(item.dataset.servicePrice); } }) const text = await formatPrice(nightsNumber,parseInt(resultPrice)+parseInt(servicePrice),formIdElement); mainpriceHolder.innerHTML = text; if (totalpriceHolder) { totalpriceHolder.innerHTML = formatPriceNumber(parseInt(parseInt(resultPrice)+parseInt(servicePrice)),formIdElement) totalpriceHolder.parentNode.removeAttribute("style"); totalpriceHolder.parentNode.classList.add("fw-bold"); } } else { if (minStay[0].hasOwnProperty("minstay")) { priceHolder.innerHTML = nightsNumber; totalpriceHolder.innerHTML = `${translations[lang].minstay} ${translations[lang].of} ${minStay[0].minstay} ${translations[lang].nights}`; mainpriceHolder.innerHTML = `${translations[lang].minstay} ${translations[lang].of} ${minStay[0].minstay} ${translations[lang].nights}`; } else { priceHolder.innerHTML = `${translations[lang]["notreached"]}`; totalpriceHolder.innerHTML = `${translations[lang]["notreached"]}`; } form.querySelector("button[type=submit]").classList.add("disabled"); form.querySelector("button[type=submit]").setAttribute("disabled",true); priceHolder.removeAttribute("style"); totalpriceHolder.parentNode.removeAttribute("style") totalpriceHolder.parentNode.classList.add("fw-bold"); } if (beConditions) { beConditionsHolder.classList.add(...["small","mt-4"]); beConditionsHolder.innerHTML = beConditions; } mainpriceHolder.removeAttribute("style"); } if (!loaded) { await loadHtml(); priceHolder.removeAttribute("style"); } loaded = true; } }), picker.on("view", async evt => { let prices = []; bookingprices.forEach( x => { prices[x.date] = Math.ceil(x.price); }); const { view, date, target } = evt.detail; const d = date ? date.format('YYYY-MM-DD') : null; if (view === 'CalendarDay' && prices[d]) { const span = target.querySelector('.day-price') || document.createElement('span'); span.className = 'day-price'; span.innerHTML = `€${prices[d]}`; target.append(span); } }), picker.on("select", async e => { if (totalpriceHolder) { totalpriceHolder.parentNode.style.opacity = 0.5; totalpriceHolder.parentNode.classList.remove("fw-bold"); } document.querySelector("[name=gu]").enable(); const startDate = picker.getStartDate(); const endDate = picker.getEndDate(); const year = startDate.getFullYear(); const month = String(startDate.getMonth() + 1).padStart(2,'0') const day = String(startDate.getDate()).padStart(2,'0'); const minStay = bookingprices.filter( item => { return item.date == `${year}-${month}-${day}` }); const nightsNumber = Math.round((endDate.getTime() - startDate.getTime()) / (60*60*24*1000)) ; const loadHtml = async () => { priceHolder.style.opacity = 0.5; mainpriceHolder.style.opacity = 0.5; const totalPrice = await loadPriceChange(nightsNumber); const beConditions = totalPrice.hasOwnProperty("beconditions") && totalPrice.beconditions ? totalPrice.beconditions[lang] : ""; if (maxGuests < selectedGuests) { mainpriceHolder.innerHTML = translations[lang].maxOccupationReached } else if (!parseInt(minStay[0].minstay) || parseInt(minStay[0].minstay) <= parseInt(nightsNumber)) { priceHolder.innerHTML = nightsNumber + " " + translations[lang].nights + "
" + formatPriceNumber(totalPrice.total,formIdElement) ; priceHolder.dataset.totalprice = totalPrice.total; priceHolder.removeAttribute("style"); if (totalpriceHolder) { let servicePrice = parseFloat(0); document.querySelectorAll("[data-service-price]").forEach( item => { if (!isNaN(item.dataset.servicePrice)) { servicePrice += parseFloat(item.dataset.servicePrice); } }) totalpriceHolder.innerHTML = formatPriceNumber(parseInt(parseInt(totalPrice.total)+parseInt(servicePrice)),formIdElement) totalpriceHolder.parentNode.removeAttribute("style"); totalpriceHolder.parentNode.classList.add("fw-bold"); form.querySelector("[type=submit]").removeAttribute("disabled") form.querySelector("[type=submit]").classList.remove("disabled") const text = await formatPrice(nightsNumber,parseInt(totalPrice.total)+parseInt(servicePrice),formIdElement); mainpriceHolder.innerHTML = text; mainpriceHolder.removeAttribute("style"); } form.querySelector("[name=from]").value = formatDate(startDate,"-"); form.querySelector("[name=to]").value = formatDate(endDate,"-"); } else { if (minStay[0].hasOwnProperty("minstay")) { priceHolder.innerHTML = nightsNumber; totalpriceHolder.innerHTML = `${translations[lang].minstay} ${translations[lang].of} ${minStay[0].minstay} ${translations[lang].nights}`; mainpriceHolder.innerHTML = `${translations[lang].minstay} ${translations[lang].of} ${minStay[0].minstay} ${translations[lang].nights}`; } else { priceHolder.innerHTML = `${translations[lang]["notreached"]}`; totalpriceHolder.innerHTML = `${translations[lang]["notreached"]}`; } priceHolder.removeAttribute("style"); totalpriceHolder.parentNode.removeAttribute("style") totalpriceHolder.parentNode.classList.add("fw-bold"); form.querySelector("button[type=submit]").classList.add("disabled"); form.querySelector("button[type=submit]").setAttribute("disabled",true); } if (beConditionsHolder && beConditions) { if (!beConditionsHolder.classList.contains("mt-4")) { beConditionsHolder.classList.add(...["mt-4","small"]); } beConditionsHolder.innerHTML = beConditions; } } await loadHtml(); }); picker.on("preselect" , async e => { priceHolder.style.opacity = 0.5; }) } }) }) }