Decrement/increment for qty and the value field - javascript

I am trying to create a cart page with the ability to use the add or minus buttons to decrement or increment the value of the input but the eventlisteners don't seem to be working and I have tried many different solutions online for this and get it to work properly.
{% extends "base.min.html" %}
{% block body_block %}
{% load static %}
<div class='container'>
<a class='back-link' href="/"> Back to Catalog</a>
<h1 class='cart-h1'>Cart </h1>
<div class='cart'>
<div class='requests'>
<div class='request'>
<img src='https://developers.elementor.com/docs/assets/img/elementor-placeholder-image.png' alt='request image'>
<div class='request-info'>
<p class='request-name'>Request: {{ requestName }}</p>
<p class='request-details'>Details: {{ requestDetails }}</p>
<p class='request-qty'>Qty: {{ requestQty }}
<div class='qty-container'>
<input type='button' value='+' class='qtyplus' id='plus' field='quantity' />
<input type='text' name='quantity' value='0' class='qty' id='inputQty' />
<input type='button' value='-' class='qtyminus' id='minus' field='quantity' />
</div>
</p>
<p class='qty-remove'></p>
<span class='remove'>Remove</span>
</div>
</div>
</div>
</div>
</div>
</br>
<div class='hidden-container'>
<p>Checkout Confirmation #: {{confirmNum}}</p>
</div>
<script type="module" src="{% static '\js\supplyshop\pageload\RequestManagementLoad.min.js' %} " type ="text/javascript"></script>
{% endblock %}
const plusBtn = document.querySelector('#plus')
const minusBtn = document.querySelector('#minus')
const inputQty = document.querySelector('#inputQty')
// increment/decrement value on input field
// add eventlisteners on +/- buttons to update the value field
plusBtn.addEventListener('click', e => {
e.preventDefault()
inputQty.value = parseInt(inputQty.value) + 1
})
minusBtn.addEventListener('click', e => {
e.preventDefault()
if (inputQty.value <= 0) {
inputQty.value = 0
}
inputQty.value = parseInt(inputQty.value) - 1
})
I tried using incrementing/decrementing the value of the input field which holds the quantity value. I've also tried using the onclick function in html and making a function that does the same thing in that but I may be going about it the wrong way as nothing is working properly. The behavior I am expecting is to click the plus or minus button and the number in the middle (input field) will increase by one or decrease by one if the add/minus button is clicked. I also want to make sure the value can't go below 0.
1 -

check with this:
minusBtn.addEventListener('click', e => {
e.preventDefault()
if (inputQty.value <= 0) {
inputQty.value = 0
}else{
inputQty.value = parseInt(inputQty.value) - 1
}
})

Related

Symfony & js : button not working in certain conditions

I have a simple "plus/minus" functionality for the product quantity on the product detail page on a shopware6 site (version 6.4.8.1) (See attached image)
See here my code in /views/storefront/page/product-detail/buy-widget-form.html.twig.
{% block page_product_detail_buy_quantity_container %}
<div class="col-12 quantity-container">
<div class="row">
<div class="col-5 col-md-3 label-quantity">
<span>{{ "detail.labelQuantity"|trans|sw_sanitize }}</span>
</div>
<div class="col-7 col-md-9 quantity-input-panel">
{% block page_product_detail_buy_quantity %}
<div class="quantity-inner">
<span class="min button" id="moins" {#onclick="minus()"#}> {% sw_icon 'minus' %} </span>
<input id="amountToBasket" type="text" name="lineItems[{{ page.product.id }}][quantity]" value="{{product.minPurchase}}" autocomplete="off" maxlength="2" class="form-control">
<input id="minPurchase" type="hidden" name="minPurchase" value="{{product.minPurchase}}" autocomplete="off" class="form-control">
<input id="maxRange" type="hidden" name="maxRange" value="{{product.calculatedMaxPurchase}}" autocomplete="off" class="form-control">
<input id="purchaseSteps" type="hidden" name="purchaseSteps" value="{{product.purchaseSteps}}" autocomplete="off" class="form-control">
<span class="plus button" id="plus" {#onclick="plus()"#}> {% sw_icon 'plus' %}</span>
</div>
{% endblock %}
</div>
</div>
</div>
{% endblock %}
And here's my js file related to the plus/minus buttons.
var minPurchase = $("#minPurchase").val();
var maxRange = $("#maxRange").val();
var count = $("#amountToBasket").val();
$("#plus").click(function () {
if (count < maxRange){
count++;
$("#amountToBasket").val(count);
}
});
$("#moins").click(function () {
if (count > minPurchase){
count--;
$("#amountToBasket").val(count);
}
});
PROBLEM : This works perfectly for ALL products where the minimum purchase quantity is equal to 1. BUT if we click on the plus or the minus for every product having the minimum purchase quantity greater than 1, it's doing nothing. It gives the impression that the buttons are deactivated in this case.
Do you have any clue on what is going on?
as replied by #DarkBee, I simply needed to specify the value type of the "count" function.
var count = parseInt($("#amountToBasket").val());

Django: Javascript error with alert box displaying values

I am creating a web application that will serve as a grocery store. The way I set it up is so the customer can come onto the website, click on the items that they would like to purchase, and then click a submit button to purchase those items. The problem I am running into is that my Javascript is not printing the correct values. In both spots, it says undefined. I will put a picture below for reference.
views.py
def inventory(request):
products = request.POST.getlist('products')
for product in products:
a = Post.objects.get(title=product)
a.quantity = a.quantity -1
a.save()
print(products)
return redirect('blog-home')
home.html
{% extends "blog/base.html" %}
{% load static %}
{% block content %}
<form action="{% url 'js' %}" method="POST" id="menuForm">
{% for post in posts %}
{% if post.quantity > 0 %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2">{{ post.category }}</a>
</div>
<h2><a class="article-title" >{{ post.title }}</a></h2>
<p class="article-content"> Price: ${{ post.Price }}</p>
<p class="article-content"> Sale: ${{ post.Sale }}</p>
<input type="checkbox" id="product_{{ post.id }}" value="{{ post.title }}" form="menuForm" name="products" > Inventory count: {{ post.quantity }}
</input>
</div>
</article>
{% else %}
{% endif %}
{% endfor %}
<button id="btn" type="submit" form="menuForm">Confirm Purchase</button>
</form>
<script src="{% static "JS/javascript.js" %}" type="text/javascript"></script>
{% endblock content %}
javascript.js
function getSelectedCheckboxValues(name) {
const checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
let values = [];
checkboxes.forEach((checkbox) => {
values.push(checkbox.value);
});
return values, tPrice;
var price = 0;
var tPrice =0;
if (values=='Milk'){
var MPrice = 3.99
tPrice = price+MPrice;
}
if (values == 'Cheese'){
var CPrice = 4.50
tPrice = price + CPrice;
}
if (values == 'Yogurt'){
var YPrice = 1.99
tPrice = price + YPrice;
}
}
const btn = document.querySelector('#btn');
btn.addEventListener('click', (event) => {
alert('You ordered: ' + getSelectedCheckboxValues('products')+
'\nTotal Price: $'+ getSelectedCheckboxValues('tPrice'));
});
First of all you are passing the parameter to the function getSelectedCheckboxValues as a string when you call them in the alert which is completely wrong.
Also you are directly comparing values list with strings which is not possible. You need to loop over the list and then compare the different elements with the different products. I will also recommend to create an object instead of the list and keep the product name as key and its price as value.

Create dynamic number of sliders in html from python list and display value with javascript?

I want to create a dynamic number of sliders with value output according to a python dictionary {{ sliders }} fed in by a flask app.
So far I have come up with this code to display the sliders, but displaying their current value underneath each slider does not work.
The JS script will just display the default value of each slider not their current one. Why is that and how to fix it?
<div class="content-section">
<form method="POST" action="{{url_for('deployment')}}">
<fieldset class="form-group">
{% for slider in sliders %}
<div class="slidecontainer">
<p>{{ slider['name'] }}</p>
<input type="range" min="{{ slider['min'] }}" max="{{ slider['max'] }}" step="{{ slider['step'] }}" class="slider" id="{{ slider['slider_id'] }}" name="{{ slider['name'] }}">
<p>Value: <span id="{{ slider['value_id'] }}"></span></p>
</div>
{% endfor %}
</fieldset>
<input type="submit" value="Submit" />
</form>
{% for slider in sliders %}
<script>
var slider = document.getElementById("{{ slider['slider_id'] }}");
var output = document.getElementById("{{ slider['value_id'] }}");
output.innerHTML = slider.value;
slider.oninput = function() {
"{{ slider['value_id'] }}".innerHTML = this.value;
}
</script>
{% endfor %}
</div>
You are missing the
document.getElementById()
in the oninput-function.
It should be
slider.oninput = function()
{
document.getElementById("{{ slider['value_id'] }}").innerHTML = this.value;
}

Dynamically display list of checked checkboxes values js/jquery

I would like to display dynamically a list of the chosen options using javascript or jQuery when the user changes his options.
PS: I'm using Django + Python to generate the options and bootstrap to style them.
Here is my code:
{% for option in options %}
<div class="input-group" style="margin-bottom: 7px;">
<div class="input-group-prepend">
<div class="input-group-text">
<input type="checkbox" name="checks[]" aria-label="Radio button for following text input" class="option_choice" class="ipad_pro" value="{{ option.name }}">
</div>
</div>
<input style="background-color: #fff;" type="text" class="form-control" disabled=True value="{{ option.name }} {{ option.price }}€" aria-label="Text input with radio button">
</div>
{% endfor %}
<ul id='options_display'></ul>
Here's what I've attempted:
var getChecked= function() {
var n = $("input:checked");
var options_display = $("#options_list")
console.log(n)
if (n.length != 0) {
$.each(n, function(index, value) {
options_display.append("<li>" + value.defaultValue + "</li>")
});
}
else {
options_display.html("<h3 class'text-center'>No Options</h3>")
}
};
getChecked()
$( "input[type=checkbox]" ).on( "click", getChecked);
The problem with that is that it doesn't reset the content of the <ul> which means that I get elements twice when I select a new one.
Please help me if you know the answer to my problem.
You can empty options_display on each click like
$("#options_list").empty();
before the condition.

How to always get new checkboxes array, every time a different button is clicked

I'm developing an app about quizzes.
IMG1: [The added comments in this picture applies for the IMG2 too]
IMG2:
Description:
[IMG1] When one or more .js-answer-check checkbox are checked, I save the values in a js array. Then, when the #save-response button is clicked, the respective array is send to the server, to be saved in the db.
[IMG2] Then I click another question of the quiz, identified by .quiz-questions class, and when one or more .js-answer-check checkboxes of this new question are checked, the values are saved in the same js array.
The problem is that the previous checkboxes values, from the previous answers, are still present in the array, due to that answers.push(answerID).
How can I only grab the values of the respective question answers in the array each time a .quiz-questions button is clicked?
Expected values:
clicking the checkbox with label "2" in the first question => array should be [ 2 ] (the data-id="2" attribute in that checkbox)
clicking the checkboxes with label "1+3" and "8/2" in the second question => array should be [4, 5] as those checkboxes have data-id="4" and data-id="5" attributes.
Actual result: [2, 4, 5]
I tried out this code:
//if one|more options are checked...
var answers = [];
$(document).on('click', '.js-answer-check', function(){
if ($(this).is(':checked')){
var answerID = $(this).data('id');
answers.push(answerID);
} else {
var removeItem = $(this).data('id');
answers = $.grep(answers, function(value){
return value != removeItem;
});
}
});
$('#save-response').on('click', function(e){
e.preventDefault();
$.ajax({
method: 'POST',
url: Routing.generate('save_answer'),
data: { answers: answers },
success: function(resp) {
if (resp.success) {
var answersBack = resp.answers;
for (var ans in answersBack) {
console.log('answerID = ', answersBack[ans]);
}
}
//answers = [];
}
});
});
And I thought that if I do answers = [] will reset the initial array, but it didn't.
Any help is welcomed. Thanks.
LATER EDIT
<div class="row margin-top-ten">
<div class="col-6">
<input type="hidden" id="quiz-id" data-quiz="{{ quiz.id }}"/>
<div class="row question-content">{# the content (question-text + checkboxes) is coming from an AJAX request because I need to present everytime a new content based on `quiz-questions` buttons #}
</div>
</div>
</row>
<div class="row margin-top-ten">
<div class="col-12">
<button class="btn btn-primary btn-sm" type="button" id="save-response">Salveaza</button>
</div>
</div>
<div class="row margin-top-fifty">
<div class="col-12">
{% set i = 1 %}
<p>Navigator intrebari:</p>
{% for question in quiz.questions %}
<a href="" class="btn btn-info btn-sm quiz-question"
data-id="{{ question.id }}" data-quiz="{{ quiz.id }}">
{{ i }}
</a>
{% set i = i + 1 %}
{% endfor %}
</div>
</div>
The AJAX request for bringing new content for each quiz-questions buttons is:
<div class="col-12">
<div class="row">
<div class="col-12 question-text" data-question="{{ question.id }}">{{ question.content|raw }}</div>
</div>
<div class="row">
{% for answer in question.answers %}
<div class="col-12 question-answers">
<span style="display: inline-block">
<label for="">
<input type="checkbox" name="user-responses[]" class="js-answer-check" data-question="{{ question.id }}" data-id="{{ answer.id }}">
</label>
</span>
<span style="display:inline-block">{{ answer.answer|raw }}</span>
</div>
{% endfor %}
</div>
</div>
The save_answer php functionality is just returning the sent-data, for debug purposes. Nothing fancy.

Categories