Skip to content

Instantly share code, notes, and snippets.

@gterrill
Last active November 22, 2017 07:01
Show Gist options
  • Save gterrill/9676668 to your computer and use it in GitHub Desktop.
Save gterrill/9676668 to your computer and use it in GitHub Desktop.
Capturing booking names on the booking form
<div class="booking-form">
<!-- normal booking form properties here -->
<div id="booking-names">
<div class="selector-wrapper booking-name">
{% capture attribute %}booking-name{% endcapture %}
<label for="{{ attribute }}">Name:</label>
<input id="{{ attribute }}" type="text" name="properties[{{ attribute }}]" class="bta-load-enable required" />
</div>
</div>
</div>
<script>
$(document).ready(function() {
validator = $('form[action*="/cart/add"]').validate();
$('select[name="quantity"]').change(function() {
var qty = $(this).val(),
template = $('.booking-name:first');
validator.resetForm();
$('.booking-name:gt(0)').remove();
for (i = 1; i < qty; i++) {
var clone = template.clone();
clone.find('span.counter').html(i+1);
$(clone).find('input, select').each(function() {
var elem = $(this),
label = elem.closest('label'),
id = elem.attr('id'),
name = elem.attr('name');
id = id.substring(0, id.lastIndexOf('-')) + '-' + (i+1);
name = name.substring(0, name.lastIndexOf(']')) + ' ' + (i+1) + ']';
label.attr('for', id);
elem.attr('id', id);
elem.attr('id', id).attr('name', name).val('');
});
clone.appendTo($('#booking-names'));
})
})
</script>
@gterrill
Copy link
Author

{% comment %}
BookThatApp 'Form 5 - Upcoming Events'
{% endcomment %}

{% if product.metafields.bookthatapp.config %}
{% unless bta_configured %}

{{ 'jquery.validate.min.js' | asset_url | script_tag }}

<div class="booking-form">
  <table id="events" class="bta-upcoming-events-table" style="width:100%"
    data-handle="{{ product.handle }}" data-name="Date"
    data-bta-max-events="12" data-bta-months="6" data-bta-low-capacity="4"
    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-available-label="Space Available"
    data-partially-available-label="{available} Places Remaining"
    data-last-available-label="1 Place Remaining"
    data-booked-out-label="No Space Available">
  	<tr><td colspan="3" class="loading">Loading...</td></tr>
  </table>
									
  <fieldset class="class-attendees">
    <legend>Participant details</legend>
    
    <div class="selector-wrapper booking-name">
      <label for="attendee-name">Name:</label>
      <input id="attendee-name" type="text" name="properties[Name 1]" class="required" placeholder="Participant Name (required)" />
    </div>

    <div class="selector-wrapper booking-email">
      <label for="attendee-email">Email:</label>
      <input id="attendee-email" type="email" name="properties[Email 1]" class="required" placeholder="Participant Email (required)" />
      <p class="small">*the reminder email will be sent to this address</p>
    </div>
  </fieldset>
</div>

<script>
  validator = $('form[action*="/cart/add"]').validate();
  
  ordinal = function(n) {
    var s=["th","st","nd","rd"],
        v=n%100;
    return n+(s[(v-20)%10]||s[v]||s[0]);
  }  

  updateAttendeeFields = function() {
    var qty = $('#quantity').val(),
        template = $('div.booking-name:first');

    validator.resetForm();
    
    $('.booking-name:gt(0)').remove();

    for (i = 1; i < qty; i++) {
      var clone = template.clone(),
          id = 'attendee-name-' + (i + 1);

      clone.find('label').attr('for', id);
      clone.find('input')
      	.attr('id', id)
      	.attr('name', 'properties[Name ' + (i + 1) + ']')
      	.attr('placeholder', ordinal(i + 1) + ' Participant Name')
      	.val('');
      
      $('.class-attendees').append(clone);
    }
  }
  
  document.addEventListener("DOMContentLoaded", function(event) {
    $('form[action="/cart/add"]').on('bta.upcomingEventsLoaded', function(event, form) {
      if ($('#events tr').length == 0) {
        $('#events').append("<tr><td colspan='3'><i>No events are scheduled at this time. Please check back later.</i></td></tr>");
      }

      if ($('#events tr').length == 0 || $('#events input[type=radio]').not(':disabled').length == 0) {
        // no scheduled events are available - disable the add to cart button
        $(':submit', $(this)).prop('disabled', true);
      }
    });

    var forms = document.forms;
    for (var x = 0; x < forms.length; x++) {
      if (forms[x].action.indexOf('/cart/add') > -1) {
        // prevent form submit until bta has finished loading
        forms[x].addEventListener("submit", function (event) {
          // check if bta has loaded
          if (!this.classList.contains("bta-active")) {
            event.preventDefault();
          }
        }, true);
      }
    }
    
    $('a.plus_btn, a.minus_btn').click(updateAttendeeFields);
    $('input[name="quantity"]').change(updateAttendeeFields);
  });
</script>
{% assign bta_configured = true %}
{% endunless %}
{% endif %}

@gterrill
Copy link
Author

2 col responsive layout:

#booking-names {
  margin: 20px 5px;
  padding: 10px;
  width: 100%;
  
  .booking-name {
    margin-top: 10px;
    font-size: smaller;

    .row {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      margin: 0 -10px;
    }
    
    .column {
      flex-basis: 100%;
      margin: 5px 0;
      padding: 0 10px;
      
      input, select {
        width: 100%;
        font-size: smaller;
      }
    }

    @media screen and (min-width: 800px) {
      .column {
        flex: 1;
      }
    }    
    
    label {
      display: block;
    }
        
    label.error {
      color: red;
    }
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment