Product pages - Allow pre-orders for products

Jennifer42
Tourist
8 0 2

I would be so grateful If you have time to send me code modification please, that's the only thing missing for me !!! thank you so much @Alex-Miller 

 

0 Likes
sellysells
New Member
1 0 1

Did you ever get an answer? This is the issue with mine

Alex-Miller
Excursionist
16 2 3

Hi! Yes i solved this today!!

(Hat tip to @John_G2  for the inspiration to loop through the variants for their policy and quantity in liquid INSIDE the JS)

 

You can check the example on my development shop:

https://aimhuge-dev-dec20.myshopify.com/products/product-preorder

Password is 123456 (check the catalog → product-preorder)

 

How to do it?!

1. Followed the tutorial linked on the first page of this thread to create a new template option for products that allow preorder

https://community.shopify.com/c/Shopify-Design/Product-pages-Allow-pre-orders-for-products/m-p/62591...

2.  BUT skip this part of the tutorial

Alex-Miller_0-1613025289763.png

3) Replace the product strings bit of script in product.pre-order.liquid 

 

 

<script>
  theme.productStrings = {
    addToCart: {{ 'products.product.add_to_cart' | t | json }}, 
    unavailable: {{ 'products.product.unavailable' | t | json }},
    sold_out: {{ 'products.product.sold_out' | t | json }}
  }
</script>

 

 

with the following:

 

 

<script>
  // Override default values of shop.strings for each template.
  // Alternate product templates can change values of
  // add to cart button, sold out, and unavailable states here.
  // | t filter translates from strings files
  // there is no Pre-order string my default, so we add it without the t filter
  theme.productStrings = {
    addToCart: {{ 'products.product.add_to_cart' | t | json }}, 
    unavailable: {{ 'products.product.unavailable' | t | json }},
    sold_out: {{ 'products.product.sold_out' | t | json }},
    preorder: {{ 'Pre-order' | json }}
  }

  
  // inventory quantity and policy were depercated from liquid
  // https://community.shopify.com/c/API-Announcements/Deprecated-Notice-inventory-quantity-and-inventory-policy-fields/m-p/419770
  // but can be accessed by reading the product into a variable
  // and backfilling the inventory quanity & policy into the product
  const product = {{ product | json}}
  let v;
  {% for variant in product.variants %}
    v = getVariantById({{ variant.id}}) 
    v.inventory_quantity = {{ variant.inventory_quantity | json }}
    v.inventory_policy = {{ variant.inventory_policy | json }}
  {% endfor %}


  // then we just change the text of the CTA when the select is changed
  document.querySelector('.single-option-selector').onchange = ()=>{
    const selectEl = document.querySelector('[name="id"]') // the select
    const cta = document.querySelector('.product-form__cart-submit') // the CTA 
    
    setTimeout(()=>{ // requires a little delay for some reason
      const [options] = getSelectedOptions(selectEl)
      const variant = getVariantById(parseInt(options.value))
      if(variant.inventory_quantity > 0 ){
        cta.textContent = theme.productStrings.addToCart
      } else if( variant.inventory_policy === "continue" ){
        cta.textContent = theme.productStrings.preorder
      } else {
        cta.textContent = theme.productStrings.sold_out
      }
    },5)
  };

  // fire the event on page load (check if it's pre-order)
  document.querySelector('.single-option-selector').onchange()

  // helper functions
  function getVariantById(id){
    const [variant] = product.variants.filter( (v) => v.id === id )
    return variant
  }

  function getSelectedOptions(selectEl) {
    const result = [];
    const options = selectEl.getElementsByTagName('option');
    for (let i = 0; i < options.length; i++) {
        if (options[i].selected)
            result.push(options[i]);
    };
    return result;
  }
</script>

 

 

CC @Jennifer42 

AIMHUGE GROWTH CONSULTING
Alex@aimhuge.com
0 Likes
Alex-Miller
Excursionist
16 2 3

Script updated to handle products with only one variant (aka no variant selector)

 

<script>
  // Override default values of shop.strings for each template.
  // Alternate product templates can change values of
  // add to cart button, sold out, and unavailable states here.
  // | t filter translates from strings files
  // there is no Pre-order string my default, so we add it without the t filter
  theme.productStrings = {
    addToCart: {{ 'products.product.add_to_cart' | t | json }}, 
    unavailable: {{ 'products.product.unavailable' | t | json }},
    sold_out: {{ 'products.product.sold_out' | t | json }},
    preorder: {{ 'Pre-order' | json }}
  }

  
  // inventory quantity and policy were depercated from liquid
  // https://community.shopify.com/c/API-Announcements/Deprecated-Notice-inventory-quantity-and-inventory-policy-fields/m-p/419770
  // but can be accessed by reading the product into a variable
  // and backfilling the inventory quanity & policy into the product
  const product = {{ product | json}}
  let v;
  {% for variant in product.variants %}
    v = getVariantById({{ variant.id}}) 
    v.inventory_quantity = {{ variant.inventory_quantity | json }}
    v.inventory_policy = {{ variant.inventory_policy | json }}
  {% endfor %}

  const selectEl = document.querySelector('[name="id"]') // the select
  const cta = document.querySelector('.product-form__cart-submit') // the CTA 
  const currentVariant = getVariantById({{product.selected_or_first_available_variant.id}})
  
  // fire the event on page load (check if it's pre-order)
  updateCTA(currentVariant, cta)

  // then we just change the text of the CTA when the select is changed
  document.querySelector('.single-option-selector').onchange = ()=>{
    
    setTimeout(()=>{ // requires a little delay for some reason
      const [options] = getSelectedOptions(selectEl)
      const variant = getVariantById(parseInt(options.value))
      updateCTA(variant, cta)
    },5)
  };

  // helper functions
  function getVariantById(id){
    const [variant] = product.variants.filter( (v) => v.id === id )
    return variant
  }

  // update the cta based on the inventory quantity and policy
  function updateCTA(variant, ctaEl){
    if(variant.inventory_quantity > 0 ){
        return ctaEl.textContent = theme.productStrings.addToCart
      } else if( variant.inventory_policy === "continue" ){
        return ctaEl.textContent = theme.productStrings.preorder
      } else {
        return ctaEl.textContent = theme.productStrings.sold_out
    }
  }

  function getSelectedOptions(selectEl) {
    const result = [];
    const options = selectEl.getElementsByTagName('option');
    for (let i = 0; i < options.length; i++) {
        if (options[i].selected)
            result.push(options[i]);
    };
    return result;
  }
</script>

 

AIMHUGE GROWTH CONSULTING
Alex@aimhuge.com
0 Likes
zeffire
New Member
2 0 0

Thank you for the tip! I managed to do the pre-order and get it to work. However I would like to add a message in the section to inform the customer about delayed shipping.

zeffire_0-1614241718955.png

 

May I know how I should do that?

0 Likes
henriettaprice
New Member
3 0 0

Hi there, thank you so much for this tutorial, it worked perfectly! 

 

Im just wondering how to get the quantity picker showing when you have pre order template enabled. As its currently only the 'preorder' button available 

 

thanks so much! 

 

Henrietta 

0 Likes
hasheleyc
Excursionist
12 0 23

Sections > product template liquid > line 152 >         <div class="free_ship"><img width="50px" src="https://cdn0.iconfinder.com/data/icons/e-commerce-69/512/delivery-512.png"><span style="font-size: 20px;padding-left: 5px;">type your message about delayed shipping here</span></div>

 

This is the only way I could think of doing it.

amber101
New Member
1 0 0

Please help! After following all steps and disabling dynamic checkout, I cannot find the code/script: 

<span data-add-to-cart-text>
{% unless current_variant.available %}
{{ 'products.product.sold_out' | t }}
{% else %}
{{ 'products.product.add_to_cart' | t }}
{% endunless %}
</span>

anywhere !!  I'm stuck at step 11 I have the style narrative if that helps!

0 Likes
Algalsc
Excursionist
25 0 5

I'm also using Narrative and can't find the add-to-cart code to replace. My website is www.perfectdd.com, can you help enable pre-order please?

0 Likes
karenACC
New Member
1 0 1

I am excited about having a way for my customers to pre-order an item when it is out of stock. Will this automatically change to pre-order when an item is out of stock? Or do I have to manually mark each item to pre-order? Can I keep the variety out of stock that I want to change to pre-order in with the other same items? or do they have to be somewhere completely else on my website?