Change status in ajax on selectbox - javascript

I have a question, So ,this code work fine only for the first select box and I dont understand why. For first select box update on database work fine but If I tried to change the statut for the second select box the status remain unchanged. Can you help me? Sorry for my english
My view :
{% for gift in aFilterGifts %}
<form action="" id="updateStatus" method="post">
<select id="statusSelect"
name="{{ gift.id }}"
class="form-control"
onChange="updateCadeauStatus({{ gift.id }})">
{% for key,statut in form_logistique.statut.choices %}
<option value="{{ key }}"
{% if gift.etat == key %}selected="selected"{% endif %}>
{{ statut }}
</option>
{% endfor %}
</select>
</form>
{% endfor %}
<script>
function updateCadeauStatus(id) {
var id = id;
var selectedName = $("#statusSelect option:selected").val();
var url_deploy = 'http:localhost/updateStatus'
console.log(id);
console.log(selectedName);
$.ajax({
url: url_deploy,
type: "POST",
async: true,
data: { id_cadeau:id, id_status:selectedName}
});
}
</script>
The controller :
public function updateStatus(){
$iGiftId = $_POST['id_cadeau'];
$iNewStatus = $_POST['id_status'];
$bUpdate = $this->updateStatusByGiftId($iGiftId, $iNewStatus);
}
The model :
public static function updateStatusByGiftId($iGiftId, $iStatusId){
$request = sprintf( ' UPDATE `%s` set etat = %d WHERE id_instant_gagnant = %d ', $table, $iStatusId, $iGiftId);
return Mysqli::query($request, $database);
}
Thx in advance.

All your select boxes do have the same id id="statusSelect".
That's not valid HTML.
One solution would be to append the gift id to the id tag to create unique ids:
{% for gift in aFilterGifts %}
<form action="" id="updateStatus{{ gift.id }}" method="post">
<select id="statusSelect{{ gift.id }}"
name="{{ gift.id }}"
...
and for the script:
<script>
function updateCadeauStatus(id) {
var id = id,
selectedName = $("#statusSelect" + id + " option:selected").val(),
url_deploy = 'http:localhost/updateStatus';
console.log(id);
...

Related

view function is not being executed

I was trying to make a basic banking system using Django, in which a user can transfer money to other user. But when I tried to transfer money nothing happens, probably because transfer function in views.py is not being executed.
Here are transaction.html file and transfer function from views.py :
transaction.html
{% extends 'bank/base.html' %}
{% block content %}
<div class="container">
<h2>Transfer Money</h2>
<form action="{% url 'transaction' %}" method="post">
{% csrf_token %}
<label for="s_acc">Select sender details</label>
<select name="s_acc" required>
<option value="select">Select</option>
{% for cust in customer %}
<option value="{{cust.account_number}}">{{cust.name}}: {{cust.account_number}} : {{cust.balance}}</option>
{% endfor %}
</select>
<br>
<label for="amt">Enter amount</label>
<input type="number" name="amt" required>
<br>
<label for="r_acc">Select receiver details</label>
<select name="r_acc" required>
<option value="select">Select</option>
{% for cust in customer %}
<option value="{{cust.account_number}}">{{cust.name}}: {{cust.account_number}} : {{cust.balance}}</option>
{% endfor %}
</select>
<br>
<button type="submit" name="button">TRANSFER</button>
</form>
</div>
{% endblock %}
transfer function from views.py:
def Transfer(request):
customer = Customer.objects.all();
if request.method=="POST":
s_acc = request.POST.get('s_acc')
amt = request.POST.get('amt')
r_acc = request.POST.get('r_acc')
print(s_acc)
print(amt)
print(r_acc)
amt = int(amt)
if((s_acc=='select')or(amt=='select')or(r_acc=='select')or(s_acc==r_acc)):
messages.warning(request,"Account not selected or both the accounts are same")
elif(amt<=0):
messages.warning(request,"Enter valid amount")
else:
for c in customer:
if(c.account_number == s_acc):
s_name = c.name;
if(amt>c.balance):
messages.warning(request,"Insufficient balance")
break
for x in customer:
if(x.account_number == r_acc):
r_name = x.name
r_bal = x.balance
break;
for c in customer:
if c.account_number == s_acc and r_acc!=s_acc and r_acc!= 'select' and amt<=c.balance and amt>0:
q1 = Transaction(sender_name = s_name, amount = amt, receiver_name = r_name )
q1.save()
acc_bal = c.balance - amt
q2 = Customer.objects.filter(account_number = s_acc).update(balance = acc_bal)
q2.save()
acc_bal = r_bal+amt
q3 = Customer.objects.filter(account_number = r_acc).update(balance = acc_bal)
q3.save()
messages.success(request,"Transfer Complete")
return redirect('tranfer_list')
return render(request,'bank/transaction.html',{'customer':customer})
urls.py
from django.urls import path
from bank import views
urlpatterns = [
path('',views.AboutView.as_view(),name = 'about' ),
path('about/', views.AboutView.as_view(),name = 'about'),
path('customers/', views.CustomerListView.as_view(),name = 'customer_list'),
path('transfer_list/', views.TransactionListView.as_view(), name = 'transfer_list'),
path('transaction/', views.Transfer, name = 'transaction'),
path('customers/new', views.CustomerCreateView, name = 'customer_new'),
]
Thanks in advance :)

What event.target will contain if I added submit event listener on the form

I have a lot of forms on the page and when one of them is submitted I want to send request via ajax to the view and have an id of the article and other info. So I need to check if form that has been clicked is the same as event.target. I did something like this but don't know if it is correct(first console.log works but second not):
<div id = "list">
{% for article in news %}
<h1>{{ article.title }}</h1>
<p>{{ article.published }}</p>
<img src = "{{ article.url }}">
<p>
<button>Upvote</button>
<button>Downvote</button>
</p>
<div id="span">
{% with article.upvotes.count as total_upvotes and article.downvotes.count as total_downvotes %}
<span upvote-id = "{{ article.id }}">{{ total_upvotes }}</span><span> upvote{{ total_votes|pluralize}}</span>
<span downvote-id = "{{ article.id }}">{{ total_downvotes }}</span><span> downvote{{ total_votes|pluralize}}</span>
{% endwith %}
</div>
<form method = 'post' action = '{% url "news:news_list" %}' form-id = '{{ article.id }}' class="form">
{{ form.as_p }}
{% csrf_token %}
<input type = "submit" value = "post">
</form>
{% endfor %}
</div>
{% endblock %}
{% block domready %}
const
list = document.getElementById('list'),
items = document.getElementsByClassName('vote');
forms = document.getElementsByClassName('form');
list.addEventListener('click', voteFunc);
list.addEventListener('submit', commentFunc);
function commentFunc(event){
event.preventDefault();
const clickedForm = event.target;
console.log('event triggered');
for (let form in forms){
if (form == clickedForm){
console.log('form is event.target')
$.ajax({
url: '{% url "news:news_list" %}',
type: 'POST',
data: {'id':$(event.target).attr('form-id'), 'title':$(this).elemets['title_field'].text(), 'body':$(this).elemets['body_field'].text()},
dataType: 'json'
})
}
}
}
Hope to hear advice how to implement it better and what event.target contains
You can write event handler for form submit event .So, whenever submit button(post) is clicked this event will get called then use .serialize() method to get all inputs inside your form and also attach form-id using &name=value and then you can pass same to backend.
Demo Code :
//when form will get submit
$("form.form").submit(function(e) {
//serialize will get all inputs as name=value separted wth `& `
console.log("data to send --> " + $(this).serialize() + "&id=" + $(this).attr('form-id'))
$.ajax({
type: "POST",
url: '{% url "news:news_list" %}',
data: $(this).serialize() + "&id=" + $(this).attr('form-id'), //send same
dataType: 'json'
});
e.preventDefault();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="list">
<a href="{{ article.resource }}">
<h1>A1</h1>
</a>
<p>abcd..</p>
<img src="{{ article.url }}">
<p>
<button>Upvote</button>
<button>Downvote</button>
</p>
<div id="span">
<span upvote-id="1">23</span><span> 54</span>
<span downvote-id="1">2</span><span> 56</span>
</div>
<form method='post' action='{% url "news:news_list" %}' form-id='1' class="form">
<p><label>somehting:</label>
<input type="text" name="something"></p>
<input type="submit" value="post">
</form>
<a href="{{ article.resource }}">
<h1>A</h1>
</a>
<p>abcd..</p>
<img src="{{ article.url }}">
<p>
<button>Upvote</button>
<button>Downvote</button>
</p>
<div id="span">
<span upvote-id="2">23</span><span> 54</span>
<span downvote-id="2">2</span><span> 56</span>
</div>
<form method='post' action='{% url "news:news_list" %}' form-id='2' class="form">
<p><label>somehting:</label>
<input type="text" name="something"></p>
<input type="submit" value="post">
</form>
</div>

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.

Checkbox filter array values not joining in url

I am trying to create a set of filters using checkboxes. When a box is checked, the value is added to the url and the page content filters accordingly.
As it stands, the filters and script is working, but instead of multiple values being joined in the url and content being displayed, the url is being overridden and only using one value from the checkbox array. For example, if WordPress and XL selected, only WordPress will show in the url. I have had a version of this script working but for select options with no issue, but checkboxes are proving an issue and i'm not sure what i've missed..
Can anyone point me in the right direction? : )
Shopify.queryParams = {};
if (location.search.length) {
for (var aKeyValue, i = 0, aCouples = location.search.substr(1).split('&'); i < aCouples.length; i++) {
aKeyValue = aCouples[i].split('=');
if (aKeyValue.length > 1) {
Shopify.queryParams[decodeURIComponent(aKeyValue[0])] = decodeURIComponent(aKeyValue[1]);
}
}
}
jQuery('.coll-picker').change(function() {
if (jQuery(this).val()) {
location.href = '/collections/' + jQuery(this).val();
}
else {
location.href = '/collections/all';
}
});
/* Specify the input */
var collFilters = jQuery('.coll-filter');
collFilters.change(function() {
delete Shopify.queryParams.page;
/* declare an array */
var newTags = [];
// console.log(newTags);
/* This works - if (this) is checked, push value from array : only working for one value though */
collFilters.each(function() {
//if (jQuery(this).val()) { // this works for select options
if (jQuery(this).is(':checked')) {
newTags.push(jQuery(this).val());
// var id = $(this).attr("id"); alert("Checked: " + id);
}
});
{% if collection.handle %}
var newURL = '/collections/{{ collection.handle }}';
if (newTags.length) {
newURL += '/' + newTags.join('+');
}
var search = jQuery.param(Shopify.queryParams);
if (search.length) {
newURL += '?' + search;
}
location.href = newURL;
{% else %}
if (newTags.length) {
Shopify.queryParams.constraint = newTags.join('+');
}
else {
delete Shopify.queryParams.constraint;
}
location.search = jQuery.param(Shopify.queryParams);
{% endif %}
});
<form class="lmwd-filter" method="post">
<ul class="clearfix filter-category">
<li>
<p>Category</p>
{% assign tags = 'Ecommerce, Woocommerce, WordPress, Magento 2' | split: ',' %}
{% for t in tags %}
{% assign tag = t | strip %}
<label for="{{ tag }}">
<input type="checkbox" id="{{ tag | handle }}" class="chk coll-filter" name="{{ tag | handle }}" value="{{ tag | handle }}" />
{{ tag }}
</label>
{% endfor %}
</li>
<li><br /></li>
<li>
<p>Size</p>
{% assign tags = 'XS, S, M, L, XL' | split: ',' %}
{% for t in tags %}
{% assign tag = t | strip %}
<label for="{{ tag }}">
<input type="checkbox" id="{{ tag | handle }}" class="chk coll-filter" name="{{ tag | handle }}" value="{{ tag | handle }}" />
{{ tag }}
</label>
{% endfor %}
</li>
</ul>
</form>

Hide variants that aren't available in Shopify?

Right now in default Shopify no matter what you select on style you'll still be able to choose any of those sizes even if it's not available for that style. I followed the instructions here: http://wiki.shopify.com/Linked_Options
It works great except that the second option list has duplicated items in it. Any idea why? here is what I have on my product-form.liquid. You can see it in action on my site here: http://gravitypicks.myshopify.com/collections/picks/products/axis
{% if product.available %}
<form action="/cart/add" method="post" class="clearfix product_form shappify_add_to_cart_form" enctype="multipart/form-data" data-money-format="{{ shop.money_format }}" data-shop-currency="{{ shop.currency }}" id="product-form-{{ product.id }}">
{% if settings.display_inventory_left %}
<div class="items_left">
{% if product.variants.first.inventory_management == "shopify" and product.variants.first.inventory_quantity > 0 %}
<p><em>{{ product.variants.first.inventory_quantity }} {{ settings.inventory_left_text | escape }}</em></p>
{% endif %}
</div>
{% endif %}
{% if product.options.size > 1 %}
<div class="select">
<select id="product-select-{{ product.id }}" name='id'>
{% for variant in product.variants %}
<option {% if variant == product.selected_or_first_available_variant %}selected="selected"{% endif %} value="{{ variant.id }}">{{ variant.title }}</option>
{% endfor %}
</select>
</div>
{% elsif product.options.size == 1 and (product.variants.size > 1 or product.options[0] != "Title") %}
<div class="select">
<label>{{ product.options[0] }}:</label>
<select id="product-select-{{ product.id }}" name='id'>
{% for variant in product.variants %}
<option {% if variant == product.selected_or_first_available_variant %}selected="selected"{% endif %} value="{{ variant.id }}">{{ variant.title }}</option>
{% endfor %}
</select>
</div>
{% else %}
<input type="hidden" name="id" value="{{ product.variants.first.id }}" />
{% endif %}
<!-- Bold Apps: Product Options -->
{% include 'shappify-options' %}
{% if settings.display_product_quantity %}
<div class="left">
<label for="quantity">Quantity:</label>
<input type="number" min="1" size="2" class="quantity" name="quantity" id="quantity" value="1" />
</div>
{% endif %}
<div class="purchase clearfix {% if settings.display_product_quantity %}inline_purchase{% endif %}">
{% if settings.cart_return == 'back' %}
<input type="hidden" name="return_to" value="back" />
{% endif %}
<input type="submit" name="add" value="{{ settings.add_to_cart_text | escape }}" class="action_button add_to_cart" />
</div>
</form>
{% if product.variants.size > 1 or product.options.size > 1 %}
<script type="text/javascript">
// <![CDATA[
$(function() {
$product = $('#product-' + {{ product.id }});
new Shopify.OptionSelectors("product-select-{{ product.id }}", { product: {{ product | json }}, onVariantSelected: selectCallback{% if product-form == 'product' %}, enableHistoryState: true{% endif %} });
{% if product.available and product.options.size > 1 %}
Shopify.linkOptionSelectors({{ product | json }});
{% endif %}
});
// ]]>
</script>
{% endif %}
{% endif %}
Here is the JS that is on the page:
<script>
// (c) Copyright 2014 Caroline Schnapp. All Rights Reserved. Contact: mllegeorgesand#gmail.com
// See http://docs.shopify.com/manual/configuration/store-customization/advanced-navigation/linked-product-options
var Shopify = Shopify || {};
Shopify.optionsMap = {};
Shopify.updateOptionsInSelector = function(selectorIndex) {
switch (selectorIndex) {
case 0:
var key = 'root';
var selector = jQuery('.single-option-selector:eq(0)');
break;
case 1:
var key = jQuery('.single-option-selector:eq(0)').val();
var selector = jQuery('.single-option-selector:eq(1)');
break;
case 2:
var key = jQuery('.single-option-selector:eq(0)').val();
key += ' / ' + jQuery('.single-option-selector:eq(1)').val();
var selector = jQuery('.single-option-selector:eq(2)');
}
var initialValue = selector.val();
selector.empty();
var availableOptions = Shopify.optionsMap[key];
for (var i=0; i<availableOptions.length; i++) {
var option = availableOptions[i];
var newOption = jQuery('<option></option>').val(option).html(option);
selector.append(newOption);
}
jQuery('.swatch[data-option-index="' + selectorIndex + '"] .swatch-element').each(function() {
if (jQuery.inArray($(this).attr('data-value'), availableOptions) !== -1) {
$(this).removeClass('soldout').show().find(':radio').removeAttr('disabled','disabled').removeAttr('checked');
}
else {
$(this).addClass('soldout').hide().find(':radio').removeAttr('checked').attr('disabled','disabled');
}
});
if (jQuery.inArray(initialValue, availableOptions) !== -1) {
selector.val(initialValue);
}
selector.trigger('change');
};
Shopify.linkOptionSelectors = function(product) {
// Building our mapping object.
for (var i=0; i<product.variants.length; i++) {
var variant = product.variants[i];
if (variant.available) {
// Gathering values for the 1st drop-down.
Shopify.optionsMap['root'] = Shopify.optionsMap['root'] || [];
Shopify.optionsMap['root'].push(variant.option1);
Shopify.optionsMap['root'] = Shopify.uniq(Shopify.optionsMap['root']);
// Gathering values for the 2nd drop-down.
if (product.options.length > 1) {
var key = variant.option1;
Shopify.optionsMap[key] = Shopify.optionsMap[key] || [];
Shopify.optionsMap[key].push(variant.option2);
Shopify.optionsMap[key] = Shopify.uniq(Shopify.optionsMap[key]);
}
// Gathering values for the 3rd drop-down.
if (product.options.length === 3) {
var key = variant.option1 + ' / ' + variant.option2;
Shopify.optionsMap[key] = Shopify.optionsMap[key] || [];
Shopify.optionsMap[key].push(variant.option3);
Shopify.optionsMap[key] = Shopify.uniq(Shopify.optionsMap[key]);
}
}
}
// Update options right away.
Shopify.updateOptionsInSelector(0);
if (product.options.length > 1) Shopify.updateOptionsInSelector(1);
if (product.options.length === 3) Shopify.updateOptionsInSelector(2);
// When there is an update in the first dropdown.
jQuery(".single-option-selector:eq(0)").change(function() {
Shopify.updateOptionsInSelector(1);
if (product.options.length === 3) Shopify.updateOptionsInSelector(2);
return true;
});
// When there is an update in the second dropdown.
jQuery(".single-option-selector:eq(1)").change(function() {
if (product.options.length === 3) Shopify.updateOptionsInSelector(2);
return true;
});
};
</script>
This link here helped immensely. I had to do some tweaking to fit my uses but it was 99% there for me.
http://docs.shopify.com/manual/configuration/store-customization/advanced-navigation/linked-product-options

Categories