Skip to content
  1. Extras
  2. msProductDiscounts

Development ​

Changing styles ​

Wrong approach ​

  1. Add your styles below;
  2. Override values in them.

Correct approach ​

  1. Copy the standard file;
  2. Override the needed values;
  3. Set the new path in system setting ms_cdek2_frontend_css

Changing chunks ​

Which chunks to use is described in presets, similar to SendIt. To use your own chunks, set the path to your presets file in ms_cdek2_presets_path. Do not change preset parameters you don't understand.

Chunk parameters ​

  1. suggestItemTpl — chunk for address suggestion list item;
  2. listWrapTpl — pickup point list wrap chunk (must contain select[name="point"]);
  3. listItemTpl — pickup point list item chunk (must contain option);
  4. emptyTpl — chunk when no pickup points found by postal code;
  5. statusTpl — delivery status chunk.

Информация

To see available placeholders, use an empty value in the parameter (works only for statusTpl and listItemTpl)

Hide or change popup message ​

Popup texts are in lexicon files with keys:

  • ms_cdek2_error
  • ms_cdek2_choose_pvz_error_message

Change map zoom on init ​

js
document.addEventListener('mscdek:map:show', e => {
  const {object} = e.detail;
  object.mapUpdParams['zoom'] = 10;
})

Disallow suggestion selection when street is not entered and door delivery is selected ​

js
document.addEventListener('mscdek:address:select:suggestion', e => {
  const {location, object} = e.detail;
  const selectedDelivery = document.querySelector('[name="delivery"]:checked');
  if (!location.data.street && selectedDelivery.value === object.config.deliveriesByType.door) {
    e.preventDefault();
    object.sendit.Notify.error('Enter street');
  }
})

Change default status output to popup notification ​

Внимание

Remove the status output block from the page.

js
document.addEventListener('mscdek:status:get', e => {
  const {status, object} = e.detail;
  if (!object.statusBlock) {
    const message = `Delivery by ${status.calc_result.delivery_date_range.max} for ${status.delivery_cost}`
    object.sendit.Notify.info(message);
  }
})

Show map in modal ​

Внимание

This example uses Fancybox

Add modal open button, initially hidden with class .hide ​

html

<button type="button" class="hide" data-fancybox data-src="#map-modal">Select pickup point</button>

Add JS to toggle button visibility on page load and delivery method change ​

Информация

3 in toggleMapButton is the ID of pickup-point delivery method

js
const toggleMapButton = () => {
  const btn = document.querySelector('[data-src="#map-modal"]');
  const delivery = document.querySelector('[name=delivery]:checked');
  if (Number(delivery.value) === 3) {
    btn.classList.remove('hide');
  } else {
    btn.classList.add('hide');
  }
}

document.addEventListener('DOMContentLoaded', e => {
  toggleMapButton();
})

document.addEventListener('change', e => {
  if (e.target.name === 'delivery') {
    toggleMapButton();
  }
})

Put map block in modal ​

html
<div id="map-modal" style="display:none;width:800px;max-width: 100%">
    <div data-mscdek-map class="hide"></div>
</div>

Add code to open modal on button click ​

js
document.addEventListener('click', e => {
  if (e.target.closest('[data-src="#map-modal"]')) {
    Fancybox.show([{src: "#map-modal", type: "inline"}]);
  }
})

Output pickup point info and confirm selection with button ​

Информация

Assume the page does not have

html
<div class="hide" data-mscdek-list></div>

and instead has a hidden field

html
<input type="hidden" name="point">

Add pickup point info block template ​

html
<template data-mscdek-baloon>
    <div data-pvz-details class="hide">
        <h5>Address:<br>
            <span data-mscdek-prop="address"></span>
        </h5>
        <p>Hours:<br>
            <span data-mscdek-prop="work_time"></span>
        </p>
        <button id="select-pvz-btn" type="button">Select</button>
    </div>
</template>

Add styles for map block and info block ​

css
[data-mscdek-map] {
    position: relative;
}

[data-pvz-details]:not(.hide) {
    flex-direction: column;
    display: flex;
    align-items: start;
    justify-content: center;
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    background: rgba(0, 0, 0, .7);
    width: 40%;
    padding: 30px;
    color: white;
}

Insert info block into map block after init ​

js
document.addEventListener('mscdek:map:init', e => {
  const {mapBlock} = e.detail;

  if (!mapBlock.querySelector('[data-pvz-details]')) {
    const baloonTemplate = document.querySelector('[data-mscdek-baloon]');
    mapBlock.insertAdjacentHTML('beforeend', baloonTemplate.innerHTML);
    baloonTemplate.innerHTML = '';
  }
})

Output pickup point info ​

js
const showBaloon = (markerData) => {
  const baloon = document.querySelector('[data-pvz-details]');
  if (baloon) {
    const addressBlock = baloon.querySelector('[data-mscdek-prop="address"]');
    const workTimeBlock = baloon.querySelector('[data-mscdek-prop="work_time"]');
    addressBlock.innerHTML = markerData.location.address;
    workTimeBlock.innerHTML = markerData.work_time;

    baloon.classList.remove('hide');
    return true;
  }
  return false;
}

document.addEventListener('mscdek:map:choose', e => {
  const {markerData, object} = e.detail;
  showBaloon(markerData.properties)
})

Add pickup point selection confirmation handler ​

js
document.addEventListener('click', e => {
  if (e.target.closest('#select-pvz-btn')) {
    const addressBlock = document.querySelector('[data-pvz-details] [data-mscdek-prop="address"]');
    const pointField = document.querySelector('[name="point"]');
    pointField && (pointField.value = addressBlock.innerHTML);
    pointField && pointField.dispatchEvent(new Event('change', {bubbles: true}));

    /* SendIt.Notify.info(`Pickup: ${addressBlock.innerHTML}`); */ // uncomment to show popup with selected address
    /* Fancybox.close(); */ // uncomment to close modal after selection
  }
})

Change marker for pickup points with even ID ​

js
document.addEventListener('mscdek:marker:create', e => {
  const {marker, markerData} = e.detail;
  if (markerData.id % 2 === 0) {
    marker.querySelector('img').src = 'assets/marker.png';
  }
})