- @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;
})
}
})
})
}