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);
Related
I have a laravel application which shows some stats to my users.
On my front end blade, I'm displaying few widgets where each widget contain's a specific stat.
Following widget is to show number of total orders.
<div class="row mt-3" id="shopify_row1">
<div class="col-md-2" id="shopify_widget1">
<div class="jumbotron bg-dark text-white">
<img class="img-fluid pull-left" src="https://cdn0.iconfinder.com/data/icons/social-media-2092/100/social-35-512.png" width="32" height="32">
<h6 class="text-secondary mt-2 px-4">Shopify</h6>
<hr class="border border-white">
<h5 class="text-white">Total Orders</h5>
<span class="tot_o" id="tot_o">{{ $tot_o }}</span>
</div>
</div>
</div>
Like this widget, I have 5 more widgets to display 5 different stats.
In every widget initially I'm displaying stats for the current date, eg: if the total number of orders for the day is 0, it shows 0...
Then, I have added a a date picker as I can get the data only for a particular day.
<td>
<input id="date" class="date form-control" type="date">
</td>
And following is my jQuery...
<script>
$(document).on('change', '#date', function (e) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'GET',
url : '/shopify_data',
data : {selected_date : $('#date').val()},
success:function(data){
$('#tot_o').empty();
$('#tot_sum').empty();
$('#avg_ov').empty();
$('#cus').empty();
$('#item_sum').empty();
$('#orders').empty();
var total_orders = data.tot_o;
var total_sales = data.sum;
var currency = data.crr;
var avg_ov = data.avg_ov;
var cus = data.cus;
var item_sum = data.item_sum;
var orders = data.orders;
$('#tot_o').append(total_orders);
$('#tot_sum').append(total_sales);
$('#avg_ov').append(avg_ov);
$('#cus').append(cus);
$('#item_sum').append(item_sum);
$('#orders').append(orders);
//console.log(total_orders);
},
timeout:10000
});
});
</script>
This entire code works perfectly, but now I need to add a loading gif till the updated results get displayed on the date change.
What changes should I do to above jQuery in order to add the loading gif...
There are multiple ways how you can create the loading gif. One would be to create an element in your blade template that is hidden or shown by using a class.
HTML:
<div class="loader hidden"></div>
CSS:
.hidden {
display: none;
}
jQuery:
const loader = document.querySelector('.loader');
$(document).on('change', '#date', function (e) {
loader.classList.remove('hidden');
// your other code..
}
And inside your success function you add the hidden class which should hide the loading element again.
success: function(data){
loader.classList.add('hidden');
// your existing code..
},
However, I would instead add a complete block, which ensures that on failure as on success the loading element is hidden.
$.ajax({
// your existing code..
complete: () => {
loader.classList.add('hidden');
}
}
You can place loading gif in any place of DOM with style="display: none".
Next, in your script before ajax you can show gif and after success or fail result hide it again:
<script>
let gif = $('.loading-gif'); // Your loading gif
$(document).on('change', '#date', function (e) {
gif.show(); // Show loading gif
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type: 'GET',
url : '/shopify_data',
data : {selected_date : $('#date').val()},
success:function(data){
gif.hide(); // Hide gif
$('#tot_o').empty();
$('#tot_sum').empty();
$('#avg_ov').empty();
$('#cus').empty();
$('#item_sum').empty();
$('#orders').empty();
var total_orders = data.tot_o;
var total_sales = data.sum;
var currency = data.crr;
var avg_ov = data.avg_ov;
var cus = data.cus;
var item_sum = data.item_sum;
var orders = data.orders;
$('#tot_o').append(total_orders);
$('#tot_sum').append(total_sales);
$('#avg_ov').append(avg_ov);
$('#cus').append(cus);
$('#item_sum').append(item_sum);
$('#orders').append(orders);
//console.log(total_orders);
},
timeout:10000
});
});
</script>
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:
This question already has answers here:
jQuery ID selector works only for the first element
(7 answers)
Closed 6 years ago.
I've implemented a program something like a shopping cart where you would add products to the cart. I'm using ajax make the page dynamic so multiple products can be added to the cart without a page reload. For some reason, the first product in the list can be added correctly while the rest of products alway redirects to the controller url when it isn't supposed to.
View Code
<section class="grid grid--loading" id="portfoliolist">
<!-- Loader -->
<img class="grid__loader" src="~/Images/grid.svg" width="60" alt="Loader image" />
<!-- Grid sizer for a fluid Isotope (Masonry) layout -->
<div class="grid__sizer"></div>
<!-- Grid items -->
#foreach (var item in Model.ProductsList)
{
var pricetag = "pricegroup3";
if (item.Price <= 300)
{
pricetag = "pricegroup1";
}
else if (item.Price > 300 && item.Price <= 500)
{
pricetag = "pricegroup2";
}
<div class="grid__item #item.Type #pricetag">
<div class="slider">
#foreach (var image in Model.ProductImagesList.Where(m=>m.ProductID == item.Id))
{
<div class="slider__item"><img src="~/Images/Products/#image.Image" /></div>
}
</div>
<div class="meta">
<h3 class="meta__title">#item.Name</h3>
<span class="meta__brand">#item.Brand</span>
<span class="meta__price">R #item.Price</span>
</div>
<a class="action action--button action--buy" href="#Url.Action("AddToPlatform", "ProductPlatforms", new { ProdID = item.Id })" id="platformAdd" data-value="#item.Id"><i class="fa fa-shopping-cart"></i><span class="text-hidden">Add to Platform</span></a>
</div>
}
</section>
The last tag is what will be clicked on to add the product to the cart.
Script -Ajax
$("#platformAdd").click(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: $(this).attr("href"),
success: toastr["success"]("Product added to Platform")
});
});
Controller function
public void AddToPlatform(int ProdID)
{
var currUser = User.Identity.GetUserId();
DateTime now = DateTime.Now;
var exists = ProductExists(ProdID);
if (exists == false)
{
ProductPlatform prodPlatform = new ProductPlatform()
{
ProductID = ProdID,
UserID = currUser,
ViewedStatus = false,
DateAdded = now
};
db.ProductPlatforms.Add(prodPlatform);
db.SaveChanges();
}
}
The ajax script function would call the controller function which will add the product to the cart. Since there are no redirects I can't seem to figure out why the ajax call redirects to the tag "href".
Thanks for any help!
You need to use class instead of id because ids are always unique.
$(".lnkAddProduct").click(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: $(this).attr("href"),
success: function(){alert("ADDED");}
});
});
Trying to search in Wikipedia by user's input but it doesn't work for some reason. First I thought it could be due to cross domain problem. But .ajax should help with that.
Here is codepen: http://codepen.io/ekilja01/pen/pRerpb
Here is my HTML:
<script src="https://use.fontawesome.com/43f8201759.js">
</script>
<body>
<h2 class="headertext">WIKIPEDIA <br> VIEWER </h2>
<div class="row">
<div class="col-10-md">
<input class="searchRequest blink_me" id="cursor" type="text" placeholder="__"></input>
</div>
<div class="searchIcon col-2-md"> </div>
</div>
<div>
<p class=results></p>
</div>
</body>
Here is my jQuery:
$(document).ready(function() {
var icon = "<i class='fa fa-search fa-2x'></i>";
$('#cursor').on("keydown", function() {
$(this).removeClass("blink_me");
var searchIcon = $(".searchIcon");
searchIcon.empty();
if ($(".searchRequest").val().length > 0) {
searchIcon.append(icon);
}
searchIcon.on("click", function() {
console.log("clicked!");
var search = $(".searchRequest").val();
var url = "https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=" + search + "&format=json&callback=?";
$.ajax({
dataType: "jsonp",
url: url,
success: function(data) {
$(".results").html(data[0]);
console.log(data[0]);
}
});
});
});
});
What am doing wrong? Please help.
There's an error in the order of load for your js.
The data object contains the text of the results in the array with index 2, which i assume is what you want to show, change it to
$(".results").html(data[2]);
You can check a modified version of your original code here
http://codepen.io/anon/pen/mRmGXG
how to get muttiple data attribute from element classes of response html.
I can extract only data.
this is response.html
<div class="book" data-name="frozen" data-author="micheal" data-price="30">
Frozen
</div>
<div class="book" data-name="unbroken" data-author="jimmy" data-price="25">
Unbroken
</div>
<div class="book" data-name="carry on" data-author="alex" data-price="32">
Carry On
</div>
Ajax code here
function getData($scope){
$.ajax({
url: "/response.html",
dataType: "html",
success: function(response) {
var $response = $(response);
// not working
// var $book-data = $response.find('div.book').data({'name','author','price'});
var $bookData = $response.find('div.book').data('name');
alert($bookData);
}
});
}
I wish to get book-data as json or array to display in angular.
try this:
var bookData=Array();
$.get("stackTest.html", function(response) {
$.each($(response).find(".book"),function(ind,ele){
bookData.push($(ele).data());
});
console.log(bookData);
});
then you get an array with the data-object of each ".book" node
mike
Pretty easy:
var allData = [];
$('.book').each(function(i){
allData.push( $(this).data() );
});
console.log( allData );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="book" data-name="frozen" data-author="micheal" data-price="30">
Frozen
</div>
<div class="book" data-name="unbroken" data-author="jimmy" data-price="25">
Unbroken
</div>
<div class="book" data-name="carry on" data-author="alex" data-price="32">
Carry On
</div>