Jquery complementary functions not working as desired - javascript

I have two complementary functions, one that publishes a post, and one that unpublishes a post when the user clicks the same button (the button is acting as a toggle). If the post is not published and the user goes to publish it everything works as it is supposed to, however if the user decides to unpublish it again the function to publish is erroneously called again. I am using class selectors to accomplish this. So publish does its business and then sets the class to unpublish so that when the user clicks the button unpublish gets called (which doesn't happen).
I have verified that publish gets the class unpublish after being called, and vise versa but the complementary function never gets called despite having its class changed in the final lines. Console.log shows that publish keeps getting called.
What am I doing wrong?
$('a.publish').on('click', function(e) {
console.log('publish item');
var id = $(this).attr('data-id');
var table = $(this).attr('rel');
var parent = $(this).closest('.btn-group');
var current = $(this).closest('a');
$.ajax({
type: 'POST',
url: '',
data: 'publish=' + id + '&table=' + table,
success: function(data) {
$('#published_' + id).hide().html(data).fadeIn();
count(table);
var buttons = parent.find(".btn-danger");
buttons.each(function() {
$(this).removeClass("btn-danger").addClass("btn-primary");
});
current.find('span').text('Unpublish');
current.removeClass("publish").addClass("unpublish");
}
});
e.preventDefault();
});
$('a.unpublish').on('click', function(e) {
console.log('unpublish item');
var id = $(this).attr('data-id');
var table = $(this).attr('rel');
var parent = $(this).closest('.btn-group');
var current = $(this).closest('a');
$.ajax({
type: 'POST',
url: '',
data: 'unpublish=' + id + '&table=' + table,
success: function(data) {
$('#published_' + id).hide().html(data).fadeIn();
count(table);
var buttons = parent.find(".btn-primary");
buttons.each(function() {
$(this).removeClass("btn-primary").addClass("btn-danger");
});
current.find('span').text('Publish');
current.removeClass("unpublish").addClass("publish");
}
});
e.preventDefault();
});
If this has to do with DOM or something, how can I subvert it?
HTML:
<a class="btn btn-sm btn-primary unpublish" href="javascript:void(0);" data-id="213114246" rel="projects">
<i class="glyphicon glyphicon-plus"></i>
<span class="actions">Unpublish</span>
</a>

$('.btn-container').on('click', '.btn', function(e) {
if ($(this).hasClass('publish')) {
console.log('publish item');
$(this).removeClass("publish").addClass("unpublish").text('unpublish');
} else {
console.log('unpublish item');
$(this).removeClass("unpublish").addClass("publish").text('publish');
}
e.preventDefault();
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn-container">
<a class="btn btn-sm btn-primary unpublish">unpublish</a>
</div>

Related

AJax Submit onclick Font Awesome Icon

I am trying to display a simple rating option on a website, a thumbs up & down that when clicked will send the response to my external URL.
The site will be displayed on mobile devices as well as desktops (that's why i'm using touchstart and click).
I need to post the following values to my external URL;
date
time
feedback (good / bad)
I'm successfully receive the date and time, but not feedback type. Looking at the console I can see the following;
My code is as follows;
HTML
<form id="kioskFeedback">
<i class="fa fa-thumbs-o-up fa-4x"></i>
<i class="fa fa-thumbs-o-down fa-4x"></i>
</form>
AJAX
$(document).ready(function() {
var today = new Date();
var date = today.getDate() + '/' + (today.getMonth() + 1) + '/' + today.getFullYear();
var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
$("#kioskFeedback").on("touchstart, click", function(e) {
event.preventDefault();
var serializedData = $(this).serialize();
$.ajax({
url: "my external url here",
type: "post",
data: serializedData + '&Date=' + date + '&Time=' + time
});
.done(function(response, textStatus, jqXHR) {
console.log('success');
});
});
});
Expanding on #ADyson's comment, look at the docs for $.serialize() http://api.jquery.com/serialize/
To Make what you have work...
Change this var serializedData = $(this).serialize();
to this var serializedData = $(this).attr('value');
That should get you started. Once you read the documentation and understand that <a></a> elements are not form elements and the $.serialize() method will not return the expected results you may want to go back and update the rest of the click handler to use a different variable name like so,
$("#kioskFeedback a").on("touchstart, click", function(e) {
e.preventDefault();
var feedbackVal = $(this).attr('value');
$.ajax({
url: "my external url here",
type: "post",
data: {
// If the script is expecting "Feedback" swap in place of "value"
value: feedbackVal,
Date: date,
Time: time
}
});
.done(function(response, textStatus, jqXHR) {
console.log('success');
});
});
Also you should change event.preventDefault(); to e.preventDefault() seeing that your event information is being passed as e and not event.
Your target needs to get updated also, so adding an a to $("#kioskFeedback")
like this $("#kioskFeedback a") will shrink the scope to the link element. Allowing you to get the attribute value.
I am also attaching a working fiddle.
$("#kioskFeedback a").on("touchstart, click", function(e) {
e.preventDefault();
var feedbackVal = $(this).attr('value');
console.log(feedbackVal);
/* $.ajax({
url: "my external url here",
type: "post",
data: {
// If the script is expecting "Feedback" swap in place of "value"
value: feedbackVal,
Date: date,
Time: time
}
});
.done(function(response, textStatus, jqXHR) {
console.log('success');
}); */
});
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="kioskFeedback">
<i class="fa fa-thumbs-o-up fa-4x"></i>
<i class="fa fa-thumbs-o-down fa-4x"></i>
</form>

No refresh or page reload using JS

I have an Ajax request in my Rails 4 app, but once the button is clicked it reloads the entire page. How can I keep that from happening? The page is cached so I cannot simply add a link_to or button_to. Thanks in advance.
listing_collection.js
$(document).ready(function(){
$(".listcollect").on("click", function(){
var listID = this.id;
$.ajax({
method: "GET",
url: "/listing_collections/:id/listcollect",
success: function(result) {
var arrLen = result.length
var $ul = $("<ul></ul>")
for (var i = 0; i<arrLen; i++){
var $li = $("<li></li>");
var $a = $("<a></a>");
$a.attr("href", "/listings/" + listID + "/add_to_collection?listing="+listID+"$amp;listing_collection_id="+result[i]["id"]+"&listing_id="+listID)
$a.text(result[i]["name"])
$li.append($a)
$(this).next().append($li)
}
}.bind(this)
})
});
});
This is the button:
<div class="btn-group listcollect-wrapper">
<button class="listcollect button btn-blue-white btn-2x dropdown-toggle" data-toggle='dropdown' type="button" id=<%= listing.id %>>Add to Listing Collection <span class="caret"></span></button>
<ul class='dropdown-menu'>
</ul>
</div>
My two cents
The dom with this class .listcollect is a button of type submit i.e button type="submit"
You can either use button type = "button" or use
event.preventDefault()
$(".listcollect").on("click", function(){
event.preventDefault()
// Rest of code
})
It's because this is the default behaviour of the anchor tag. As suggested you can either change the control type to something like button or override the default behaviour like so:
$(".listcollect").on("click", function(e){
e.preventDefault();
});
Try this:
$(document).ready(function(){
$(".listcollect").on("click", function(e){
e.preventDefault();
e.stopPropagation();
var listID = this.id;
$.ajax({
method: "GET",
url: "/listing_collections/:id/listcollect",
success: function(result) {
var arrLen = result.length
var $ul = $("<ul></ul>")
for (var i = 0; i<arrLen; i++){
var $li = $("<li></li>");
var $a = $("<a></a>");
$a.attr("href", "/listings/" + listID + "/add_to_collection?listing="+listID+"$amp;listing_collection_id="+result[i]["id"]+"&listing_id="+listID)
$a.text(result[i]["name"])
$li.append($a)
$(this).next().append($li)
}
}.bind(this)
})
});
});
I have added e.preventDefault() that prevents the browser to handle the the click by default and e.stopPropagation() that disable the propagation of the click event to the containers of your control, in case they have listener too.

Toggle data-value after Ajax success without element ID

I have multiple buttons to toggle status of different projects:
<div class="btn-group btn-toggle project_status" data-project-id="1" data-form="project_status" data-value="1">
<button class="btn btn-default active">ACTIVE</button>
<button class="btn btn-primary">CLOSED</button>
</div>
<div class="btn-group btn-toggle project_status" data-project-id="2" data-form="project_status" data-value="1">
<button class="btn btn-default active">ACTIVE</button>
<button class="btn btn-primary">CLOSED</button>
</div>
I need to toggle the data-value between 1 and 2 when ajax post success.
I have tried this so far but without any luck:
$('.project_status').click(function(){
var project_id = $(this).attr('data-project-id');
var project_status_val = $(this).attr('data-value');
var toggle_status = function(){
$(this).find('.btn').toggleClass('active').toggleClass('btn-primary');
if (project_status_val == '1'){
alert(project_status_val);
$(this).attr('data-value','2');
} else {
alert(project_status_val);
$(this).attr('data-value','1');
}
return false;
};
var dataString = 'project_id=' + project_id + '&project_status=' + project_status_val;
$.ajax({
type: "POST",
url: "post.php",
data: dataString,
success: toggle_status
});
$('#sidebar-wrapper').load('sidebar.php');
return false;
});
I have got the alert data value correct. I have got the sidebar reload with updated value (only the first click). But I am not able to change the attribute value so that the next click will send the toggled value.
Please help! Thx
$(this) inside the toggle_status method is not your btn. Inside the method the this keyword refers to the object the method belongs to. In this case Window. As a workaround, I have made a self property before the method to store a reference to the selected $('.project_status') object. I have updated the code so it will work.
https://jsfiddle.net/05akxvx3/1/
$('.project_status').click(function(){
var self = $(this);
var project_id = self.attr('data-project-id');
var project_status_val = self.attr('data-value');
var toggle_status = function(){
self.find('.btn').toggleClass('active').toggleClass('btn-primary');
if (project_status_val == '1'){
self.attr('data-value','2');
} else {
self.attr('data-value','1');
}
alert(self.attr('data-value'));
return false;
};
var dataString = 'project_id=' + project_id + '&project_status=' + project_status_val;
$.ajax({
type: "POST",
url: "post.php",
data: dataString,
success: toggle_status
});
$('#sidebar-wrapper').load('sidebar.php');
return false;
});
You have an extra dash in your $(this).attr() statement.
$(this).attr('data--value','2'); ought to be:
$(this).attr('data-value','2');

jquery script runs only if page refresh

i have a button with the folowing code
<button type="button" class="btn btn-success btn-xs vote up" id="76" name="up"><span class="glyphicon glyphicon-thumbs-up"></span> Bueno</button>
the button does not work unless i reload the page, and i dont know why. any ideas?
jquery code is at the beginning of the body
jquery
<script type="text/javascript">
$(function() {
$(".vote").click(function()
{
var id = $(this).attr("id");
var name = $(this).attr("name");
var dataString = 'id='+ id ;
var parent = $(this);
var _this = this;
if(name=='up')
{
$(this).fadeIn(600).html('<span class="glyphicon glyphicon-ok"></span>');
$.ajax({
type: "POST",
url: "up_vote.php",
data: dataString,
cache: false,
success: function(html)
{
parent.html(html);
$( _this ).remove();
$( ".escondido" ).css( "display", "block" );
} });
return false;
});
});
</script>
If the jQuery code is at the beginning of the code (before the HTML) as you state, the DOM would not have been created yet. Try moving the jQuery code to the bottom of the body (after the HTML).
I would assume you're getting an error in the button click event. Have you tried using the live('click') instead? Can you demonstrate the issue using JSFIDDLE?
In the jsFiddle I created, I'm seeing syntax errors - Original Code
If I change the code to Edited jsFiddle:
$(function () {
$(".vote").click(function () {
var id = $(this).attr("id");
var name = $(this).attr("name");
var dataString = 'id=' + id;
var parent = $(this);
var _this = this;
if (name == 'up') {
$(this).fadeIn(600).html('<span class="glyphicon glyphicon-ok"></span>');
$.ajax({
type: "POST",
url: "up_vote.php",
data: dataString,
cache: false,
success: function (html) {
parent.html(html);
$(_this).remove();
$(".escondido").css("display", "block");
}
});
return false;
}; // Removed ) from this line
});
}); // Added this whole line

Jquery ajax addClass issue

First sorry im a big beginner and just experimenting, and I made a similar wall like facebook with oembed.
And would like to add a like, and dislike button too.
I started with the like button, it works, likes, and unlikes too, and the cookie saves the class value perfectly.
My problems is the ajax call, so actually when I click on the like button it overwrites all anchors href val and adds a class to all not on what click.
here is my code
jquery
var cookieLike = "like_"
$('a.like').each(function(){
var id = $(this).attr('href'), cookieLiked = cookieLike + id;
switch($.cookies.get(cookieLiked) ) {
case "unliked":
$(this).removeClass('btn-success');
break;
case "liked":
$(this).addClass('btn-success');
break;
}
}).on('click', function(e){
e.preventDefault()
var likeId = $(this).attr('href');
$.ajax({
url: "<?php echo base_url(); ?>stream/like/" + likeId ,
type: "post",
data: likeId,
dataType: "json",
success: function(like)
{
if(like.likeStatus == "unliked") {
$('a.like').attr('href', likeId).removeClass('btn-success');
$.cookies.set(cookieLike + likeId, 'unliked');
}else if(like.likeStatus == "liked") {
$('a.like').attr('href', likeId).addClass('btn-success');
$.cookies.set(cookieLike + likeId, 'liked');
}
}
});
});
html
<div class="stream-bottom">
Komment
<div class="pull-right like-options">
<i class="icon-thumbs-up" title="tetszik"></i>
<i class="icon-thumbs-down" title="nem tetszik"></i>
</div>
</div>
could please someone point out what i am missing?
Maybe:
.on('click', function (e) {
e.preventDefault();
var button = $(this);
var likeId = button.attr('href');
$.ajax({
url: "<?php echo base_url(); ?>stream/like/" + likeId,
type: "post",
data: likeId,
dataType: "json",
success: function (like) {
if (like.likeStatus == "unliked") {
button.removeClass('btn-success');
$.cookies.set(cookieLike + likeId, 'unliked');
} else if (like.likeStatus == "liked") {
button.addClass('btn-success');
$.cookies.set(cookieLike + likeId, 'liked');
}
}
});
});
Bind the target element (the clicked link) and reference it in the success callback
In the .on('click') callback
var $link = $(this);
In the success callback use
$(this).attr('href', likeId)
instead of
$('a.like').attr('href', likeId)
When you use $("a") or $("a.like") you are referring to the entire set of anchor tags or anchor tags with 'like' as the class name. To specifically use the anchor tag on which you have clicked use $(this) variable.
That will give you the element on which the event got generated and in this case the anchor tag on which you clicked.

Categories

Resources