How can i assing a different class after a success ajax response - javascript

I'm working in a net core app, i made a HttpPost function to know if an user marked like.
This is the function code:
var likesCancion = (from likesCanc in _context.table
where likesCanc.SongId == idCancion && likesCanc.UserId == idUser
select likesCanc.Likes).FirstOrDefault();
if (likesCancion == 1)
{
return 1;
}
else
{
return 0;
}
I have this:
<div class="col-3 col-sm-2 col-md-2">
<i class="far fa-heart" id="heart" data-idAudio = #song.Id>
<span class="badge" >#song.Likes</span>
</i>
</div>
This is the <div> that I want to change at the start of the page if the user liked it or not.
The #song.Likes its data filled from the database.
I made an ajax request inside a for loop and get the respond of my HttpPost function:
const iconosCorazon = document.querySelectorAll('#heart');
setTimeout(function () {
let idUser = $('#inputidUsuario').val();
function makeRequest(i)
{
$.ajax({
type: "POST",
url: "checkHeart",
data: { idCancion: i, idUser: idUser },
dataType: "text",
success: function (msg) {
console.log(msg);
**if (msg == 1) {
$('.fa-heart').removeClass("far text-dark");
$('.fa-heart').addClass("fa text-danger");
}
else
{
$('.fa-heart').removeClass("fa text-danger");
$('.fa-heart').addClass("far fa-heart");
}**
},
error: function (req, status, error) {
console.log(msg);
}
});
}
for (var i=0;i<iconosCorazon.length;i++) {
let idCancion = iconosCorazon[i].getAttribute('data-idAudio');
makeRequest(idCancion);
}
I want to assign the css class to the correct element coming from the function result.
The issue here its that ajax execute all the elements at once and change the classes only with the last lopped element. So the question is how can i assign the rigth class to each div element. eg: If result == 1 paint red, if result == 0 paint other color.
Sorry for my bad english
Im trying to make this code works

You should use $(".fa-heart:eq(index)") to locate the each element with same class name. Sample code below:
$(".div_test:eq(0)").css("border","2px solid yellow");
Test Result:

Related

Refresh attribute value after html() with ajax

I am making start/pause button that works like this:
var btns = document.querySelectorAll(".repairToggle");
for (i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", manageOrderStatus);
}
function manageOrderStatus() {
var func = this.getAttribute("func");
var btn = this;
var endpoint = "{% url 'mtn:ajax_repair_toggle' %}";
$.ajax({
url: endpoint,
type: "GET",
data: {
'func': func,
},
success: function (data) {
$(btn).html(data);
}
});
}
I have start and stop buttons stored in separate html files:
work_order_start.html:
<div type="button" class="repairToggle" func="start">
<svg>...</svg>
</div>
work_order_pause.html:
<div type="button" class="repairToggle" func="stop">
<svg>...</svg>
</div>
In view i render one of the buttons based on the value of func attribute:
def repair_toggle(request):
...
func = request.GET.get('func')
if func == 'stop':
return render(request, 'mtn/work_order_start.html')
else:
return render(request, 'mtn/work_order_pause.html')
The problem is it only works once. After the first click it keeps executing ajax call but it sends the same old func value in request. How do i fix that?
UPDATE:
I figured out the problem. $(btn).html(data); only replaces the svg element. So the func stays the same. If i do this instead:
<div type="button" class="repairToggle">
<svg id='funcButton' func="stop">
</div>
How do i get func out of svg. I tried this.getElementById('funcButton').getAttribute("func"); but it doesn't work.
You are inserting the button inside the original button.
Change work_order_pause.html and work_order_start.html to only contain the svg and add in success function :
if(func == "start"){
this.setAttribute("func", "stop")
}
else{
this.setAttribute("func", "start")
}

How to get ID value using map()

I've page that contain the list button and search button.
index.php :
<li class="page-item" id="'.$i.','.$record_per_page.'"><a class="page-link" href="javascript:void(0);" >'.$i.'</a></li>
<input class="form-control" type="text" placeholder="insert your keyword ..." aria-label="Search" id="budget_keyword" name="<?=$record_per_page;?>">
script.js :
$(document).on('click','#table-content .page-item',function () {
var mode = this.id.split(',');
var page = mode[0];
var p = mode[1];
var keyword = $('#budget_keyword').map(function() {
return this.id.value;
});
$.ajax({
url: "paging.php",
method: "POST",
data: { page: page, p: p, keyword: keyword },
success: function (data) {
$('#table-content').html(data);
}
})
});
My Goals are :
When user click the li button, then it will pass 2 variables which containing values from #page-item and #budget_keyword id
I already got the value of #page-item from my script above, but for the #budget_keyword, it seems returning an object which i cannot understand below :
Object { length: 0, prevObject: Object(1) }
I just need the value from user input text inside searchbox (#budget_keyword)
Can someone give me an idea ?
sorry for my bad english
Seems like multiple inputs with same id="budget_keyword" exist in your HTML.Due to that keyword is not coming properly (or in other words to say map() not working).
You can use .next() to get desired keyword. Check below code:
$(document).on('click','#table-content .page-item',function () {
var mode = this.id.split(',');
var page = mode[0];
var p = mode[1];
var keyword = $(this).next('.form-control').val();
$.ajax({
url: "paging.php",
method: "POST",
data: { page: page, p: p, keyword: keyword },
success: function (data) {
$('#table-content').html(data);
}
})
});
Note:- if only one id="budget_keyword" exist in whole document,then directly do:
var keyword = $('#budget_keyword').val();

change an element's text with variable id

I am designing a social network that has timeline and there is like button. I use AJAX to apply the like button on the server side. the problem is that I want to change the number of like for each post immediately after they have liked successfully. Because my elements are generated by for-each, I want to change the number of like for the exact element, I really have a problem with it.I am using thymeleaf.
I am looking for an idea that how to do this.
here is my html code:
<div class="col-sm-4">
<div class="row" >
<div class="col-sm-12">
<img th:if="${tweet.isFavorited()}" src="../static/images/like.png" th:src="#{/images/like.png}" th:class="like-img" th:id="${tweet.getId()}" width="35" height="35"/>
<img th:if="${!tweet.isFavorited()}" src="../static/images/dislike.png" th:src="#{/images/dislike.png}" th:class="like-img" th:id="${tweet.getId()}" width="35" height="35"/>
</div>
</div>
<div class="row">
<div class="col-sm-12" >
<h6 th:if="${tweet.isRetweet()}" th:class="like-count" th:id="${tweet.getId()}" th:text="${tweet.getRetweetedStatus().getFavoriteCount()}"></h6>
<h6 th:if="${!tweet.isRetweet()}" th:class="like-count" th:id="${tweet.getId()}" th:text="${tweet.getFavoriteCount()}"></h6>
</div>
</div>
and it is my script code:
$(function () {
$(".like-img").click(function () {
event.preventDefault();
var $post = $(this);
var toSend = {
"tweetId": this.getAttribute("id")
}
$.ajax({
type : "POST",
contentType: "application/json; charset=utf-8",
url : "like",
data : JSON.stringify(toSend),
dataType : 'json'
}).done(function (data) {
if(data.status == "success") {
if ($($post).attr("src") == "/images/dislike.png") {
$($post).attr('src','/images/like.png');
}
else {
$($post).attr('src','/images/dislike.png');
}
return false;
}
});
});
})
Okay so to make this work you will need to assign unique ids to the like-count elements, something like so:
<h6 th:if="${tweet.isRetweet()}" th:class="like-count" th:id="${tweet.getId()}_like_count" th:text="${tweet.getRetweetedStatus().getFavoriteCount()}"></h6>
Then you can retrieve the current count, increment it, and set the text of the count element. Something like so:
var currentCount = parseInt($('#'+toSend.tweetId+'_like_count').innerHtml)
var newCount = currentCount++;
$('#'+toSend.tweetId+'_like_count').text(newCount);

Images in JSON AngularJS

I'm new to AngularJS, so sometimes when I do some mistake that is obvious, I still can't figure out what is going wrong with my code. So saying, here is my doubt:
HTML code:
<body ng-controller = "Ctrl">
<script id="Page6.html" type="text/ng-template">
<div class="list card" style="background-color: beige">
<div class="item item-icon-left">
<i class="icon ion-home"></i>
<input type="text" placeholder = "Enter display name" ng-model="user.nam">
</div>
<a ng-click = "saveedit(user)"<button class="button button-clear">SAVE DETAILS</button></a>
</div>
</script>
</body>
CONTROLLER.JS
.controller('Ctrl',function($scope,$rootScope,ContactService){
$rootScope.saveedit=function(user) {
ContactService.save({names: user.nam, image:"images.jpg"},ContactService.getid("Donkey"));
}
});
THIS IS THE SERVICE:
.service('ContactService', function () {
var items = [
{ id: 1, names: 'Dolphin', image: 'dolphin.jpg',}, { id: 2, names: 'Donkey', image: 'donkey.jpg'}, { id: 3, empid: 'FG2043', image: 'penguin.jpg'}];
var im = [{image: ''}];
var ctr=0;
var uid=3;
this.save = function (contact,id) {
ctr=0;
for (i=0;i<items.length;i++) {
if(items[i].id == id)
{
im[0].image= items[i].image;
ctr=100;
break;
}
}
uid = (uid+1);
contact.id = uid;
items.push(contact);
if (ctr==100 ) {
alert("in save putting the image");
items[contact.id].image = im[0].image; //doubt
alert("finished putting image");
}
}
//simply search items list for given id
//and returns the object if found
this.getid = function (name) {
for (i=0;i<items.length;i++) {
if (items[i].names == name) {
return (i+1);
}
}
}
//simply returns the items list
this.list = function () {
return items;
}
});
The problem I am facing is this: Everything works, except one thing. In ContactService, push() function, the line I have commented as //doubt is not getting executed.
The alert before it "in save putting the image" runs, but the alert "finished putting image" doesn't. What is the mistake there??
The problem here is that you're using the id's, which start at 1, to navigate in an array whose indexes start at 0.
To access the most recently pushed element, you should rather do :
items[contact.id - 1].image = im[0].image;
But you actually don't need to access the array : items[contact.id - 1] will return the object that you just pushed, and which is already referenced by variable contact, so you could just do :
contact.image = im[0].image;

JQuery Clear <ul> Two Menus Away

I have three menus: College, Department and Program. When a College is clicked, the list of Departments belonging to that College is shown. When a Department is clicked, the list of Programs belonging to that Department is shown.
My problem is that when I click a new College, the Departments re-populate in the second list but I can't get the Programs in the third column to clear out. I've tried a bunch of different things with .nextAll() and .siblings() and whatnot, but nothing has worked yet.
Here's the HTML:
<div class="row">
<div class="col-xs-4">
<h4>Colleges</h4>
<ul class="colleges-menu">
<?php CommonFunctions::getCollege('list'); ?>
</ul>
</div>
<div class="col-xs-4">
<h4>Departments</h4>
<ul id="departments" class="colleges-menu">
</ul>
</div>
<div class="col-xs-4">
<h4>Programs</h4>
<ul id="programs" class="colleges-menu">
</ul>
</div>
And the JQuery:
function ajaxLists(){
var entity = '.' + $(this).attr('class');
var nextEntity;
var value;
var data;
switch(entity){
case '.college':
nextEntity = '#departments';
value = $(this).val();
data = {list_college: value};
break;
case '.departments':
nextEntity = '#programs';
value = $(this).val();
data = {list_departments: value};
break;
default:
break;
}
//this should ONLY run if we are selecting a college or department
if(entity == '.college' || entity == '.departments'){
$("body").css("cursor", "progress");
$.ajax({
url: "sort_college.php",
type: "post",
data: data,
success: function(info){
$(nextEntity).html('');
$(nextEntity).append(info);
console.log(info);
},
error: function(){
alert("there's an error with AJAX");
}
}).done(function(){
$("body").css("cursor", "default");
}); //end ajax
}
}
As you mentioned that your code should fit further elements added in the future, you need to make sure you don't rely on hardcoded IDs, classes, etc.
This should solve your problem, or at least give you a good ground to go from there:
$(function () {
$('.col-xs-4 .colleges-menu').on('click', 'li', function () {
// Go up in this element parents until you reach the div.
// Then you go to its next sibling and grab the ul.
var nextEntity = $(this).parents('.col-xs-4').next().find('ul');
// Self explanatory.
var value = $(this).val();
// Variable to store the data.
var data = {};
// If there's a nextEntity element, it means you didn't reach the last
// set of options.
if (nextEntity) {
// Creating a property for data that is based in a variable.
data["list_" + nextEntity.attr("id")] = value;
$("body").css("cursor", "progress");
$.ajax({
url: "sort_college.php",
type: "post",
data: data,
success: function (info) {
nextEntity.html('');
nextEntity.append(info);
console.log(info);
},
error: function () {
alert("there's an error with AJAX");
}
}).done(function () {
$("body").css("cursor", "default");
});
}
});
});

Categories