Django Javascript not working in HTML to Ajax call - javascript

I'm trying to detect changes in a Form to change the following parameters depending on the previous one.
Concretely when I change id_send_to(Client) it shows a list of companies from the client.
I think that this should be done with Ajax Call.
This is the code and when I check in the inspector I cannot see the console.log
{% extends "helpdesk/base.html" %}
{% load i18n bootstrap %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$("#id_send_to").change(function () {
console.log( $(this).val() );
});
});
</script>
Any Idea ?
<form method='post' action='./' enctype='multipart/form-data'>
<fieldset>
{{ form|bootstrap }}
{% comment %}
{% for field in form %}
{% if field.is_hidden %}
{{ field }}
{% else %}
<dt><label for='id_{{ field.name }}'>{% trans field.label %}</label>{% if not field.field.required %} <span class='form_optional'>{% trans "(Optional)" %}</span>{% endif %}</dt>
<dd>{{ field }}</dd>
{% if field.errors %}<dd class='error'>{{ field.errors }}</dd>{% endif %}
{% if field.help_text %}<dd class='form_help_text'>{% trans field.help_text %}</dd>{% endif %}
{% endif %}
{% endfor %}
{% endcomment %}
<div class='buttons form-group'>
<input type='submit' class="btn btn-primary" value='{% trans "Submit
Ticket" %}' />
</div>
</fieldset>
{% csrf_token %}</form>

Related

When select different options shows different input, but all inputs of all options are required

I'm working with Django and I made a function that creates a person (employee, student, or worker) and as you can see I created the three different forms on create_person, so on the template, when you select an option on school_role to choose what kind of person you will create, its shows different inputs and select, it depends if you click on student, academic or employee. This is ok, but my problem is that I need to fill all of the inputs and selects on all of the three options to be able to send the form, and I need that you just have to fill one ( employee, academic, or student).
def create_person(request):
if request.method == 'POST':
form = PersonForm(request.POST)
daysform = AvailableDayForm(request.POST)
studentForm = StudentForm(request.POST)
academicForm = AcademicForm(request.POST)
employeeForm = EmployeeForm(request.POST)
if form.is_valid() and daysform.is_valid():
data = form.save()
daysform.save(id=data.id)
id = data.id
if(data.school_role==1):
if studentForm.is_valid():
studentForm.save(id = id)
messages.success(
request=request,
message='success'
)
return redirect('cases:list')
elif(data.school_role == 2):
if academicForm.is_valid():
academicForm.save(id = id)
messages.success(
request=request,
message='success'
)
return redirect('cases:list')
else:
if employeeForm.is_valid():
employeeForm.save(id = id)
messages.success(
request=request,
message='success'
)
return redirect('cases:list')
else:
form = PersonForm()
daysform = AvailableDayForm()
studentForm = StudentForm()
academicForm = AcademicForm()
employeeForm = EmployeeForm()
context = {
'form': form,
'studentForm': studentForm,
'academicForm': academicForm,
'employeeForm': employeeForm,
'daysform': daysform
}
return render(request, 'person/create_person.html', context)
This is the template create_person.html:
<div class="columns">
<div class="column">
<h1 class="title">New person </h1>
</div>
</div>
<div class="card">
<div class="card-content">
<form method="post">
{% csrf_token %}
{% for non_field_error in form.non_field_errors %}
<p class="help is-danger">{{ non_field_error }}</p>
{% endfor %}
{% for field in form %}
<div class="field">
<div class="control">
<label for="{{ field.id_for_label }}" class="label">
{{field.label}}
</label>
{% if field.field.widget.input_type == 'select' %}
{%if field.name == 'school_role'%}
<div class="select">
<select onchange="yesnoCheck(this);" name = "school_role" required>
<option value="">--------</option>
<option value="1">Student</option>
<option value="2">Academic</option>
<option value="3">Employee</option>
</select>
</div>
<div id="ifStudent" style="display: none;">
{% for field in studentForm %}
<label for="{{ field.id_for_label }}" class="label">
{{field.label}}
</label>
{% if field.field.widget.input_type == 'select' %}
<div class="select">
{{ field }}
</div>
{% else %}
{{ field }}
{% endif %}
{% for error in field.errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
{% endfor %}
</div>
<div id="ifAcademic" style="display: none;">
{% for field in academicForm %}
<label for="{{ field.id_for_label }}" class="label">
{{field.label}}
</label>
{% if field.field.widget.input_type == 'select' %}
<div class="select">
{{ field }}
</div>
{% else %}
{{ field }}
{% endif %}
{% for error in field.errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
{% endfor %}
</div>
<div id="ifWorker" style="display: none;">
{% for field in employeeForm %}
<label for="{{ field.id_for_label }}" class="label">
{{field.label}}
</label>
{% if field.field.widget.input_type == 'select' %}
<div class="select">
{{ field }}
</div>
{% else %}
{{ field }}
{% endif %}
{% for error in field.errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
{% endfor %}
</div>
{%else%}
<div class="select">
{{ field }}
</div>
{% endif %}
{% else %}
{{ field }}
{% endif %}
{% for error in field.errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
</div>
</div>
{% endfor %}
And this is my script.
function yesnoCheck(that) {
if (that.value == "1") {
document.getElementById("ifStudent").style.display = "block";
} else {
document.getElementById("ifStudent").style.display = "none";
}
if (that.value == "2"){
document.getElementById("ifAcademic").style.display = "block";
} else {
document.getElementById("ifAcademic").style.display = "none";
}
if (that.value == "3"){
document.getElementById("ifWorker").style.display = "block";
}else{
document.getElementById("ifWorker").style.display = "none";
}
}

Counter variable not updating correctly

EDIT:
As several of you pointed out, the "submit" type reloads the page each time, so a running count is not maintained. I fixed this by using sessionStorage to store the number. Here's the fixed code:
function addItem(){
window.sessionStorage.setItem('count',Number(window.sessionStorage.getItem('count'))+1);
/*if(currentItems>3){
currentItems=3;
}*/
console.log("Item added");
update();
}
function removeItem(){
window.sessionStorage.setItem('count',Number(window.sessionStorage.getItem('count'))-1);
/*if(currentItems<0){
currentItems=0;
}*/
console.log("Item removed");
update();
}
function update(){
console.log(Number(window.sessionStorage.getItem('count')));
}
Original Question:
I don't have much experience in JS so forgive me if this is a silly question. I created the following script to count the number of items added to a bundle of products:
var currentItems=0;
function addItem(){
++currentItems;
/*if(currentItems>3){
currentItems=3;
}*/
console.log("Item added");
update();
}
function removeItem(){
--currentItems;
/*if(currentItems<0){
currentItems=0;
}*/
console.log("Item removed");
update();
}
function update(){
console.log(currentItems);
}
The addItem and removeItem events are triggered by "onclick" tags on certain buttons. When I check the console, it correctly shows the "Item added" and "Item removed" messages, but it displays the wrong number for currentItems. When I click a button that should trigger addItems, the console displays 1 regardless of how many items I've added. Similarly, when I click a button that triggers removeItems, the console displays -1. It seems like the variable is starting from 0 each time I click. Any ideas on how to fix this?
EDIT:
Here's the full code. I'm building a custom template within the Bundle Builder Shopify App, so everything aside from the CSS styling and my script are default.
<style type="text/css">
.product-box {
display: flex;
width: 50%;
float: left;
margin-left:15%;
}
.product {
display: flex;
flex-direction: column;
}
.note-field--container {
display: flex;
flex-direction: column;
}
.bundle-content{
width:20%;
float:left;
margin-right:5%;
}
#outside-progress{
background-color:grey;
width: 30%;
}
#inside-progress{
background-color:#202945;
height:30px;
}
</style>
<script type="text/javascript">
const selectedVariants = new Map();
function setAddDisabled(form) {
const variantId = form.querySelector('[name="variant"]').value;
const sectionId = form.querySelector('[name="section"]').value;
const canAdd = window.BundleBuilder.canAddVariant(variantId, sectionId);
form.querySelector('[type="submit"]').disabled = !canAdd;
}
/* Change variant price after variant change */
Array.prototype.forEach.call(
document.querySelectorAll('.bundle-builder--add-to-bundle-form select[name="variant"]'),
function (select) {
select.addEventListener('change', function (e) {
const variantId = e.target.value;
selectedVariants.set(e.target.id, variantId);
const price = e.target.querySelector('option[value="' + variantId + '"]').dataset.price;
e.target.parentNode.querySelector('.variant-price').textContent = price;
const form = e.target.parentElement;
setAddDisabled(form);
});
}
);
function render() {
selectedVariants.forEach(function (variantId, selectId) {
const select = document.getElementById(selectId);
if (select) {
select.value = variantId;
}
});
Array.prototype.forEach.call(
document.querySelectorAll('.bundle-builder--add-to-bundle-form'),
setAddDisabled,
);
}
/* Change variant to what was selected last */
document.body.addEventListener('bundlebuilder:render', render);
render()
</script>
{% if bundle.published %}
<h1>{{ bundle.current_section.name }}</h1>
<div id="outside-progress">
<div id="inside-progress"></div>
</div>
<div class="product-box">
{% for product in bundle.current_section.products %}
<div class="product">
<h2>{{ product.title }}</h2>
<img src="{{ product.image.src }}" />
{% add_to_bundle_form bundle.current_section %}
{% if product.available_variants.size > 1 %}
<select name="variant" id="select-{{ bundle.current_section.index }}-{{ product.id }}">
{% for variant in product.available_variants %}
<option value="{{ variant.id }}" data-price={{ variant.price | money }}>
{{ variant.title }}{% if variant.available_count %} (available: {{ variant.available_count }}){% endif %}
</option>
{% endfor %}
</select>
{% else %}
<input type="hidden" name="variant" value="{{ product.available_variants[0].id }}" />
{{ product.available_variants[0].title }}{% if product.available_variants[0].available_count %} (available: {{ product.available_variants[0].available_count }}){% endif %}
{% endif %}
<span class="variant-price">{{ product.available_variants[0].price | money }}</span>
<button type="submit" style="color:#ffffff; background-color:#202945;" onclick="addItem()">Add</button>
{% end_add_to_bundle_form %}
{% for variant in product.variants_in_bundle %}
{% change_quantity_form %}
{% comment %}{{ variant.title }}{% endcomment %}
<input type="hidden" name="variant" value="{{ variant.id }}" />
<input type="hidden" name="section" value="{{ bundle.current_section.index }}" />
<button type="submit" name="remove" onClick="removeItem()">-</button>
{{ variant.count }}
<button type="submit" name="add" onclick="addItem()">+</button>
{% end_change_quantity_form %}
{% endfor %}
</div>
{% endfor %}
</div>
{% if bundle.has_next_section %}
{% section_switch_form %}
<input type="hidden" name="section" value="{{ bundle.current_section.index | plus: 1 }}" />
<button type="submit" style="color:#ffffff; background-color:#202945;">Next</button>
{% end_section_switch_form %}
{% endif %}
{% if bundle.has_prev_section %}
{% section_switch_form %}
<input type="hidden" name="section" value="{{ bundle.current_section.index | plus: -1 }}" />
<button type="submit" style="color:#ffffff; background-color:#202945;">Previous</button>
{% end_section_switch_form %}
{% endif %}
{% if bundle.errors.size > 0 %}
<ul>
{% for error in bundle.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
<div class="bundle-content">
{% if bundle.content.items.size == 0 %}
<span>Your bundle is empty</span>
{% else %}
<table>
<tr>
<th>Product</th>
<th>Variant</th>
<th>Price</th>
<th></th>
</tr>
{% for item in bundle.content.items %}
<tr>
<td>{{ item.variant.product.title }}</td>
<td>{{ item.variant.title }}</td>
<td>{{ item.variant.price | money }}</td>
<td>
{% unless item.is_required %}
{% remove_from_bundle_form item %}
<button type="submit" style="color:#ffffff; background-color:#202945;" name="remove" onclick="removeItem()">Remove</button>
{% end_remove_from_bundle_form %}
{% endunless %}
</td>
</tr>
{% endfor %}
{% if bundle.content.price < bundle.content.compare_at_price %}
<tr>
<th colspan="2">Discount</th>
<th>
<span>{{ bundle.content.price | minus: bundle.content.compare_at_price | money }}</span>
</th>
<th></th>
</tr>
{% endif %}
<tr>
<th colspan="2">Total</th>
<th>
<span>{{ bundle.content.price | money }}</span>
</th>
<th></th>
</tr>
</table>
{% if settings.note_enabled %}
<div class="note-field--container">
<label>{{ settings.note_label }}{% if settings.note_required %} (required){% endif %}</label>
{% note_field %}{{ settings.note_text }}{% end_note_field %}
</div>
{% if settings.note_prompt_visible %}
<div class="note-field--error-message">
<p>Note required before adding to cart.</p>
</div>
{% endif %}
{% endif %}
{% add_to_cart_form %}
{% if bundle.subscription_type == 'optional' and bundle.subscription_frequencies.size > 0 %}
<label>
<input type="radio" name="subscription-enabled" value="0" />
One-time purchase
</label>
<label>
<input type="radio" name="subscription-enabled" value="1" />
Subscribe
</label>
{% endif %}
{% if bundle.subscription_type == 'required' or bundle.subscription_enabled %}
{% for frequency in bundle.subscription_frequencies %}
<ul>
<li>
<label>
<input type="radio" name="subscription-frequency" value="{{ frequency.id }}" />
{{ frequency.frequency }} {{ frequency.unit }}
</label>
</li>
</ul>
{% endfor %}
Email: <input type="email" required name="subscription-email" value="{{ settings.subscription_email }}" />
{% endif %}
<button type="submit"{% unless bundle.can_add_to_cart %} disabled="disabled"{% endunless %} style="color:#ffffff; background-color:#202945;">
{% if bundle.adding_to_cart %}
Processing...
{% else %}
Add bundle to cart
{% endif %}
</button>
{% end_add_to_cart_form %}
{% endif %}
</div>
{% else %}
<p>Sorry, this bundle is currently unavailable.</p>
{% endif %}
<script type="text/javascript">
/* Custom Progress Bar */
const progress = document.getElementById("inside-progress");
var currentItems=0;
function addItem(){
++currentItems;
/*if(currentItems>3){
currentItems=3;
}*/
console.log("Item added");
update();
}
function removeItem(){
--currentItems;
/*if(currentItems<0){
currentItems=0;
}*/
console.log("Item removed");
update();
}
function update(){
console.log(currentItems);
}
</script>
function addItem(){
window.sessionStorage.setItem('count',Number(window.sessionStorage.getItem('count'))+1);
/*if(currentItems>3){
currentItems=3;
}*/
console.log("Item added");
update();
}
function removeItem(){
window.sessionStorage.setItem('count',Number(window.sessionStorage.getItem('count'))-1);
/*if(currentItems<0){
currentItems=0;
}*/
console.log("Item removed");
update();
}
function update(){
console.log(Number(window.sessionStorage.getItem('count')));
}

Lemonstand makes radio buttons able to select more than one, how do I fix?

I can change the "checkbox" to "radio" but it still allows more than one to be selected. What can I do to only allow a single selection? Here's the site: https://winkdiapers.com/product/os-pocket-diaper
<div class="clearfix">
{% for index, extra in product.extras %}
<div class="extra">
<label class="title" for="{{ 'extra-'~index }}">
{% if extra.enabled %}
<input type="checkbox" id="{{ 'extra-'~index }}" {{ checkbox_state(postedExtras[extra.id], extra.id) }} name="extras[{{ extra.id }}]" data-ajax-handler="shop:product" data-ajax-update="#product-page=shop-product">
{% else %}
<input type="checkbox" disabled="disabled">
{% endif %}
{{ extra.name }} ({{ extra.price|currency }})</label>
</div>
{% endfor %}
</div>
{% endif %}

simulate label click on button click

please I need help simulating a label click when I click on the button.
I tried to make the label the same size as the button so when I click on the button it will check my checkbox, then I tried using java script to simulate the label click when i click on the button.
the problem is my label size is to small inside my button so I have to click inside the label to check.
this is my html file :
{%- block checkbox_widget -%}
<button class="btn-large waves-effect waves-light {% if checked %}disabled{% endif %}" style="margin-bottom:2%;">
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
<label for="{{ id }}" class="white-text" style="font-size: 22px;">{{ label|trans({}, translation_domain) }}</label>
</button>
{%- endblock checkbox_widget -%}
{%- block radio_widget -%}
<button class="btn-large waves-effect waves-light {% if checked %}disabled{%endif %}" style="margin-bottom:2%;">
<input type="radio" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
<label for="{{ id }}" class="white-text" style="font-size: 22px;">{{ label|trans({}, translation_domain) }}</label>
</button>
{%- endblock radio_widget -%}
I tried using the following modification + script
{%- block checkbox_widget -%}
<button class="btn-large waves-effect waves-light {% if checked %}disabled{% endif %}" id="button" onclick="myFunction()" style="margin-bottom:2%;">
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
<label for="{{ id }}" class="white-text" style="font-size: 22px;" id="check">{{ label|trans({}, translation_domain) }}</label>
</button>
<script>
function myFunction() {
buttn = document.getElementById("check");
buttn.click();
}
</script>
{%- endblock checkbox_widget -%}
can someone please correct my java script or tell me how the get my label the same size as my button.
Sorry for my english and thanks in advance :)
{%- block checkbox_widget -%}
<button class="btn-large waves-effect waves-light {% if checked %}disabled{% endif %}" id="button" onclick="myFunction()" style="margin-bottom:2%;"></button>
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %} />
<label for="{{ id }}" class="white-text" style="font-size: 22px;" id="check">{{ label|trans({}, translation_domain) }}</label>
<script>
function myFunction() {
buttn = document.getElementById("check");
buttn.click();
}
</script>
{%- endblock checkbox_widget -%}
Try this
First: are you putting more than one of these widgets on the page? If so, it won't work the way you expect since id should be unique to a single element.
Secondly: Since your label is tied to the checkbox (via the for property), if you click the label, it will seem as if nothing has happened, as the JS is sending a click, then the label is "undoing" it. See here: https://jsfiddle.net/q1vour7v/ and click on the label, then click on the edges away from the label.
In this version, the label is not tied to the checkbox, and it works as expected: https://jsfiddle.net/q1vour7v/1/

Customizing Dropdown on Shopify Product Page (Single Variant)

Working with one variant in Shopify on the product page dropdown, and would like it grayed out when not available (sold out).
Here's the code I have so far: (for the entire page)
{% include 'buyx-product' with product %}
{% include 'buyx-price-min' with product %}
{% assign option_to_match = settings.option_to_match %}
{% assign option_index = 0 %}
{% for option in product.options %}
{% if option == option_to_match %}
{% assign option_index = forloop.index0 %}
{% endif %}
{% endfor %}
{% if buyx_product_available %}
<form action="/cart/add" method="post" class="clearfix product_form" data-money-format="{{ shop.money_format }}" data-option-index="{{ option_index }}" id="product-form-{{ product.id }}">
{% if product.options.size > 1 and (product.options[1] != "BuyXDiscount") %}
<div class="select">
<select id="product-select-{{ product.id }}" name='id'>
{% for variant in product.variants %}
{% unless variant.title contains '% Off' %}
<option value="{{ variant.id }}">{{ variant.title }}</option>
{% endunless %}
{% endfor %}
</select>
</div>
{% elsif buyx_select_one_option and (product.variants.size > 1 or product.options[0] != "Title" or product.options.first != 'BuyXDiscount') %}
<div class="select">
<label>{{ product.options[0] }}:</label>
<select id="product-select-{{ product.id }}" name='id'>
{% for variant in product.variants %}
{% unless variant.title contains '% Off' %}
<option value="{{ variant.id }}">{{ variant.title }}</option>
{% endunless %}
{% endfor %}
</select>
</div>
{% else %}
<input type="hidden" name="id" value="{{ product.variants.first.id }}" />
{% endif %}
{% include 'swatch' with 'Color' %}
{% 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="Add to Cart" class="action_button add_to_cart" />
</div>
<script data-product="{{ product | json | escape }}" id="out-of-stock" src="http://setup.shopapps.io/out-of-stock/script/nisolo.js"></script>
</form>
{% if buyx_product_variants_size > 1 %}
<script type="text/javascript">
// <![CDATA[
$(function() {
function buyx_product_json(product) {
var variants = []
//does it have BuyXDiscount option?
var option_position = -1
for (var oi = 0, olen = product.options.length; oi < olen; oi++) {
if (product.options[oi] == "BuyXDiscount") {
option_position = oi+1
break
}
}
if (option_position == -1) {
return product
}
if (product.options.length > 1) {
product.options.splice(option_position-1, 1)
} else {
product.options[0] = "Title"
}
option_position = "option" + option_position
product.available = false
for (var vi = 0, vlen = product.variants.length; vi < vlen; vi++) {
if (product.variants[vi][option_position] == "Default") {
product.variants[vi][option_position] = ""
variants.push(product.variants[vi])
product.available = product.available || product.variants[vi].available
}
}
product.variants = variants
return product
}
<strong>$product = $('#product-' + {{ product.id }});
// if($('.single-option-selector', $product).length == 0) {
new Shopify.OptionSelectors("product-select-{{ product.id }}", { product: buyx_product_json({{ product | json }}), onVariantSelected: selectCallback });
{% if product.available %}
{% assign found_one_in_stock = true %}
{% for variant in product.variants %}
{% if variant.available == false %}
jQuery('.single-option-selector option:eq({{ forloop.index0 }})').attr('disabled', 'disabled');
{% endif %}
{% endfor %}
{% endif %}</strong>
//}
});
// ]]>
</script>
{% endif %}
{% endif %}
Unfortunately, what's happening is that instead of the product with 0 inventory being grayed out, the product prior to the product with 0 inventory is being grayed out. For example, in the screenshot below, size 9.5 is the size with zero inventory, but size 9 is showing as grayed out.
When I say manually, I mean something like this...
<select>
{% for variant in product.variants %}
{% if variant.available %}
<option value="{{variant.id}}">{{variant.title}}</option>
{% else %}
<option value="{{variant.id}}" disabled>{{variant.title}}</option>
{% endif %}
{% endfor %}
</select>
Perhaps instead of using the for loop index, you could select the option with the corresponding variant title or id? Something like this:
{% unless variant.available %}
jQuery('.single-option-selector option[value="{{ variant.title }}"]').attr('disabled', 'disabled');
{% endunless %}
This answer might also be useful:
jQuery('.single-option-selector option:contains({{ variant.title | json }})')...
although option:contains may not work in your situation where you have sizes like 9 and 9.5.
EDIT:
From the link you provided, it looks like Size is option2, so try this:
jQuery('.single-option-selector option[value="{{ variant.option2 }}"]').attr('disabled', 'disabled');

Categories

Resources