How to loop over an html with javascript? - javascript

I have an HTML code which looks like this:-
<article class="media content-section">
<div class="media-body">
<h2><a class="article-title" href="{% url 'post-detail' post.slug %}">{{ post.title }}</a></h2>
<div class="article-metadata">
<a class="mr-2" href="{% url 'blog-profile' name=post.author %}">{{ post.author }}</a>
<div class="float-right">
<small class="text-muted">Category</small>
<small class="text-muted">{{ post.date_posted }}</small>
</div>
<div style="float:right;">
<img style="height:19px; width:18px;" src="{% static "blog/viewicon.png" %}">
<p style="float: right; display: inline !important;" id="ViewCount">
.....
</p>
</img>
</div>
</div>
<p class="article-content">{{ post.content|truncatechars:200|safe }}</p>
</div>
</article>
I am trying to add the values of viewcount asynchronously to all the blogs field. With this js/ajax code:-
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<script>
$(document).ready(function(){
setInterval(function()
{
$.ajax({
type:'GET',
url: "{% url 'getBlogs' %}",
success: function(response){
$("#ViewCount").empty();
for (var key in response.blogs)
{
console.log(response.blogs);
var temp = response.blogs[key].view_count
$("#ViewCount").append(temp);
}
},
error:function(response){
alert("No Data Found");
}
});
},1000);
});
</script>
I have many such blogs, But the values seem to be displayed all at once at only a single field which looks like this:-
But I am trying to display the viewcount of each blogs to its dedicated position. Is there I anyway I can achive it.

One of the easiest way is to use HTML markup to differentiate different viewCount using data attributes.
blogs={
"1":{
"view_count":1
},
"2": {
"view_count":15
}
}
for (var key in blogs)
{
var temp = blogs[key].view_count
$(`[data-key=${key}]`).append(`${temp} views`);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p data-key="1" id="ViewCount">Key:1 :- </p>
<p data-key="2" id="ViewCount">Key:2 :- </p>

Related

Issue on getting id from Selected HTML elements from Ajax GET response with jQuery

I am using ajax to display product data and then delete on click a specific on using the product id but am not able to get the product id as it is showing undefine can you guys suggest something.
In this code first I am getting the product details for the cart dropdown menu and then displaying it in list format with delete button through the first ajax and then on clicking delete should delete the element in the second ajax using the elements product id which I have saved inside data-r but on console, it showing undefined can anyone tell me what is the issue. As I know that the elements are created dynamically but I am not getting a solution
function TopCartVal() {
// Used Route inside the ajax
var url = "{{ route('pdt.details', ':id') }}";
var yui = "{{ route('delete_fr.cart', ':id') }}";
// Ajax Structure
$.getJSON( "{{ route('my.cart','json') }}", function( data ) {
console.log(data);
var Cart = $('#cart_dp_sec_pdt_desc');
// Loop for data
$.each(data, function(key , value) {
console.log(value);
url = url.replace(':id', value.product_id);
yui = yui.replace(':id', value.product_id);
Cart.append(`
<div class="row">
<div class="col-xs-4">
<div class="image">
<a href="`+url+`">
<img src="{{ asset('')}}`+value.image+`" alt=""/>
</a>
</div>
</div>
<div class="col-xs-7">
<h3 class="name">
`+value.product_name+`
</h3>
<div class="price">`+value.currency+value.product_price+`</div>
</div>
<div class="col-xs-1 action">
<a href="#"
data-r"`+value.id+`"
class="cart_dp_btn_ctn_delete">
<i class="fa fa-trash"></i>
</a>
</div>
</div>
`);
});
});
}
// delete part
$(document).on('click', '.cart_dp_btn_ctn_delete', function(e){
e.preventDefault();
var id = $(this).attr('data-r'); // id of to be deleted element
var yui = "{{ route('delete_fr.cart', ':id') }}";
yui = yui.replace(':id', id);
console.log(yui);
console.log(id); // it is showing undefined`enter code here`
// $.getJSON( yui, function(data){
// TopCartVal();
// });
});
You are missing an = here:
data-r"`+value.product_id+`"
But using template literals correctly will make it easier to see
`<div class="row">
<div class="col-xs-4">
<div class="image">
<a href="${url">
<img src="{{ asset('')}}${value.image}" alt=""/>
</a>
</div>
</div>
<div class="col-xs-7">
<h3 class="name">
${value.product_name}
</h3>
<div class="price">${value.currency+value.product_price}</div>
</div>
<div class="col-xs-1 action">
<a href="#" data-r="${value.product_id}" class="cart_dp_btn_ctn_delete">
<i class="fa fa-trash"></i>
</a>
</div>
</div>`

can't refresh the data in a DIV python Django nor the page after a jquery

Let me start by saying I have 2 variables in an HTML template(messages and users) and I have multiple buttons that when one of them is clicked it calls a jquery code that sends a post request to a Django server and it returns an update to a variable(messages)
however, it's not updating the loop, I also tried to return a new HTML page that contains the new variable updated but the jquery is not updating the whole page with the new HTML
if I can update the variable alone it would be better and if I can't do that how can I make jquery use the new HTML page
the python code i used to return the update to the varialbe messages:
if request.method == 'POST':
send=Message.objects.filter(from_id=request.POST.get('userId'),to_id=2)
rec=Message.objects.filter(from_id=2,to_id=request.POST.get('userId'))
messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
print(messages)
return HttpResponse(list(messages))
and the code i used to return new HTML template:
m = Message.objects.filter(to_id=2).order_by('-id')
users = {}
for i in m:
if users.get(i.from_id.username) == None:
users[i.from_id.username] = User.objects.get(id=i.from_id.id)
users = list(users.values())
send=Message.objects.filter(from_id=users[0].id,to_id=2)
rec=Message.objects.filter(from_id=2,to_id=users[0].id)
messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
if request.method == 'POST':
send=Message.objects.filter(from_id=request.POST.get('userId'),to_id=2)
rec=Message.objects.filter(from_id=2,to_id=request.POST.get('userId'))
messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
print(messages)
return render(request,'psych.html',{"users":users, "messages":list(messages)})
return render(request,'psych.html',{"users":users, "messages":list(messages)})
the HTML code and jquery code that uses the variable and try to update it
function newUser(id){
$.ajax({
type: 'POST',
url:'/psych.html/',
data:{
userId:id,
},
success: function(data){
console.log(data);// the data returnd are correct and as needed
//but i cant make it update the messages
$('#messageDiv').load(document.URL + ' #messageDiv');
}
})
}
{% for i in users %}
<li class="">
<button type="button" class="btn" onClick="newUser({{i.id}})">
<div class="d-flex bd-highlight">
<div class="img_cont">
<!-- here was an image ----------------------------------------------->
</div>
<div class="user_info">
<span>{{i.id}}</span>
</div>
</div>
</button>
</li>
{% endfor %}
<!-- The varialbe that i'm trying to update is called messages bottom -->
{% for o in messages %}
{% if o.to_id.id != 2 %}
<div class="d-flex justify-content-start mb-4">
<div class="img_cont_msg">
<!-- here was an image-->
</div>
<div class="msg_cotainer">
{{o.message}}
<!-- <span class="msg_time">{{o.time}}</span> -->
</div>
</div>
{% else %}
<div class="d-flex justify-content-end mb-4">
<div class="msg_cotainer_send">
{{o.message}}
<!-- <span class="msg_time_send">{{o.time}}</span> -->
</div>
<div class="img_cont_msg">
<!-- here was an image-->
</div>
</div>
{% endif %}
{% endfor %}
if it helps i did it before and updated the messages from jquery but i used form and there was only 1 variable i will add the code to that too
$(document).on('submit','#submitMessage', function (e){
e.preventDefault();
$.ajax({
type: 'POST',
url:'/psych.html/',
data:{
message:$('#messageHolder').val(),
csrfmiddlewaretoken: $('input[message=csrfmiddlewaretoken]').val(),
},
success: function(data){
// it work like charm here
$('#messageDiv').load(document.URL + ' #messageDiv');
}
})
})
{% for o in messages %}
{% if o.to_id.id == 2 %}
<div class="d-flex justify-content-start mb-4">
<div class="img_cont_msg">
<!-- here was an image-->
</div>
<div class="msg_cotainer">
{{o.message}}
<!-- <span class="msg_time">{{o.time}}</span> -->
</div>
</div>
{% else %}
<div class="d-flex justify-content-end mb-4">
<div class="msg_cotainer_send">
{{o.message}}
<!-- <span class="msg_time_send">{{o.time}}</span> -->
</div>
<div class="img_cont_msg">
<!-- here was an image-->
</div>
</div>
{% endif %}
{% endfor %}
<form id="submitMessage" >
{% csrf_token %}
<div class="card-footer">
<div class="input-group">
<div class="input-group-append"></div>
<input name="message" class="form-control type_msg" placeholder="Type your message..." id="messageHolder">
<div class="input-group-append">
<button type="submit" class="btn">
<span class="input-group-text send_btn" ><i class="fas fa-location-arrow"></i></span>
</button>
</div>
</div>
</div>
</form>
Try this
$("#messageDiv").load(location.href+" #messageDiv>*");
i figured the problem and it was because i didn't know that
$("#messageDiv").load(location.href+" #messageDiv>*");
would make a GET request so all I did was adding the necessary data to the URL and then change the URL too(so if the client refreshed the page it would stay in the same spot) without refreshing the page and then do the command app there
if it could help anyone please look at the code below:
function newUser(id){
var url = document.URL;
url = url.split('/');
url[url.length-2] = id;
url = url.join('/');
window.history.pushState("object or string", "my website name", url);
$('#messageDiv').load(url + ' #messageDiv');
}
sadly i don't know how to do post requst then load the page please if you know comment down bellow so someone else might get help from it

Passing different URL parameters to AJAX function in Django

How to pass the different URL names to the javascript function. Here are my HTML and Javascript code.
{% for profile, g_name in group_list %}
<li class="contact">
<div class="wrap">
<img src="{{profile}}" alt="No image" />
<div class="meta">
<input type="hidden" id="myGroup" name="myGroup" value="{{g_name}}">
<button onclick="GetMessages()">
<p class="name">{{g_name}}</p>
</button>
</div>
</div>
</li>
{% endfor %}
<script>
function GetMessages() {
var myGroup = document.getElementById('myGroup').value;
$('.ajaxProgress').show();
$.ajax({
type: "GET",
url: "/getmsgs/"+myGroup,
success: function(response){
$("#display").empty();
...
},
error: function(response){
alert("No Data Found");
}
});
}
</script>
and this is my URL
path('getmsgs/<str:word>/', views.groupmsgs_ajax, name='groupmsgs_ajax'),
when I try the above method I am getting the first 'myGroup' id value. it is passing the first group name by default.
I am not able to call other group names.
Thank you for any help
That is because all input elements have the same id myGroup so document.getElementById('myGroup').value get always the first element value.
The following code changes should solve the issue given that g_id exists and is a string
{% for profile, g_name, g_id in group_list %}
<li class="contact">
<div class="wrap">
<img src="{{profile}}" alt="No image" />
<div class="meta">
<input type="hidden" id="{{g_id}}" name="{{g_id}}" value="{{g_name}}">
<button onclick="GetMessages({{g_id}})">
<p class="name">{{g_name}}</p>
</button>
</div>
</div>
</li>
{% endfor %}
<script>
function GetMessages(id) {
var myGroup = document.getElementById(id).value;
$('.ajaxProgress').show();
$.ajax({
type: "GET",
url: "/getmsgs/"+myGroup,
success: function(response){
$("#display").empty();
...
},
error: function(response){
alert("No Data Found");
}
});
}
</script>
Or pass the name directly to GetMessages function
{% for profile, g_name, g_id in group_list %}
<li class="contact">
<div class="wrap">
<img src="{{profile}}" alt="No image" />
<div class="meta">
<button onclick="GetMessages({{g_name}})">
<p class="name">{{g_name}}</p>
</button>
</div>
</div>
</li>
{% endfor %}
<script>
function GetMessages(myGroup) {
$('.ajaxProgress').show();
$.ajax({
type: "GET",
url: "/getmsgs/"+myGroup,
success: function(response){
$("#display").empty();
...
},
error: function(response){
alert("No Data Found");
}
});
}
</script>

How to identify multiple forms in one template?

I'm trying to implement a follower/following system in Django. In the template, all follow requests have a user and they all have user id's that can be displayed. The template is a profile page that contains several follow requests made by other users. I have created a separate form for each accept/decline and I want to uniquely identify each form so that I can submit that one and remove it subsequently.
<div class="col s12 l6 trending-panel container">
<h4>
Requests
</h4>
<div class="divider"></div>
{% for bond_request in bond_requests %}
{% if bond_request.accepted == False %}
<div>
<div class="row bond-request-row" id="{{bond_request.by_user.id}}">
<div class="col s6">
<a href="{% url 'accounts:profile' bond_request.by_user.username %}">
<div class="col s8">
<img class="profile-image-request" src="https://m.media-amazon.com/images/M/MV5BNjUxNDcwMTg4Ml5BMl5BanBnXkFtZTcwMjU4NDYyOA##._V1_.jpg" alt="">
</div>
<div class="col s4">
<h6 id="follower-username">
#{{bond_request.by_user}}
</h6>
</div>
</a>
</div>
<div class=" col s12 center accept-decline-margin">
<div class="col s12 l6">
<form action="accounts:accept_bond_request" method="POST" id="bond-request-accept-form">
<!-- <a href="#" id="bond-request-accept" class="green-text white btn">
<div>
<ion-icon name="add"></ion-icon>
<span>Accept</span>
</div>
</a> -->
<button id="bond-request-accept" class="green-text white btn" type="submit">Accept</button>
</form>
</div>
<div class="col s12 l6">
<a href="" class="grey-text white btn">
<div class="">
<ion-icon name="remove"></ion-icon>
<span>Ignore</span>
</div>
</a>
</div>
</div>
</div>
<!-- HERE -->
</div>
{% else %}
{% endif %}
<div class="divider">
</div>
{% endfor %}
</div>
$("#bond-request-accept-form").on('submit',function(){
// Cleans the username
// var each_bond_request = $();
var raw_follower_username = $("#follower-username").text().trim();
var follower_username = raw_follower_username.replace("#","");
console.log("Follower username: ",follower_username);
$.ajax({
type: "POST",
url: "/accounts/user/" + follower_username + "/accept_request",
data:{
"follower_username" : follower_username,
},
success: function(data){
console.log(data);
M.toast({html: follower_username + ' started following you',classes: 'green'}, );
},
error: function(data){
console.log("All error data: ",data);
M.toast({html: 'Failure',classes: 'red'}, );
},
});
});
You should create a standalone function to handle submit. And reference this function in each form you created.
function SubmitHandler (e) {
// Cleans the username
// var each_bond_request = $();
var raw_follower_username = $(e).find("#follower-username").text().trim();
var follower_username = raw_follower_username.replace("#","");
console.log("Follower username: ",follower_username);
$.ajax({
type: "POST",
url: "/accounts/user/" + follower_username + "/accept_request",
data:{
"follower_username" : follower_username,
},
success: function(data){
console.log(data);
M.toast({html: follower_username + ' started following you',classes: 'green'}, );
},
error: function(data){
console.log("All error data: ",data);
M.toast({html: 'Failure',classes: 'red'}, );
},
});
return false;
}
Then in your template:
...
<form id="bond-request-accept-form" onsubmit="SubmitHandler(this)">
...
Note the #follower-username should be nested within the form tag for jQuery to find the correct one.
First, I just want to say that I may be understanding your question wrong. If so, feel free to correct me.
If I am understanding this right, you have multiple copies of essentially the same form with slight variations depending on the user that is sending the request. Since IDs are meant to be unique and can cause issues in JavaScript if there are more than one instance of them, I would change the bond-request-accept-form to a class rather than an ID, and do something like this in JQuery:
$(".bond-request-accept-form").toArray().forEach(function(elem){
$(elem).on('submit', function(){
// Logic to perform when the form is submitted
});
});
Put different URLs in the action for the two forms. Then you'll have two different view functions to deal with the two different forms.

Laravel, Javascript file is not found

#extends('template')
<script type="text/javascript" src="js/Chart.js"></script>
#section('title')
{{ $student->name }} - Student Detail
#endsection
#section('main')
<div class="container-fluid">
<div class="row">
<div class="col-md-8 col-xs-12" >
<header>
<h3><strong>{{ $student->name }}</strong> <img src="../img/kattis.png" alt="Kattis" width="20" height="15"> in CS3233 S1 AY 2020/21</h3>
<p><strong>SPE</strong>(ed) component: <strong>{{ $student->mc }} + {{ $student->tc }} = {{ $student->mc+$student->tc }}</strong><br>
<strong>DIL</strong>(igence) component: <strong>{{ $student->hw }} + {{ $student->bs }} + {{ $student->ks }} + {{ $student->ac }} = {{ $student->hw+$student->bs+$student->ks+$student->ac }}</strong><br>
<strong>Sum = SPE + DIL = {{ $student->mc+$student->tc }} + {{ $student->hw+$student->bs+$student->ks+$student->ac }} = {{ $student->mc+$student->tc+$student->hw+$student->bs+$student->ks+$student->ac }}</strong></p>
</header>
</div>
<div class="col-md-4 hidden-xs hidden-sm">
<img class="pull-right" id="photo" src="#if($student->avatar) {{Storage::url($student->avatar)}} #else ../img/locked.png #endif" alt="Photo of {{ $student->name }}" width="100" height="100">
<img class="pull-right" id="flag" src="../flags/4x3/{{strtolower($student->country)}}.svg" alt="{{$student->country}} Flag" width="100">
</div>
</div>
</div>
<div><canvas id="myChart" width="400" height="400"></canvas></div>
#endsection
#section('footer')
<script>
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'radar',
labels: ["MC", "TC", "HW", "Bs", "KS", "Ac"],
data: [$student->mc,$student->tc,$student->hw,$student->bs,$student->ks,$student->ac]
});
</script>
#endsection
In this file, called detail.blade.php, I include Chart.js. This file is located in public/js. detail.blade.php is in the directory with all the other views. In index.blade.php, I successfully referenced javascript files in the exact same way, for example
#section('footer')
<script type="text/javascript" src="js/highlight.js"></script>
#endsection
. But in detail.blade.php, it doesn't work. I get the error: Failed to load resource: the server responded with a status of 404 (Not Found) regarding Chart.js.
What is wrong?
<script type="text/javascript" src="/js/Chart.js"></script>
This line does not form part of any section so it's not included. You need to include it in some section (e.g. main or footer)
Try
<script src="{{ URL::asset('/js/Chart.js') }}"></script>
I think your js folder is in public if it's taht you gonna have acess to your script with this link.

Categories

Resources