shopify liquid showing variant prices based on input - javascript

I am a beginner in liquid and currently I am trying to develop a shopify store. In the products page, I am displaying the options as radio buttons and taking customer inputs. The prices are different for the variants. Now I am trying to display the variant price based on the customer input, I am a bit lost. This is what I have so far:
{% for product_option in product.options_with_values %}
{{ product_option.name }}
{% for value in product_option.values %}
<input type="radio" id = "{{ value }}" name="{{ product_option.name}}" value="{{ value }}" >
<label for="{{ value }}">{{ value }}</label>
{% endfor %}
<!--want to show the variant price here-->
<br>
{% endfor %}
</div>
I know that I can display all the variant prices like this:
{% for variant in product.variants %}
{{ variant.title }} - {{ variant.price | money }}
{% endfor %}
But that's not what I want. Is there any way to do it without having to use javaScript? Thanks in advance.

Liquid is a server side language. It is processed by the server and cannot offer any dynamic behaviour.
You need to change the price with Javascript. There is no other solution.
Using your code I've made a small example
document
.querySelectorAll("input[name='Size']").forEach(option =>{
option.addEventListener("change", function (event, target) {
document.querySelectorAll(".price").forEach((price) => {
if(price.dataset.option==option.value){
price.classList.remove("hide");
}else{
price.classList.add("hide");
}
});
});
})
.hide{
display: none;
}
<html>
<form>
Size
<input type="radio" id="S" name="Size" checked="checked" value="S">
<label for="S">S</label>
<input type="radio" id="M" name="Size" value="M">
<label for="M">M</label>
<br>
<p>Price:
<span class="price" data-option="S">£14.00</span>
<span class="price hide" data-option="M">£15.00</span>
</p>
<input type="number" min="1">
<button type="submit">Add to Cart</button>
</form>
</html>

Related

How do I make my error cover any instances of the same error in the rest of the text boxes?

This works for only the first of my entries however, in the rest of my entries, the error doesn't show. How do I ensure if the entries don't match on the rest, the error message appears too? I'm using Python/Flask and Html/Js
<script>
function compare_input() {
var f_input = document.querySelector(".credit").value;
var s_input = document.querySelector(".debit").value;
if (f_input !== s_input) {
alert('Debit and Credit must be equal');
}
}
</script>
Inputs
For Credit
{% for number in range(1, 6) %}
<tr>
<td>
<select name="credit_{{ number }}_account">
{% for account in accounts %}
<option value="{{ account['acct_num'] }}">{{ account['acct_num'] }} - {{ account['acct_name'] }}</option>
{% endfor %}
</select>
</td>
<td style="padding-bottom: 1px">
<input style="border: none" class="credit" name="credit_{{ number }}_value" type="text" datatype="currency" placeholder="$0" id="credit_{{ number }}_value">
</td>
</tr>
{% endfor %}
For Debit
{% for number in range(1, 6) %}
<tr>
<td>
<select name="debit_{{ number }}_account">
{% for account in accounts %}
<option value="{{ account['acct_num'] }}">{{ account['acct_num'] }} - {{ account['acct_name'] }}</option>
{% endfor %}
</select>
</td>
<td style="padding-bottom: 1px">
<input style ="border: none" class="debit" name="debit_{{ number }}_value" type="text" datatype="currency" placeholder="$0" id="debit_{{ number }}_value">
Top entries are credit then debit. All the entries that need to read the same error when credit doesn't equal debit
I don't really know much Js either, just learning

Shopify adding two products to cart with one checkout button

So I have a bundle I created to add two products to cart once those products are selected. I want them to be added to cart at the same time. I'm currently only getting one product being added, with the name="id". How can I create the values in input for both to checkout?
Here's my form:
<form method="post" action="/cart/add" class="col-button ">
<input id="idPrice" type="hidden" name="id" value="" />
<input id="designPrice" type="hidden" name="id" value="" />
<input min="1" max="2" type="hidden" id="quantity" name="quantity" />
<button name="checkout" {%unless product.available %}style='margin-bottom:20px;'{% endunless %}type="{% if settings.cart_action == 'ajax' %}button{% else %}submit{% endif %}" name="add" class="collection-add-to-cart {% if settings.cart_action == 'ajax' %} ajax-submit {% endif %}action_button add_to_cart {% if show_payment_button %} action_button--secondary {% endif %} {% if product.available == false %}disabled{% endif %}" data-label={{ add_to_cart_label | json }}>
{{ 'layout.general.checkout' | t }}
</button>
</form>
Thanks in advance!

How to set PayPal shipping costs with JavaScript/JQuery

I have a Form that is in html.twig format. In that form there is a for loop that shows every product we have.
Corresponding to that Form there is a chckForm() Functions which calculates or to be more precise adds shipping costs to a product when a user buys it.
The shipping costs dropdown has 2 Values: "12,00" or "18.50". This Value is then added to the order.
The problem is that if users buys more of our products than the shipping cost is always added again instead of only being added once to the whole order.
Form Code in html.twig:
<table class="table table-striped">
{% for item in page.header.paypal.items %}
{% set image = media['user://pages/images/'~item.image].resize(52) %}
<tr>
<td>{{ image }}</td>
<td>{{ item.name }}</td>
<td>{{ item.description }}</td>
<td>{{ item.amount|number_format(2,',') }} {{ currency_sign }}</td>
<td>
<form name="{{ item.name }}"
id="{{ item.name }}"
target="paypal"
action="{{ page.header.paypal.action }}"
method="post"
onsubmit="return chkForm('{{ item.name }}');">
<input src="/images/button-basket.png" name="submit"
alt="In den Warenkorb" title="In den Warenkorb"
type="image">
<input name="add" value="1" type="hidden">
<input name="cmd" value="_cart" type="hidden">
<input name="business" value="{{ page.header.paypal.business }}" type="hidden">
<input name="item_name" value="{{ item.name }} - {{ item.description }}" type="hidden">
<input name="amount" value="{{ item.amount|number_format(2,'.') }}" type="hidden">
<input name="no_shipping" value="0" type="hidden">
<input name="shipping" value="0.00" type="hidden">
<input name="no_note" value="1" type="hidden">
<input name="currency_code" value="{{ page.header.paypal.currency_code }}" type="hidden">
<input name="lc" value="{{ page.header.paypal.lc }}" type="hidden">
<input name="bn" value="PP-ShopCartBF" type="hidden">
</form>
</td>
</tr>
{% endfor %}
</table>
and the corresponding JavaScript/jQuery code:
function chkForm(form)
{
var shippingCosts = $('#shippingCosts').val(); // value from shipping dropdown 12 or 18.50
var shippingField = $('#'+form+' input[name=shipping]'); // hidden input > 0.00
shippingField.val(shippingCosts);
console.log("value1:" + shippingCosts);
return true;
}
Now I need to solve that problem by somehow saying that the shipping value should only be added once in the .js Function. I tried a few things with some if`s but it didn't work.
Another way could be to just add the products with the price and then at the end if the User presses the final BUY so on the PayPal checkout site he is asked to either specify shipping costs as 12$ or 18.50$ - but I don't know if that is possible with PayPal.

Remove form from DOM using JavaScript

I have three radio buttons.. each radio buttons on click have an independent form that appears. I need to remove form from DOM when i click on a radio button. and there are a third one not ready yet. When i click on the first radio button only its form appears, the other two are removed from DOM. Same for other.
I don't have a good idea about JavaScript.
Html:
<div class="page-header">
<h1>Backtesting{% if form.instance.pk %}: {{form.instance.title}} {% endif %}</h1>
</div>
<div class="row">
<div class='col-md-9'>
<form action="{% url "backtest" %}" method='POST' role='form' id='form'>
{% csrf_token %}
<div id="tabs">
<input type="radio" name="tabs" value="first" id="toggle-tab1" checked="checked" />
<label for="toggle-tab1">Long</label>
<input type="radio" name="tabs" value="second" id="toggle-tab2" />
<label for="toggle-tab2">Short</label>
<input type="radio" name="tabs" value="third" id="toggle-tab3" />
<label for="toggle-tab3">Long and Short</label>
<div id="tab1" class="tab" >
{% include 'tags/parameters_form.html' %}
<br />
{% if user.is_authenticated %}
<input type='submit' id='run' value='Run' class='btn btn-default'>
{% if user.profile.is_active %}
Name: {{ form.title }} <input type='submit' name='save' value='Save' class='btn btn-default'>
{% else %}
<p>
Expired account! you need to reactivate in order to save parameters.
</p>
{% endif %}
{% else %}
Please login in order to Run backtesting!
</br>
Our system needs your email in order to notify you once one or more of your simulations are done. This is a safer way for you to keep track of your previous simulations (/jobs).
{% endif %}
</div>
<div id="tab2" class="tab" >
{% include 'tags/parameters_backtest_form.html' %}
<br />
{% if user.is_authenticated %}
<input type='submit' id='run' value='Run' class='btn btn-default'>
{% if user.profile.is_active %}
Name: {{ form.title }} <input type='submit' name='save' value='Save' class='btn btn-default'>
{% else %}
<p>
Expired account! you need to reactivate in order to save parameters.
</p>
{% endif %}
{% else %}
Please login in order to Run backtesting!
</br>
Our system needs your email in order to notify you once one or more of your simulations are done. This is a safer way for you to keep track of your previous simulations (/jobs).
{% endif %}
</div>
</div>
</form>
</div>
</div>
{% endblock %}
<form action="{% url "backtest" %}" method='POST' role='form' id='form'>
{% csrf_token %}
<div id="tabs">
<input type="radio" name="tabs" value="first" id="toggle-tab1" checked="checked" />
<label for="toggle-tab1">Long</label>
<input type="radio" name="tabs" value="second" id="toggle-tab2" />
<label for="toggle-tab2">Short</label>
<input type="radio" name="tabs" value="third" id="toggle-tab3" />
<label for="toggle-tab3">Long and Short</label>
<div id="tab1" class="tab" >
<!-- first form will show when page load -->
<fieldset id="first" class="toggle">
{% include 'tags/parameters_form.html' %}
</fieldset>
<fieldset disabled id="second" class="toggle">
{% include 'tags/parameters_form.html' %}
</fieldset>
<fieldset disabled id="third" class="toggle">
{% include 'tags/parameters_form.html' %}
</fieldset>
.....
Js
$('[name="tabs"]').click(function(){
$('.toggle').prop("disabled", true);
var val = $(this).val()
$('#'+val).prop('disabled', false);
});
When you add disabled attr in fieldset then fieldset inner input field data will not post in form that means field will not work in fieldset tag if it have disabled attribute. So you can show specific form in each condition and add attribute disable in fieldset tag that inner field data will not post.
Read about https://www.w3schools.com/tags/att_fieldset_disabled.asp
If you cannot change DOM elements and add a class there my answer would be to attach a event listener to each of the buttons:
'use strict';
var button1 = document.getElementById('toggle-tab1'),
button2 = document.getElementById('toggle-tab2'),
button3 = document.getElementById('toggle-tab3');
button1.addEventListener('click', function () {
// Code that takes it away (hide DOM elements or whatever you need)
});
On a side note a better approach would be to add a function to all of the radio inputs and then based on the ID or value of the input radio you can alter the behavior:
<input type="radio" name="tabs" onclick="handleClick(this)" value="first" id="toggle-tab1" checked="checked" />
Then you can have a function:
function handleClick (e) {
if (e.id == 'toggle-tab1') {
// Code that takes it away (hide DOM elements or whatever you need)
}
};
function onclick(e){
var tab = document.getElementById('toggle-tab1');
tab.style.visibility = "hidden";
}
button1.addEventListener('click', onclick(e))
This should do the trick!
Problem is resolved with :
<input type="radio" name="tabs" value="first" id="toggle-tab1" {% if strategy == 'l' %} checked="checked"{% endif %} />
<label for="toggle-tab1">Long</label>
<input type="radio" name="tabs" value="second" id="toggle-tab2" {% if strategy == 's' %} checked="checked" {% endif %} />
<label for="toggle-tab2">Short</label>
<div id="tab1" class="tab" >
<form action="{% url "backtest" %}" method='POST' role='form' id='form'>
{% csrf_token %}
<input type="hidden" name="tabs" value="first" id="toggle-tab1" checked="checked" />

October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear

I am using October CMS and materializecss to create an options form on one of my pages. The form works fine and dynamically loads content when you click through the various options. However, I have noticed that if I click on the same option two times in a row the content disappears and no new data is inserted. Even the loading screen fails to appear. Debugging has shown that no ajax request is actually being fired off. Does anyone know how I can change this so that clicking twice would either leave the current content on the page or reload the content on the page? Below is the problematic radio element and the complete partial.
Radio Button:
<p class="optrow">
<input onclick="onsend()" type="radio" class="box" id="cat_all"
name="dates" value="all" data-request="onEventDeals"
checked="checked" data-request-update="'deals::default':'#deals'"
data-request-loading="#loading">
<label for="cat_all"> Show All</label>
</p>
Partial:
<ul class="collapsible" data-collapsible="accordion">
<li>
<div class="collapsible-header active"><i class="material-icons">format_list_bulleted</i>Deal Options</div>
<div class="collapsible-body"><form id="dealsoptions" class data-request="onTest" data-request-update="calcresult: '#deals'">
{# <p>
See All Deals - Clear
</p> #}
{# <h5><b> Deal Source</b></h6>
<hr>
<div id="dealsource">
<p class="optrow">
<input onClick="onsend()" type="checkbox" class="box" id="source_all" name="userProviders[]"
value="all" data-request="onLocalDeals" data-request-update="'deals::default': '#deals'"
data-request-loading="#loading" data-request-data="clear:1"/>
<label for="source_all"> Show All</label>
</p>
{% for provider in providers %}
<p class="optrow">
<input onClick="onsend()" type="checkbox" class="box sourcebox" id="source_{{ provider.userProviderID }}" name="userProviders[]" value="{{ provider.userProviderID }}" checked="checked" data-request="onLocalDeals" data-request-update="'deals::default': '#deals'" data-request-loading="#loading"/>
<label for="source_{{ provider.userProviderID }}"> {{ provider.providerName }}</label>
</p>
{% endfor %}
</div>
#}
<hr>
<h5><b> Event Date</b></h6>
<hr>
<div id="eventdate">
<p class="optrow">
<input onClick="onsend()" type="radio" class="box" id="cat_all"
name="dates" value="all" data-request="onEventDeals" checked="checked"
data-request-update="'deals::default': '#deals'" data-request-loading="#loading"/>
<label for="cat_all"> Show All</label>
</p>
{% set weekEnd = "this sunday"|date('Y-m-d') %}
{% set dates = {'Today':{'start':"now"|date("Y-m-d"),'end':"now"|date("Y-m-d")},
'Tomorrow':{'start':"now"|date_modify("+1 day")|date("Y-m-d"),'end':"now"|date_modify("+1 day")|date("Y-m-d")},
'This_Weekend':{'start':"this sunday"|date_modify("-2 day")|date('Y-m-d'),'end':weekEnd},
'This_Week':{'start':"now"|date("Y-m-d"),'end':weekEnd},
'This_Month':{'start':"now"|date("Y-m-d"),'end':"now"|date("Y-m-t")}} %}
{% for key,date in dates %}
<p class="optrow">
<input onClick="onsend()" type="radio" class="box type_{{ key }}"
id="cat_{{ key }}" name="dates"
value="{{ date.start }}:{{ date.end }}"
data-request-data="start:'{{ date.start }}',end:'{{ date.end }}'"
data-request="onEventDeals" data-request-update="'deals::default': '#deals'"
data-request-loading="#loading"/>
<label for="cat_{{ key }}"> {{ key|replace({'_':' '})|title }}</label>
</p>
{% endfor %}
</div>
{% partial 'deals::apps' %}
</form>
</div>
</li>
</ul>
I notice you have onClick="onsend()" on the input, this might be causing a problem for the AJAX handler to be fired off. Try removing it and see if it progresses further.

Categories