Symfony & js : button not working in certain conditions - javascript

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());

Related

Decrement/increment for qty and the value field

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
}
})

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;
}

Reload the page after clicking a form button in IE

I have a problem with my web site.
I have a button that displays the form and the problem is that on IE and on the edge when I click this button it shows me the form but refreshed the page automatically after the click.
I do not know how to solve this problem. Can you help me please ?
Here is my code html :
<div class="col-xs-3" id="div6">
<div style="text-align: center; color: #333; font-weight:bold;">Actualité</div>
{% if user.is_authenticated %}
{% if request.user.is_staff %}
<form action="#modification">
<div style="text-align: center;">
<button type="submit" id="modifier" class="btn btn-primary">Modifier l'actu</button>
</div>
</form>
<form action="#modification" id="formActu" style="display: none" method="post">
{% csrf_token %}
<div id="modification"></div>
<div style="text-align: center;">
<button type="submit" class="btn btn-success" id="valider" style="margin-top: 1%;">Valider</button>
</div>
</form>
{% endif %}
{% endif %}
{% if not actu %}
<div id="messageNonActu" style="margin-top: 5%;">Pas d'actualité pour le moment !</div>
{% endif %}
{% for actuCommentaire in actu %}
<div id="commentaireActu" style="margin-top: 5%;">{{actuCommentaire.commentaire}}</div>
{% endfor %}
</div>
Here is my script :
$(document).ready(function(){
var compteur = 0;
$('#modifier').click(function(){
if(compteur === 0){
$('#modification').append('{% for field in form %}<label class="my_class" for="{{ field.name|escapejs }}">{{ field.label|escapejs }} :</label>{{ field|escapejs }}{% endfor %}');
$('#formActu').show()
$('#exampleTextarea').css({resize: 'none'});
$('#commentaireActu').hide();
$('#messageNonActu').hide();
$('#modifier').removeClass('btn btn-primary').addClass('btn btn-danger');
$('#modifier').html("Annuler la modif");
compteur++;
}else{
if($('#formActu').is(':visible')){
$('#formActu').hide();
$('#commentaireActu').show();
$('#modifier').removeClass('btn btn-danger').addClass('btn btn-primary');
$('#modifier').html("Modifier l'actu");
}else{
$('#commentaireActu').hide();
$('#formActu').show();
$('#modifier').removeClass('btn btn-primary').addClass('btn btn-danger');
$('#modifier').html("Annuler la modif");
}
}
});
});
Image 1 with just button
After clicking I have a preview of the second image but it refreshed the page in less than a second after clicking on the button
Image 2 with form
Then I get the visual of the first image directly
Try this and check:(Just return false from the end of method because IE considers button click as submit that's why your page reloads)
$('#modifier').click(function(){
//your logic
return false;
}

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