Upcoming

How to Create Pre-Workout Supplement Landing Page Using Elementor Free

Tools and Links Used

Hostinger Fast, beginner friendly WordPress hosting.
Get Hosting
Elementor The free page builder this tutorial is built with.
Get Elementor
Elementor Pro The Pro upgrade used throughout this tutorial.
Get Elementor Pro
Kitninja eCommerce Elementor template kits.
Get Templates
Kitpapa Ready made Elementor template kits.
Get Templates
Project Files Download the resources used in this tutorial.
Download Files

Prompt Used in This Tutorial

Product Shortcode
[custom_product id="YOUR_PRODUCT_ID"]
Checkout Form CSS
<style>
form.checkout.woocommerce-checkout {
    flex-direction: column-reverse;
}


/==Product Design==/

.cp-title {
    font-family: 'Bebas Neue';
    font-style: normal;
    font-weight: 400;
    font-size: 46px;
    line-height: 48px;
    letter-spacing: -0.005em;
    color: #FAFAFF;
    margin-bottom: 20px;
}

.cp-price {
    display: flex;
    justify-content: space-between;
}

.cp-price::before {
    content: '1 Product ';
    font-family: 'Bebas Neue';
    font-style: normal;
    font-weight: 400;
    font-size: 46px;
    line-height: 48px;
    letter-spacing: -0.005em;
    color: #FAFAFF;
}

.cp-price .woocommerce-Price-amount.amount {
    font-family: 'Bebas Neue';
    font-style: normal;
    font-weight: 400;
    font-size: 46px;
    line-height: 48px;
    letter-spacing: -0.005em;
    color: #FAFAFF;
}

.cp-price {
    padding-bottom: 7px;
    border-bottom: 1px solid #FAFAFF;
    margin-bottom: 20px;
}


select.cp-attr {
    font-family: DM Sans;
    font-weight: 500;
    font-size: 24px;
    line-height: 28px;
    letter-spacing: -0.5%;
    text-align: left;
    width: calc((100% - 20px) / 2);
    margin: 0;
    padding: 11.5px 25px;
    border-radius: 20px;
}
select.cp-attr + select.cp-attr {
    margin-left: 20px;
}
.custom-product-wrap {
    font-size: 0;
}

.qty-btn, .custom_qty {
    font-family: 'DM Sans';
    font-style: normal;
    font-weight: 500;
    font-size: 24px;
    line-height: 28px;
    letter-spacing: -0.005em;
    color: #000107;
}

.custom-qty-wrap{
  display:flex;
  gap:0 12px;
  align-items:center;
  margin:20px 0;
  flex-wrap: wrap;
}
.custom-qty-box{
  display:flex;
  align-items:center;
  border-radius:6px;
  overflow:hidden;
  gap: 20px;
  width: 100%;
}
.custom-qty-box input{
  width:23.73%;
  height:58px;
  border:0;
  text-align:center;
  outline:none;
  border-radius: 20px;
}
.qty-btn {
    width: 34.748%;
    height: 54px;
    border: 0;
    background: #f5f5f5;
    cursor: pointer;
    font-size: 20px;
    padding: 0 !important;
    border-radius: 20px;
}


.custom_buy_now{
  height:42px;
  padding:0 18px;
  border:0;
  background:#111;
  color:#fff;
  border-radius:6px;
  cursor:pointer;
}

.custom-product-wrap.is-loading {
  pointer-events: none;
  opacity: 0.72;
  transition: opacity 0.25s ease;
}

.custom_buy_now.is-loading {
  opacity: 0.7;
  cursor: wait;
}

.checkout-refreshing #order_review,
.checkout-refreshing .woocommerce-checkout-review-order-table,
.checkout-refreshing .cartflows-checkout__order-review,
.checkout-refreshing .wcf-checkout-summary-wrap {
  opacity: 0.45;
  transition: opacity 0.25s ease;
}

#order_review,
.woocommerce-checkout-review-order-table,
.cartflows-checkout__order-review,
.wcf-checkout-summary-wrap {
  transition: opacity 0.25s ease;
}



.custom-update-status{
  margin-top:2px;
  font-size:13px;
  line-height:1.4;
  color:#666;
  min-height:18px;
  transition:opacity 0.25s ease, color 0.25s ease;
}

.custom-update-status.is-loading{
  color:#111;
}

.custom-update-status.is-success{
  color:green;
}

.custom-update-status.is-error{
  color:#c62828;
}


.custom-product-wrap.is-loading {
  opacity: 0.72;
  transition: opacity 0.25s ease;
}

.checkout-refreshing #order_review,
.checkout-refreshing .woocommerce-checkout-review-order-table,
.checkout-refreshing .cartflows-checkout__order-review,
.checkout-refreshing .wcf-checkout-summary-wrap {
  opacity: 0.45;
  transition: opacity 0.25s ease;
}

#order_review,
.woocommerce-checkout-review-order-table,
.cartflows-checkout__order-review,
.wcf-checkout-summary-wrap {
  transition: opacity 0.25s ease;
}

.custom-update-status{
  margin-top:2px;
  font-size:13px;
  line-height:1.4;
  color:#666;
  min-height:18px;
  transition:opacity 0.25s ease, color 0.25s ease;
}

.custom-update-status.is-loading{
  color:#111;
}

.custom-update-status.is-success{
  color:green;
}

.custom-update-status.is-error{
  color:#c62828;
}

/=== Product overview ==/
#order_review thead {
    display: none;
}


/======================/
/*  Checkout SECTION  */
/======================/

.custom-checkout-form #customer_info {
    display: none;
}

.custom-checkout-form #order_review_heading {
    display: none !important;
}

#billing_fields_heading {
    margin-top: 40px;
    margin-bottom: 20px;
}

.input-text {
    padding: 0 0 9px 0 !important;
}

.select2-selection {
    padding: 0 0 10px 0 !important;
}


.form-row:not(:last-child) {
    margin-bottom: 40px !important;
}

h3#payment_options_heading {
    margin: 0 0 20px;
}

button#place_order {
    box-shadow: inset 0px 4.48869px 5.15229px rgba(0, 1, 7, 0.36), inset 0px -4.92792px 5.15229px rgba(250, 250, 255, 0.25);
    margin-top: 22px;
}

.input-text::placeholder {
    color: #6E6E6E !important;
}


.custom-payment-wrapper {
    display: none;
    opacity: 0;
}

/* ✅ FIX: Show payment wrapper once it has content */
.custom-payment-wrapper:not(:empty) {
    display: block;
    opacity: 1;
}
</style>


<script>
jQuery(function ($) {

  function normalizeKey(key) {
    if (key === undefined || key === null) return '';
    return String(key).replace(/^attribute_/, '').trim().toLowerCase();
  }

  function normalizeValue(value) {
    if (value === undefined || value === null) return '';
    return String(value).trim().toLowerCase().replace(/s+/g, '-');
  }

  function getAttributesForMatch($wrap) {
    let attributes = {};

    $wrap.find('.cp-attr').each(function () {
      let rawName = $(this).attr('name') || '';
      let cleanName = normalizeKey(rawName);
      let val = $(this).val();

      if (val !== '') {
        attributes[cleanName] = normalizeValue(val);
      }
    });

    return attributes;
  }

  function getAttributesForAjax($wrap) {
    let attributes = {};

    $wrap.find('.cp-attr').each(function () {
      let rawName = $(this).attr('name') || '';
      let val = $(this).val();

      if (val !== '') {
        attributes[rawName] = val;
      }
    });

    return attributes;
  }

  function findVariation(variations, selectedAttributes) {
    if (!variations || !variations.length) return null;

    for (let i = 0; i < variations.length; i++) {
      let variation = variations[i];
      let match = true;

      for (let key in variation.attributes) {
        let cleanKey = normalizeKey(key);
        let variationValue = normalizeValue(variation.attributes[key]);
        let selectedValue = normalizeValue(selectedAttributes[cleanKey]);

        if (variationValue !== '') {
          if (variationValue !== selectedValue) {
            match = false;
            break;
          }
        }
      }

      if (match) return variation;
    }

    return null;
  }

  function setStatus($wrap, text, state) {
    const $status = $wrap.find('.custom-update-status');
    if (!$status.length) return;

    $status.removeClass('is-loading is-success is-error').text(text);

    if (state) {
      $status.addClass(state);
    }
  }

  function setLoading($wrap, state) {
    if (state) {
      $wrap.addClass('is-loading');
      $('body').addClass('checkout-refreshing');
      setStatus($wrap, 'Updating order...', 'is-loading');
    } else {
      $wrap.removeClass('is-loading');
      $('body').removeClass('checkout-refreshing');
    }
  }

  function refreshSelectedVariation($wrap) {
    let variations = $wrap.data('variations') || [];
    let attributesForMatch = getAttributesForMatch($wrap);

    let match = findVariation(variations, attributesForMatch);

    if (match) {
      $wrap.find('.variation_id').val(match.variation_id);

      if (match.price_html) {
        $wrap.find('.cp-price').html(match.price_html);
      }

      setStatus($wrap, '', '');
      return true;
    } else {
      $wrap.find('.variation_id').val('');
      setStatus($wrap, 'Please select options', 'is-error');
      return false;
    }
  }

  function autoUpdateCheckout($wrap) {
    if ($wrap.hasClass('is-loading')) return;

    let productId = parseInt($wrap.data('product-id'), 10);
    let qty = parseInt($wrap.find('.custom_qty').val(), 10) || 1;
    let variationId = parseInt($wrap.find('.variation_id').val(), 10) || 0;

    let hasVariations = $wrap.find('.cp-attr').length > 0;
    let attributesForAjax = getAttributesForAjax($wrap);

    if (hasVariations && !variationId) {
      setStatus($wrap, 'Please select options', 'is-error');
      return;
    }

    setLoading($wrap, true);

    $.ajax({
      url: wc_checkout_params.ajax_url,
      type: 'POST',
      dataType: 'json',
      data: {
        action: 'custom_cf_set_qty',
        product_id: productId,
        qty: qty,
        variation_id: variationId,
        attributes: attributesForAjax
      },
      success: function (res) {
        if (res.success) {
          $(document.body).trigger('update_checkout');
        } else {
          setLoading($wrap, false);
          setStatus($wrap, res.data && res.data.message ? res.data.message : 'Update failed', 'is-error');
          console.log('AJAX response:', res);
        }
      },
      error: function (xhr) {
        setLoading($wrap, false);
        setStatus($wrap, 'Could not update order', 'is-error');
        console.log('AJAX error:', xhr.responseText);
      }
    });
  }

  function scheduleAutoUpdate($wrap, delay = 250) {
    let oldTimer = $wrap.data('updateTimer');
    if (oldTimer) {
      clearTimeout(oldTimer);
    }

    let newTimer = setTimeout(function () {
      autoUpdateCheckout($wrap);
    }, delay);

    $wrap.data('updateTimer', newTimer);
  }

  $(document).on('change', '.cp-attr', function () {
    let $wrap = $(this).closest('.custom-product-wrap');

    if (refreshSelectedVariation($wrap)) {
      scheduleAutoUpdate($wrap, 200);
    }
  });

  $(document).on('click', '.qty-plus', function () {
    let $wrap = $(this).closest('.custom-product-wrap');
    let $input = $wrap.find('.custom_qty');
    let val = parseInt($input.val(), 10) || 1;
    $input.val(val + 1).trigger('change');
  });

  $(document).on('click', '.qty-minus', function () {
    let $wrap = $(this).closest('.custom-product-wrap');
    let $input = $wrap.find('.custom_qty');
    let val = parseInt($input.val(), 10) || 1;
    $input.val(Math.max(1, val - 1)).trigger('change');
  });

  $(document).on('input change', '.custom_qty', function () {
    let $wrap = $(this).closest('.custom-product-wrap');

    if ($wrap.find('.cp-attr').length) {
      refreshSelectedVariation($wrap);
    }

    scheduleAutoUpdate($wrap, 250);
  });

  $(document.body).on('updated_checkout', function () {
    $('.custom-product-wrap').each(function () {
      let $wrap = $(this);
      setLoading($wrap, false);
      setStatus($wrap, 'Order updated', 'is-success');

      let oldStatusTimer = $wrap.data('statusTimer');
      if (oldStatusTimer) {
        clearTimeout(oldStatusTimer);
      }

      let newStatusTimer = setTimeout(function () {
        setStatus($wrap, '', '');
      }, 1200);

      $wrap.data('statusTimer', newStatusTimer);
    });
  });

  $(document.body).on('checkout_error', function () {
    $('.custom-product-wrap').each(function () {
      let $wrap = $(this);
      setLoading($wrap, false);
      setStatus($wrap, 'Checkout refresh failed', 'is-error');
    });
  });

  $('.custom-product-wrap').each(function () {
    let $wrap = $(this);

    if ($wrap.find('.cp-attr').length) {
      let ok = refreshSelectedVariation($wrap);

      if (ok) {
        scheduleAutoUpdate($wrap, 300);
      }
    } else {
      scheduleAutoUpdate($wrap, 300);
    }
  });

});
</script>




<script>
(function () {

    function getRequiredFields() {
        var fields = [];

        // Get all inputs/selects that are marked required OR have a required label (*)
        document.querySelectorAll('.woocommerce-checkout .form-row').forEach(function (row) {
            // Check if the row is marked as required by WooCommerce
            if (
                row.classList.contains('validate-required') ||
                row.querySelector('abbr.required') ||
                row.querySelector('label .required')
            ) {
                var input = row.querySelector('input, select, textarea');
                if (input && input.id) {
                    fields.push(input.id);
                }
            }
        });

        return fields;
    }

    function areRequiredFieldsFilled() {
        var fieldIds = getRequiredFields();

        if (fieldIds.length === 0) return false;

        for (var i = 0; i < fieldIds.length; i++) {
            var field = document.getElementById(fieldIds[i]);
            if (!field) continue;
            var val = (field.value || '').trim();
            if (!val) return false;
        }

        return true;
    }

    function showPayment() {
        var el = document.querySelector(".custom-payment-wrapper");
        if (!el) return;
        el.style.display = "block";
        el.style.opacity = "1";
    }

    function hidePayment() {
        var el = document.querySelector(".custom-payment-wrapper");
        if (!el) return;
        el.style.display = "none";
        el.style.opacity = "0";
    }

    function checkAndTogglePayment() {
        if (areRequiredFieldsFilled()) {
            showPayment();
        } else {
            hidePayment();
        }
    }

    function attachListeners() {
        var form = document.querySelector('.woocommerce-checkout');
        if (!form) return;

        // Native input/change events
        form.addEventListener('input', checkAndTogglePayment);
        form.addEventListener('change', checkAndTogglePayment);

        if (window.jQuery) {
            // Select2 dropdowns (Country / State)
            jQuery(form).on('select2:select select2:close', 'select', function () {
                setTimeout(checkAndTogglePayment, 100);
            });

            // WooCommerce country/state change
            jQuery(document.body).on('country_to_state_changed', function () {
                setTimeout(checkAndTogglePayment, 300);
            });
        }
    }

    function movePaymentBlock() {
        var wrapper = document.querySelector(".wcf-customer-info-main-wrapper");
        var heading = document.querySelector(".wcf-payment-option-heading");
        var payment = document.querySelector(".woocommerce-checkout-payment");

        if (!wrapper || !heading || !payment) return;

        if (heading.parentElement && heading.parentElement.classList.contains("custom-payment-wrapper")) {
            checkAndTogglePayment();
            return;
        }

        var newWrap = document.createElement("div");
        newWrap.className = "custom-payment-wrapper";
        newWrap.style.display = "none";
        newWrap.style.opacity = "0";

        heading.parentNode.insertBefore(newWrap, heading);
        newWrap.appendChild(heading);
        newWrap.appendChild(payment);
        wrapper.appendChild(newWrap);

        attachListeners();

        // Check immediately + delayed for pre-filled values
        checkAndTogglePayment();
        setTimeout(checkAndTogglePayment, 500);
        setTimeout(checkAndTogglePayment, 1500);
    }

    setTimeout(movePaymentBlock, 300);
    setTimeout(movePaymentBlock, 1000);
    setTimeout(movePaymentBlock, 2000);

    if (window.jQuery) {
        jQuery(document.body).on("updated_checkout", function () {
            setTimeout(movePaymentBlock, 300);
            setTimeout(checkAndTogglePayment, 800);
        });
    }

    var observer = new MutationObserver(function () {
        movePaymentBlock();
    });
    observer.observe(document.body, { childList: true, subtree: true });

})();
</script>
Checkout Form CSS Class
custom-checkout-form

Get Your FREE Freelancing Roadmap

Stop hopping between tutorials. Grab the Freelancing Mastery Handbook to learn how to choose a skill, build your foundation, find clients, and confidently start your freelancing journey.

Free eBook Download

Related Tutorials

From learning the right skills to building a stronger digital presence, we help you turn ideas into practical, professional results.

Vibe Code a REAL Animated WordPress Website with Claude + Elementor

21.8K views

View Tutorial

Vibe Coding Full Course for Beginners – Build & Launch a Real SaaS

3.3K views

View Tutorial

Edit Videos with ChatGPT Codex — Raw Clips to Finished Reel

3.4K views

View Tutorial

Browse All Tutorials