JQuery toggle () with unknown initial state

I have a project I'm working on that uses a small image to mark the record as a favorite on several rows of the table. Data is retrieved from the database, and the image is based on whether this item is a favorite. One image for a loved one, another image if not a favorite. I want the user to be able to switch the image and make it a favorite or not. Here is my code:

$(function () { $('.FavoriteToggle').toggle( function () { $(this).find("img").attr({src:"../../images/icons/favorite.png"}); var ListText = $(this).find('.FavoriteToggleIcon').attr("title"); var ListID = ListText.match(/\d+/); $.ajax({ url: "include/AJAX.inc.php", type: "GET", data: "action=favorite&ItemType=0&ItemID=" + ListID, success: function () {} }); }, function () { $(this).find("img").attr({src:"../../images/icons/favorite_not.png"}); var ListText = $(this).find('.FavoriteToggleIcon').attr("title"); var ListID = ListText.match(/\d+/); $.ajax({ url: "include/AJAX.inc.php", type: "GET", data: "action=favorite&ItemType=0&ItemID=" + ListID, success: function () {} }); } ); }); 

Works great if the initial state is not a favorite. But you need to double-click to change the image if it is originally a favorite. This causes AJAX to fire twice and essentially makes it a favorite, not a favorite, before the image responds. The user believes that he made him a favorite, because the image has changed, but in fact it is not. Help someone?

+4
source share
4 answers

Add a class to your favorite Toggle that defines the state. Use this to determine the css for your icon, and not replace the image. Then it gives you the ability to easily determine the status of your favorite text.

 $(function() { $('.FavoriteToggle').click(function(){ var $this = $(this); var id = $this.find('.FavoriteToggleIcon').attr("title").match(/\d+/); if ($this.hasClass('isFavorite')){ $this.removeClass('isFavorite'); } else { $this.addClass('isFavorite'); } $.ajax({ url: "include/AJAX.inc.php", type: "GET", data: "action=favorite&ItemType=0&ItemID=" + id, success: function () {} }); }) }); 

Add to your css:

 .FavoriteToggle .icon{ background: url("../../images/icons/favorite_not.png"); } .FavoriteToggle.isFavorite .icon{ background: url("../../images/icons/favorite.png"); } 

In doing so, you get a class that defines the state, so you can do more, and then just change the image with it if you want, and this makes it so that you determine the image paths in your javascript, which is always dirty.

+1
source

I don’t know if this is suitable for you, but I usually use this as a switching function, and with some additional php I can even set it to one or another initial state:

 <style type="text/css"> <!-- .mybox_edit { display: none; } --> </style> <script language="JavaScript" type="text/JavaScript"> <!-- function toggleBox( box_id ) { var box_edit = document.getElementById(box_id + "_edit"); var box_show = document.getElementById(box_id + "_show"); // is it hidden? if ( box_show.style.display == 'none' ) { box_show.style.display = 'block'; box_edit.style.display = 'none'; } else { box_show.style.display = 'none'; box_edit.style.display = 'block'; } } //--> </script> 
0
source
 $(function () { // toggle on click $('.FavoriteToggle').click ( function() { // prevent duplicate AJAX request with a "loading" flag if (!this.isLoading) { var $img = $(this).find("img"); var ListID = $(this).find('.FavoriteToggleIcon').attr("title").match(/\d+/); // flag that we are currently loading something this.isLoading = true; // determine the action from the current state of the img if ($img.attr("src").indexOf("favorite.png") > -1) var actionVerb = "unFavorite"; else var actionVerb = "mkFavorite"; $.ajax({ url: "include/AJAX.inc.php", type: "GET", data: {action: actionVerb, ItemType: 0, ItemID: ListID }, success: function($i) { return function() { // change image on success only if ($i.attr("src").indexOf("favorite.png") > -1) { $i.attr("src", "../../images/icons/favorite_not.png"; else $i.attr("src", "../../images/icons/favorite.png"; }; }($img), error: function(xhr, textStatus, errorThrown) { // make some note of the error alert(textStatus); } complete: function(p) { return function(xhr, textStatus) { // set loading flag to false when done p.isLoading = false; }; }(this) }); } }); }); 

Unconfirmed, but you should get this idea.

All the material if ($img.attr("src").indexOf("favorite.png") could be made much easier by adding the favorite CSS class to <img> . For example, in the main function:

 var actionVerb = $img.is(".favorite") ? "unFavorite" : "mkFavorite"; 

and in the success callback:

 if ($i.is(".favorite")) $i.attr("src", "../../images/icons/favorite_not.png"; else $i.attr("src", "../../images/icons/favorite.png"; // now toggle the CSS class $i.toggleClass("favorite") 
0
source

Ok, here is what I got, a simplified version of the PetersenDidit post above.

 $('.FavoriteToggle').click(function() { var id = $(this).attr("title").match(/\d+/); if ($(this).hasClass('isFavorite')) { $(this).removeClass('isFavorite'); } else { $(this).addClass('isFavorite'); } $.ajax({ url: "include/AJAX.inc.php", type: "GET", data: "action=favorite&ItemType=0&ItemID=" + id, success: function() { } }); }); 
0
source

Source: https://habr.com/ru/post/1303837/


All Articles