jquery use diferente variables in the same <p> from fields from database - javascript

http://prntscr.com/ir16ez
I have a problem, i cannot put diferent amounts in my shopping cart because when i choose a quantity, the program take what i choose and does the result for money etc,(working fine here) and brings the quantity to the shopping cart named "encomenda" but when i add a diferent item, the quantity changes to all instead of changing to only one, ssry from my english
//shopping cart html
<div class="rightdiv">carrinho
<div id="encomenda" class="expandContent">
<h3 class="header">
<div class="headerColumn1">Encomenda</div>
<div class="headerColumn2 expand"><img src="img/plus.png"/></div>
<div class="expandedContentClearFloat"></div>
</h3>
<div class="expandedContent">
{% for item in data %}
<div class="product-removal">
<article class="product">
<header>
<img src="{{ item.img|e }}" class="iconcomp">
</header>
<div class="content">
<h1>{{ item.marca|e }}</h1>
{{ item.descr|e }}
</div>
<footer class="content">
<h2 class="full-price fixed fixed-encomenda">
{{ item.preco_unit|e }}€
</h2>
<p class='quantidade' ></p> **//shows the amount here**
<a class='pull-right adicionar adicionar-encomenda' data-id='{{ item.id|e }}'
data-preco='{{ item.preco_unit|e }}' data-modelo="{{ item.modelo|e }}" data-marca="{{ item.marca|e }}" data-descr="{{ item.descr|e }}">
<h2 class="full-price">
{{ item.preco_unit|e }}€
</h2>
</a>
<h2 class="price">
{{ item.preco_unit|e }}
</h2>
</footer>
</article>
</div>
{% endfor %}
<h1 id='valor_configuracao' class='pull-right' value='data-preco'>0</h1>
</div>
<input type="button" id="enviar" value="enviar" data-mensagem="ola">
</div>
</div>
//add disco for example
$('.adicionar-disco').click(function () {
id = $(this).data('id');
var allExceptClicked = $('.adicionar-disco').not(this);
AdicionarItem(allExceptClicked, "disco", "disco2");
$(this).data('quantidade', parseFloat($(this).parent().find("span.qt").text()));
$(this).parent().parent().find("button.close-disco").data('quantidade', parseFloat($(this).parent().find("span.qt").text()));
preco = preco + ($(this).data("preco")* $(this).data('quantidade'));
p=$(this).data('quantidade'); **//receive in p the amount**
var rounded = Math.round((preco) * 100) / 100;
$('#valor_configuracao').html(rounded);
$('.adicionar-encomenda').each(function () {
var productRow = $(this).parent().parent();
var i = $(this).data('id');
if (i == id) {
productRow.show();
alert(p);
$(".quantidade").text(p);**//give the <p> variable that is in the "encomenda" p that has the amount needed**
//$("p").attr(".quantidade",p);
//Marcar item como selecionado
$(this).attr("data-selecionado","sim");
}
});
});

the statement $(".quantidade").text(p) set the same value at all element with class="quantitade", and all item of your chart have class="quantitade".
You should uniquely identify the div where you want to set the value, with id attribute, if possible, generated with the product id.

Related

Chart js multiple pie chart on one page

Iam building my portfolio website and i build a simple stocktracker. I added some charts from Chart.js, but somehow only one gets rendered when I excecute the code.
I managed to assign all the divs and data dynamically by making the variables dynamic. I did this by adding the portfolio id in the for loop. I can't figure out why its not working. Appreciate any help.
{% extends 'base.html' %}
{% block page_content %}
{% if user.is_authenticated %}
<body>
<div class="container">
<div class="row">
<div class="col-12">
<h2>
Welcome to the stocktracker
</h2>
<p>I build this stocktracker app to learn database operations. To get current stock data, I linked this to
the free API from Polygon.io. It's only possible to do 5 API calls per minute. You will see an error
message whenever the api calls are exceeded.
<br><br>Current features are:
<ol>
<li>Basic CRUD database operation</li>
<li>Adding portfolio's linked to user</li>
<li>Only show portfolio's linked to user</li>
<li>Show general KPI's in portfolio overview</li>
<li>KPI's calculated based on positions in portfolio</li>
<li>Adding position to portfolio</li>
<li>API connection with Polygon.io to get live stock data</li>
<li>Chart.js integration for visual representation of portfolio metrics</li>
</ol>
</p>
</div>
</div>
<div class="row">
<div class="col-8">
<h2>Select your portfolio</h2>
</div>
<div class="col-4 text-end">
<!-- Button trigger modal -->
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#addPortfolioModal">
Add new portfolio
</button>
<!-- Modal -->
<div class="modal fade" id="addPortfolioModal" tabindex="-1" role="dialog"
aria-labelledby="addPortfolioModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addPortfolioLabel">Modal title</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form name="portfolio_form" method="post">
{% csrf_token %}
<p>
{{ portfolio_form }}
</p>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close
</button>
<input type="submit" value="Submit"/>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div>
{% for portfolio in portfolios %}
<div class="row pt-4">
<div class="col-6">
<a class="btn btn-primary" href="{% url 'portfolio_detail' portfolio.pk%}">Go to {{ portfolio }}</a>
</div>
</div>
{% if portfolio.total_positions > 0 %}
<div>
{% load static %}
<div class="col-4 text-start" style="width: 50%;">
<canvas id="pie-chart{{ portfolio.pk }}"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.3/dist/Chart.min.js"></script>
<script>
var randomNum_{{ portfolio.pk }} = () => Math.floor(Math.random() * (235 - 52 + 1) + 52);
function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
countPositions = {{ portfolio.total_positions|safe }};
var barColors_{{ portfolio.pk }} = [];
for (let i = 0; i < countPositions; i++) {
randomGeneratedColor = rgbToHex(randomNum_{{ portfolio.pk }}(), randomNum_{{ portfolio.pk }}(), randomNum_{{ portfolio.pk }}());
while (barColors_{{ portfolio.pk }}.includes(randomGeneratedColor)) {
randomGeneratedColor = rgbToHex(randomNum(), randomNum(), randomNum());
}
barColors_{{ portfolio.pk }}.push(randomGeneratedColor);
}
var config_{{ portfolio.pk }} = {
type: 'pie',
data: {
datasets: [{
data: {{ portfolio.data_for_chart_array|safe }},
backgroundColor: barColors_{{ portfolio.pk }},
label: 'Stock ticker'
}],
labels: {{ portfolio.labels_array|safe }}
},
options: {
responsive: true
}
};
window.onload = function() {
var ctx = document.getElementById('pie-chart{{ portfolio.pk }}').getContext('2d');
window.myPie = new Chart(ctx_{{ portfolio.pk }}, config_{{ portfolio.pk }});
};
</script>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-4 pt-2">
<b>Total amount invested:</b> {{ portfolio.total_amount_invested }}
<br><b>Positions:</b> {{ portfolio.total_positions }}
<br><b>Profit:</b> {{ portfolio.total_profit }}
<br><b>Profit in %:</b> {{ portfolio.total_profit_percentage }} %
</div>
</div>
</div>
{% endfor %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"></script>
</div>
</body>
{% endif %}
{% endblock %}
Somehow only the last chart gets rendered instead of all three.
You have a loop there, and in each iteration of the loop, you're using window.onload = function() {…};
Basically, you're overwriting the onload function at each iteration of the loop, so only the last overwrite survives.
What you want is to add load event listeners on the window instead of continually overwriting one single listener.
To achieve this, I would recommend replacing this:
window.onload = function () {…}
with this:
window.addEventListener('load', function() {…})`
See addEventListener
Another way of seeing that window.onload = function () {…} is problematic is the following snippet:
window.onload = function () { alert('one') };
window.onload = function () { alert('two') };
Q: What do you expect to happen on page load here?
A: Similarly to your case, only the second function (alerting "two") will be called.

How to change contents on clicking the selected div using Javascript?

I am new to Javascript. I wish to change the contents of div on selecting a particular div element.
If I select a div, the text associated with that div contents only should display. I am using a loop to display the contents. It's like a chat application. If a user clicks on a contact the messages associated with that user should display. I am using a loop to display messages and users.
What I have tried is:
Twig code:
{% set msg = query().from('messages').get() %}
{% set to_add =to_name %}
{% set to_details = query().from('users_users').where('id', to_add).get() %}
<div class="container">
<h3 class=" text-center">Messaging</h3>
<div class="messaging">
<div class="inbox_msg">
<div class="inbox_people">
<div class="headind_srch">
<div class="recent_heading">
<h4>{{auth_user().first_name}}</h4>
</div>
<div class="srch_bar">
<div class="stylish-input-group">
<input type="text" class="search-bar" placeholder="Search" >
<span class="input-group-addon">
<button type="button"> <i class="fa fa-search" aria-hidden="true"></i> </button>
</span> </div>
</div>
</div>
<div class="inbox_chat">
{% set newArray = [] %}
{% for msg in msg_details %}
{% if msg.to_name not in newArray %}
<div class="chat_list active_chat" onclick=viewMessage(this)>
<div class="chat_people">
<div class="chat_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>
<div class="chat_ib">
<h5>{{msg.to_name}} <span class="chat_date">{{msg.time}}</span></h5>
</div>
</div>
</div>
{% set newArray = newArray|merge([msg.to_name]) %}
{% endif %}
{% endfor %}
</div>
</div>
<div class="mesgs">
<div class="msg_history">
<div class="incoming_msg">
<div class="incoming_msg_img">
<img src="https://ptetutorials.com/images/user-profile.png" alt="sunil">
</div>
<div class="received_msg">
<div class="received_withd_msg">
<p>{{msg.message}}</p>
<span class="time_date">{{msg.time}}</span></div>
</div>
</div>
<div class="outgoing_msg">
<div class="sent_msg">
<p></p>
<span class="time_date"></span> </div>
</div>
</div>
</div>
</div>
</div></div>
Javascript code:
<script>
function copyText(elementId){
var x = document.getElementById(elementId).textContent;
if(document.getElementById('select-text').value.length == 0)
{
document.getElementById("btn").disabled = false;
document.getElementById(elementId).style.backgroundColor = "lightblue";
document.getElementById('select-text').focus();
document.getElementById('select-text').value += x;
}
else{
document.getElementById('select-text').readOnly = true;
}
}
</script>
What my output looks like
Output
My output shows all the messages, I want to show only the particular user message. How to do so?
What my table looks like:
Table
First of all you have to fetch the data from your table using a query something like to ensure you will get one record from each from_id.
SELECT * FROM msg GROUP BY from_id;
Then you can loop in twig to create the left side elements like,
{% for distinctMsg in distinctMsgs %}
<div class="chat_list active_chat" data-userId="{{ distinctMsg.fromId }}">
<div class="chat_people">
<div class="chat_img"> <img src="https://ptetutorials.com/images/user-profile.png" alt="sunil"> </div>
<div class="chat_ib">
<h5>{{distinctMsg.to_name}} <span class="chat_date">{{distinctMsg.time}}</span></h5>
</div>
</div>
</div>
{% endfor %}
Then in your javascript:-
$(".chat_list").on("click", function(){
// have a look here https://stackoverflow.com/questions/5309926/how-can-i-get-the-data-id-attribute
var userId = $(this).data( "userId" );
// Maybe display a loading icon in the right side div
$.ajax({
type: "POST",
url: "/api/msg/user/history", // your controller url
dataType: 'json',
headers: {
// if you have any headers to set
"Authorization": "Bearer {{ token }}"
},
data:{
"userId" : userId
}
})
.done(function (response) {
// stop displaying the loading icon
// process the response and display message history in right side
})
.fail(function (xhr, status, error) {
// show proper error message
});
});
NOTE: You will have to have jQuery in your page for Ajax functions to work.

Why is Javascript not working with Django HTML?

I am trying to put some javascript code in my Django website. The javascript code is supposed to check if the buttons are being pressed and alert the user if they are. This only works for the first button, however. Because I am looping over all the buttons to display them, I think javascript is not seeing it as HTML code. Here is the javascript code.
const card = document.querySelector('.card');
card.addEventListener('click', e => {
if (e.target.classList.contains('btn')) {
alert('hi')
}
})
Here is the HTML/Django code :
{% extends "/Users/marco/Documents/codes/Python/Django/vracenmasse/templates/base_generic.html" %}
{% load static %}
{% block content %}
<center><h1>Nos Produits</h1></center>
<hr>
<div class="row" style = "border: 50px solid white;">
{% for product in products %}
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="../../../media/{{ product.product_picture.name }}" alt="{{ product.product_picture.name }}">
<div class="card-body">
<center>
<h5 class="card-title">{{ product.name }}</h5>
<p class="card-text">{{ product.product_price|floatformat:2 }}$ / unité</p>
<p class="card-text">Catégorie : {{ product.type_of_product }}</p>
{% if product.new_product == "yes" %}
<b><p class="card-text"><font size="3.5" color="Orange">Nouveaux!</font></p></b>
{% endif %}
{% if product.availability == "Out Of Stock"%}
<b><p class="card-text"><font size="1.5" color="red">En rupture de stock</font></p></b>
<hr>
<button type="button" class="btn btn-primary" disabled>Ajouter au Panier</button>
{% else %}
<p style="font-size:15;">Quantité : </p><input type="number" step="12" min="0" />
<span class="validity"></span>
<hr>
<button type="button" class="btn btn-outline-primary" id='realbutton'>Ajouter au Panier</button>
{% endif %}
<div class="alert alert-success alert-dismissible fade show" role="alert" style ="visibility:hidden;">
<center>Produit ajouté au panier!</center><button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
</center>
</div>
</div>
{% endfor %}
</div>
</div>
<script src="{% static "products/buttonalerts.js" %}"></script>
{% endblock %}
The first button is the only thing that works. We can see on line #6 there is the for loop. It iterates over all the products and it adds its own "Add To Cart" Button. The alert only works for the first button though. Thank you.
The problem is that you are creating a “div” element for each product in your list, but the querySelector() method only returns the first element with the specified class.
You need to use the querySelectorAll() method to get a list with all the elements then apply the event listener to each of them:
const cards = document.querySelectorAll('.card');
for (let i = 0; i < cards.length; i++) {
cards[i].addEventListener('click', e => {
if (e.target.classList.contains('btn')) {
alert('hi')
}
}
)
Another solution would be to query directly for the elements that contain the “btn” class and add the event listener to those:
const buttons = document.querySelectorAll(".btn");
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function() {
alert('hi');
}
)

Using Django Models to assign HTML div through jQuery

for the last few days I've been trying to create a method in jquery using django models and I have found myself to be very out of my depth and would appreciate and explanation I can get. So currently I have a django model that has the following information : name, date, location, semester. I use the first 3 pieces of information in displaying my html, however, I want to use 'semester' to see what div tag my items go into.
The semester tag can either return 'Fall' or 'Spring' values is there a way I can use this to assign the components to the correct div. So if semester is Fall then it should go into the div with the id 'fall-races' and if its spring it should go to 'spring-races'
Currently I only have a jquery working where I get all the elements and assign it to the other div.
Thank you for your help and any possible advice.
<div class="flex-column">
<div class="header shadow-lg">
<h1 class="text-center py-3">
Fall Schedule
</h1>
</div>
<div id="fall-races">
{% for race in race %}
<div class="regatta-card my-2 mx-2 ">
<h2 class="center-text py-2">{{ race.date }}</h2>
<h1 class="text-center my-2">{{ race.name }}</h1>
<h3 class="text-center mb-3">{{ race.location}}</h3>
<h6 class="text-center">Recap</h6>
</div>
{% endfor %}
</div>
<input type="button" onclick="findChildren()" value="Click it" />
<div class="header shadow-lg">
<h1 class="text-center py-3">
Spring Schedule
</h1>
</div>
<div id="spring-races">
</div>
</div>
<script>
function findChildren() {
var objChl = document.getElementById('fall-races').children;
var msg = document.getElementById('spring-races');
msg.innerHTML = '';
for (i = 0; i < objChl.length ; i++) {
msg.appendChild(objChl[i]);
}
}
</script>
Maybe you want something like this:
Html:
<!-- Some html stuff -->
<div id="fall-races">
{% for race in race %}
<div class="regatta-card my-2 mx-2 ">
<h2 class="center-text py-2">{{ race.date }}</h2>
<h1 class="text-center my-2">{{ race.name }}</h1>
<h3 class="text-center mb-3">{{ race.location}}</h3>
<h6 class="text-center">Recap</h6>
<input type="hidden" value="{{race.semester}}" />
</div>
{% endfor %}
</div>
<!-- Some html stuff -->
JS:
<script>
function findChildren() {
var parent = document.getElementById('fall-races');
var objChl = parent.children;
var msg = document.getElementById('spring-races');
msg.innerHTML = '';
for (i = 0; i < objChl.length ; i++) {
const element = objChl[i];
var value = element.getElementsByTagName("input")[0].value;
if (value==="Spring"){
msg.appendChild(element);
parent.removeChild(element);
}
}
}
</script>
This is like the simplest way to achieve that, hope it helps you.

Add Attribute to an unshift item vuejs

I have two lists , user can drag items from list 1 to list 2 and there is a button with text input so user can add his own input to the list 2 which will be automatically updated in my MYSQL database using axios.
This is AddItem script
addItembh(){
var input = document.getElementById('itemFormbh');
if(input.value !== ''){
// this line makes a new article with input value but no attribute :(
this.tasksNotCompletedNew.unshift({
behv_skilldesc:input.value
});
axios.post('../joborder/addAttrib', {
behv_skilldesc: input.value,
type:'behvnew',
joborder_id: this.joborder_id ,
alljobs_id: this.alljobs_id
}).then((response) => {
console.log(response.data);
}).catch((error) => {
console.log(error);
});
input.value='';
}
},
To be clear on the question : I need to assign an attribute to my new article thats getting created so I can find the text of that attrib later on deleteItem method
UPDATE :
<template>
<div class="row">
<div class="col-md-4 col-md-offset-2">
<section class="list">
<header>Drag or Add Row Here</header>
<draggable class="drag-area" :list="tasksNotCompletedNew" :options="{animation:200, group:'status',handle:'disabled'}" :element="'article'" #add="onAdd($event, false)" #change="update">
<article class="card" v-for="(task, index) in tasksNotCompletedNew" :key="task.prof_id" :data-id="task.prof_id" #change="onChange">
<span >
{{ task.prof_skilldesc }}
</span>
<span v-if="task.prof_skilldesc !== 'Drag Here'">
<button class="pull-left" #click="deleteItem(task.prof_id) + spliceit(index)" ><i class="fa fa-times inline"></i></button>
</span>
</article>
<article class="card" v-if="tasksNotCompletedNew == ''">
<span>
Drag Here
</span>
</article>
</draggable>
<div>
<input id='itemForm' />
<button v-on:click='addItem' class="btn btn-theme btn-success" style='margin-top:5px;' >Add a row </button>
</div>
</section>
</div>
<div class="col-md-4">
<section class="list">
<header>List of Skills ( Hold left click )</header>
<draggable class="drag-area" :list="tasksCompletedNew" :options="{animation:200, group:'status'}" :element="'article'" #add="onAdd($event, true)" #change="update">
<article class="card"
v-for="(task, index) in visibleskills"
:key="task.prof_id" :data-id="task.prof_id"
>
{{ task.prof_skilldesc }}
<div v-if="index == 4" style="display:none" >{{index2 = onChange(index)}}</div>
</article>
<pagination
v-bind:tasksCompletedNew ="tasksCompletedNew"
v-on:page:update ="updatePage"
v-bind:currentPage ="currentPage"
v-bind:pageSize="pageSize">
</pagination>
</draggable>
</section>
</div>
</div>
</template>
So on Add a row our method will be called .
Thanks for any help

Categories