Skip to content

Instantly share code, notes, and snippets.

@gterrill
Last active June 3, 2020 08:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gterrill/616576fa3b78ba602342f235dea767ee to your computer and use it in GitHub Desktop.
Save gterrill/616576fa3b78ba602342f235dea767ee to your computer and use it in GitHub Desktop.
Booking Form allowing units, and updating qty with number of units * days

Instructions:

  1. Add a hidden quantity field for BTA products in the booking-form.liquid snippet:

    <input type="hidden" id="quantity" name="quantity" value="1" />

  2. Make sure the normal quantity input is not rendered for BTA products (e.g. in sections/product-template.liquid).

For example, this is how it should look on the Debut theme (sections/product-template.liquid:183):

            {% if section.settings.show_quantity_selector %}
              {% unless product.metafields.bookthatapp.config %}
              <div class="product-form__item product-form__item--quantity">
                <label for="Quantity">{{ 'products.product.quantity' | t }}</label>
                <input type="number" id="Quantity" name="quantity" value="1" min="1" class="product-form__input" pattern="[0-9]*">
              </div>
              {% endunless %}
            {% endif %}
  1. Add the input for units:

<input type="number" id="units" name="properties[Units]" value="1" min="1" pattern="[0-9]*" />

Note: this is just a regular line item property with the name 'Units'.

It should go just after <div class="booking-form">

You will probably need to copy the markup/CSS classes so that it looks nice. Here is how it should look for Debut (including the hidden quantity input field):

<input type="hidden" id="quantity" name="quantity" value="1" />
  
<div class="product-form__item product-form__item--quantity">
  <label for="Quantity">{{ 'products.product.quantity' | t }}</label>
  <input type="number" id="units" name="properties[Units]" value="1" min="1" class="product-form__input" pattern="[0-9]*" />
</div>
  1. Copy the ProductRental Javascript to the booking form snippet (it goes inside the <script> tags).

  2. Update cart.liquid as per the cart template section.

  3. If the theme shows a count of items in the cart header update it per the cart count section.

Please contact us at support@zetya.com if you need help with this or would like a quote to have us install it for you.

{% if product.metafields.bookthatapp.config %}
<div class="booking-form">
<div>
{% capture attribute %}booking-start{% endcapture %}
<label for="{{ attribute }}-{{ product.handle }}">From:</label>
<input id="{{ attribute }}-{{ product.handle }}" type="text" name="properties[From]" size="12" class="datepicker bta required bta-load-enable bta-dp-start" disabled="disabled"
data-handle="{{ product.handle }}" data-variant="{{ product.selected_or_first_available_variant.id }}"
data-bta-product-config="{{ product.metafields.bookthatapp.config }}"
data-bta-variant-config="{% for variant in product.variants %}{{ variant.id }}:{{ variant.metafields.bookthatapp.config }}{% unless forloop.last %},{% endunless %}{% endfor %}"
data-bta-range-partner-id="#booking-finish-{{ product.handle }}"
data-bta-range-days-max="0" data-bta-range-days-min="0" />
</div>
<div>
{% capture attribute %}booking-finish{% endcapture %}
<label for="{{ attribute }}-{{ product.handle }}">To:</label>
<input id="{{ attribute }}-{{ product.handle }}" type="text" name="properties[To]" size="12" class="datepicker bta required bta-load-enable bta-dp-finish" disabled="disabled"
data-bta-range-partner-id="#booking-start-{{ product.handle }}" />
</div>
<div class="quantity">
<label for="quantity">Quantity:</label>
{% comment %}
<div class="rental-summary">
Days: <span class="rental-days"></span><br>
Total: <span class="rental-total"></span>
</div>
{% endcomment %}
<input type="number" id="units" name="properties[Units]" value="1" min="1" pattern="[0-9]*" />
</div>
<div class="bta-validation-messages" style="display:none">
<p class="bta-validation-date-missing">Please select a date</p>
</div>
<input type="hidden" id="quantity" name="quantity" value="1" />
</div>
<script>
// rental product behaviour
var ProductRental = function() {
_this = this;
this.configs = {};
this.durations = [];
this.init = function() {
'{{ product.metafields.bookthatapp.config }}'.replace(new RegExp("([^?=&]+)(=([^&]*))?", "g"), function($0, $1, $2, $3) {_this.configs[$1] = $3;});
_this.durations = JSON.parse(unescape(_this.configs.durations)).sort(function(a, b) {
return a.position - b.position;
});
_this.hideDurationOptionSelect();
_this.initFormListeners();
};
this.initFormListeners = function() {
var form = $('form[action="/cart/add"]');
form.on('bta.dataLoaded, bta.datetimeChange', function(event, form) {
_this.updateQuantity();
});
form.on('click', '.js-qty__adjust', function() {
_this.updateQuantity();
});
$('#units').change(function() {
_this.updateQuantity();
});
};
this.updateQuantity = function() {
var form = $('form[action="/cart/add"]').data('bta.bookingForm'),
start = form.getStartDateTime(),
finish = form.getFinishDateTime();
$('.rental-summary .rental-total').text('-');
$('.rental-summary .rental-days').text('-');
if (start && finish) {
var days = form.rangeCount();
// total rent = number of units * number of days * variant.price
var variantId = bta.findSelectedVariantId(),
units = parseInt($('#units').val(), 10),
variant = _this.findVariant(variantId),
total = variant.price * units * days;
$('#quantity').val(units * days);
$('.rental-summary .rental-days').text(days);
$('.rental-summary .rental-total').text(_this.formatMoney(total));
}
};
this.findVariant = function(id) {
for (var i = 0; i < _this.product.variants.length; i++) {
if (_this.product.variants[i].id == id) {
return _this.product.variants[i];
}
}
};
this.hideDurationOptionSelect = function() {
// hide option for duration (bypass .selector-wrapper inside booking form)
$('.selector-wrapper:nth-child(' + _this.configs['duration_option_position'] + ')').filter(function(index) {
return $(this).parents('.booking-form').length == 0;
}).hide();
};
this.formatMoney = function(total) {
return Shopify.formatMoney(total, '{{ shop.money_format }}')
};
this.product = {{ product | json }};
}
document.addEventListener("DOMContentLoaded", function(event) {
new ProductRental().init();
});
var bta = {
productId: {{ product.id }}
}
</script>
{% endif %}
{% assign cart_count = 0 %}
{% for item in cart.items %}
{% if item.product.metafields.bookthatapp.config %}
{% assign cart_count = cart_count | plus: item.properties.Units %}
{% else %}
{% assign cart_count = item.quantity %}
{% endif %}
{% endfor %}
<span class="icon-cart"></span> {{ 'layout.general.cart' | t }} (<span class="cart_count">{{ cart_count }}</span>)
1. Display line item property dates:
{% if item.product.metafields.bookthatapp.config %}
<p>{{ item.properties.From }} - {{ item.properties.To }}</p>
{% else %}
// ususal guff
{% endif %}
2. Show units for quantity:
{% if item.product.metafields.bookthatapp.config %}
{{ item.quantity | divided_by: item.properties.Units }} days x {{ item.properties.Units }}
<input type="hidden" name="updates[]" id="Updates_{{ item.id }}" value="{{ item.quantity }}" data-line="{{ forloop.index }}">
<a href="/cart/change?line={{ forloop.index }}&quantity=0">Remove</a>
{% else %}
<input type="number" name="updates[]" id="updates_{{ item.id }}" value="{{ item.quantity }}" min="0" data-line="{{ forloop.index }}">
{% endif %}
/* BookThatApp */
.booking-form {
display: -ms-flex;
display: -webkit-flex;
display: flex;
> div {
padding: 10px 0;
margin-right: 20px;
}
> div:last-child {
margin-right: 0px;
}
#units {min-width: 50px}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment