Facebook
From Hazel, 1 Month ago, written in JavaScript.
Embed
Download Paste or View Raw
Hits: 138
  1. [removed]
  2. try{
  3.  
  4. const ONETICK_PROPERTY_FLAG = '__onetick_checkbox_id'
  5. const ATC_BUTTON_ID = '__onetick_atc_button_id'
  6. class OnetickCheckbox extends HTMLElement {
  7.   constructor() {
  8.     super()
  9.   }
  10.   init() {
  11.     const checkboxInput = this.querySelector('.onetick-checkbox > input')
  12.     this.addEventListener('click', e => {
  13.       e.preventDefault()
  14.       e.stopPropagation()
  15.       checkboxInput.checked = !checkboxInput.checked
  16.     })
  17.   }
  18.   connectedCallback() {
  19.     this.init()
  20.   }
  21. }
  22. customElements.define('onetick-checkbox', OnetickCheckbox)
  23. ;(async function () {
  24.   let allowClick = true
  25.   window.addEventListener('load', async () => {
  26.     var _a
  27.     try {
  28.       const onetickCheckBoxes = [...document.querySelectorAll('.onetick-checkbox-container')]
  29.       if (!(onetickCheckBoxes == null ? void 0 : onetickCheckBoxes.length)) return
  30.       const sectionsWrapCheckbox = []
  31.       onetickCheckBoxes.forEach((checkBox, index) => {
  32.         const currentChecboxId = checkBox.getAttribute('data-checkbox-id')
  33.         if (!currentChecboxId) return checkBox.remove()
  34.         const closestSection = checkBox.closest('.shopify-section')
  35.         if (!closestSection) return checkBox.remove()
  36.        
  37. const atcButtons =     closestSection.querySelectorAll('form[action*="/cart/add"] button[type="submit"]')
  38.  
  39. const atcButton = atcButtons[atcButtons.length -1]
  40.         if (!atcButton) {
  41.           const warningBanner = checkBox.previousElementSibling
  42.           if (warningBanner) {
  43.             const errorMessageElement = warningBanner.querySelector('.onetick-error-message')
  44.             errorMessageElement[removed] = `Checkbox only works inside sections with product details. <a
  45.             href='https://help.ecomate.co/manual/why-my-checkbox-doesnt-show-on-my-theme/'
  46.             target='_blank'
  47.               48, 48, 1);'>
  48.            Learn more</a
  49.            >`
  50.            warningBanner.style.display = 'block'
  51.          }
  52.          return checkBox.remove()
  53.        }
  54.        const inputCheckbox = checkBox.querySelector('label[class="onetick-checkbox"] > input[type="checkbox"]')
  55.        if (!inputCheckbox) return checkBox.remove()
  56.        const currentSectionWrapperId = closestSection.getAttribute('id') || ''
  57.        if (
  58.          sectionsWrapCheckbox.find(
  59.            ({ sectionWrapperId, checkboxId }) =>
  60.              sectionWrapperId === closestSection.getAttribute('id') && checkboxId === currentChecboxId
  61.          )
  62.        ) {
  63.          const warningBanner = checkBox.previousElementSibling
  64.          if (warningBanner) {
  65.            warningBanner.style.display = 'block'
  66.          }
  67.          return checkBox.remove()
  68.        }
  69.        sectionsWrapCheckbox.push({
  70.          sectionWrapperId: currentSectionWrapperId || '',
  71.          checkboxId: currentChecboxId,
  72.          sectionElement: closestSection,
  73.          checkboxElement: checkBox,
  74.          inputCheckboxElement: inputCheckbox,
  75.          atcButtonElement: atcButton,
  76.        })
  77.      })
  78.      if (!sectionsWrapCheckbox.length) return
  79.      const uniqueSectionIds = [...new Set(sectionsWrapCheckbox.map(item => item.sectionWrapperId))]
  80.      uniqueSectionIds.forEach(sectionId => {
  81.        const checkboxesInCurrentSection = sectionsWrapCheckbox.filter(
  82.          ({ sectionWrapperId }) => sectionWrapperId === sectionId
  83.        )
  84.        const currentATCButton = checkboxesInCurrentSection[0].atcButtonElement
  85.        currentATCButton.addEventListener(
  86.          'click',
  87.          e => {
  88.            if (!allowClick) {
  89.              console.log('Prevent other click events')
  90.              e.preventDefault()
  91.              e.stopPropagation()
  92.              e.stopImmediatePropagation()
  93.            }
  94.          },
  95.          true
  96.        )
  97.        currentATCButton.addEventListener('mouseup', async e => {
  98.          allowClick = false
  99.          e.preventDefault()
  100.          e.stopPropagation()
  101.          e.stopImmediatePropagation()
  102.          currentATCButton.style.pointerEvents = 'none'
  103.          currentATCButton.style.cursor = 'not-allowed'
  104.          const formATCData = { items: [] }
  105.          checkboxesInCurrentSection.forEach(({ checkboxElement, checkboxId, inputCheckboxElement }) => {
  106.            const checkBoxUpsellVariantIds = checkboxElement.getAttribute('data-upsell-variant-ids') || ''
  107.            const upsellProducts = checkBoxUpsellVariantIds.split('; ')
  108.            const isCheckedInput = inputCheckboxElement.checked
  109.            if (!isCheckedInput) return
  110.            formATCData.items.push(
  111.              ...upsellProducts.map(p => ({
  112.                id: p,
  113.                quantity: 1,
  114.                properties: {
  115.                  [ONETICK_PROPERTY_FLAG]: checkboxId,
  116.                  [ATC_BUTTON_ID]: currentATCButton.getAttribute('id'),
  117.                },
  118.              }))
  119.            )
  120.          })
  121.          if (formATCData.items.length) {
  122.            await fetch(`${window.Shopify.routes.root}cart/add.js`, {
  123.              method: 'POST',
  124.              headers: {
  125.                'Content-Type': 'application/json',
  126.              },
  127.              body: JSON.stringify(formATCData),
  128.            })
  129.              .then(response => response.json())
  130.              .then(async () => {
  131.                await fetch(`${window.Shopify.routes.root}cart.js`)
  132.                  .then(response => response.json())
  133.                  .then(data => {
  134.                    return data
  135.                  })
  136.              })
  137.              .catch(error => console.error('Failed to upsell product:', error))
  138.          }
  139.          allowClick = true
  140.          currentATCButton.style.pointerEvents = 'auto'
  141.          currentATCButton.style.cursor = 'pointer'
  142.          currentATCButton.click()
  143.        })
  144.      }, true)
  145.      await fetch(
  146.        `undefined/api?public=true&shop;=${(_a = window.Shopify) == null ? void 0 : _a.shop}&type=GET_VALID_CHECKBOXES`
  147.      )
  148.        .then(res => res.json())
  149.        .then(res => {
  150.          if (!res.success) throw new Error(res.message)
  151.          const allActiveCheckboxes = res.data
  152.          const onetickCheckBoxes2 = [...document.querySelectorAll('.onetick-checkbox-container')]
  153.          onetickCheckBoxes2.forEach(checkBox => {
  154.            const currentChecboxId = checkBox.getAttribute('data-checkbox-id')
  155.            if (!allActiveCheckboxes.includes(currentChecboxId)) return checkBox.remove()
  156.          })
  157.        })
  158.        .catch(err => {
  159.          console.error('Failed to get valid checkboxes', err)
  160.        })
  161.      console.log('Run OneTick theme helper version 1.0.0')
  162.    } catch (error) {
  163.      console.error('Error occurs in OneTick helper:', error)
  164.    }
  165.  })
  166. })()
  167.  
  168. }catch(e){
  169. console.log(e);
  170. }
  171. [removed]