JQuery Click Function Randomly Stops Working - javascript

I am sorting a list of users by first name when a user click on the sort icon. However, I've noticed that there are times when I click the sort icon, the icon is switched, however, the data not sorted. For example, I click on it 10 times, and there may be 3 times when the data simply not sorted but the icon changed. Any help here would be appreciated.
A partial section of the html code.
<div class="divFullWidth hidden-sx col-sm-2 col-md-2 col-lg-2">
First Name
<a id="sortName" href="#" data-sort="SORT">
<i id="sortIcon" class="sort fa fa-1x fa-sort-alpha-desc"></i></a></div>
The function to handle replacing the button and submit the form.
$('#sortName').on('click', function (e) {
e.preventDefault();
if ($('#sortIcon').hasClass('fa-sort-alpha-desc')) {
$('#searchVal').val('asc');
$('form').submit();
$(this).find('#sortIcon').removeClass('fa-sort-alpha-desc').addClass('fa-sort-alpha-asc');
} else {
$('#searchVal').val('desc');
var myVal = $('#searchVal').val();
$('form').submit();
$(this).find('#sortIcon').removeClass('fa-sort-alpha-asc').addClass('fa-sort-alpha-desc');
}
});

Is the following line suppose to be the same in both the if block and the else block?
$(this).find('#sortIcon').removeClass('fa-sort-alpha-desc').addClass('fa-sort-alpha-asc');

Try it like this
$('a#sortName').on('click', function (e) {
e.preventDefault();
// Setting the current clicked icon into a variable.
var findSortIcon = $(this).find('#sortIcon');
if (findSortIcon.hasClass('fa-sort-alpha-desc')) {
$('#searchVal').val('asc');
//$('form').submit(); - We are sending the submit anytime whenever the button is clicked
findSortIcon.removeClass('fa-sort-alpha-desc').addClass('fa-sort-alpha-asc');
} else {
$('#searchVal').val('desc');
//var myVal = $('#searchVal').val(); - no need for this (You dont use it anyway)
// $('form').submit(); - same in here
findSortIcon.removeClass('fa-sort-alpha-asc').addClass('fa-sort-alpha-desc');
}
// Whether its true or false submit it!
$('form').submit();
// Extra stuff to check changing directly
var attr = findSortIcon.attr("class");
$('#show-class').html(attr + " for " + $(this).text())
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="divFullWidth hidden-sx col-sm-2 col-md-2 col-lg-2">
First Name
<a id="sortName" href="#" data-sort="SORT">
<i id="sortIcon" class="sort fa fa-1x fa-sort-alpha-desc">
ICON
</i>
</a>
</div>
<div class="divFullWidth hidden-sx col-sm-2 col-md-2 col-lg-2">
First Name2
<a id="sortName" href="#" data-sort="SORT">
<i id="sortIcon" class="sort fa fa-1x fa-sort-alpha-desc">
ICON2
</i>
</a>
</div>
<div id="show-class"></div>

Try this code instead:
$('#sortName').on('click', function (e) {
e.preventDefault();
if ($('#sortIcon').hasClass('fa-sort-alpha-desc')) {
$(this).find('#sortIcon').removeClass('fa-sort-alpha-desc').addClass('fa-sort-alpha-asc');
$('#searchVal').val('asc');
} else {
$(this).find('#sortIcon').removeClass('fa-sort-alpha-asc').addClass('fa-sort-alpha-desc');
$('#searchVal').val('desc');
}
$('form').submit();
});

I changed the code to see if the hidden field is null or not. Then, I made a decision based on that decision. The new JQuery code is below, and it's worked fine so far.
$('#sortName').on('click', function (e) {
e.preventDefault();
var testVal = $('#searchVal').val();
if (testVal === 'desc') {
$('#sortIcon').removeClass('fa-sort-alpha-desc').addClass('fa-sort-alpha-asc');
$('#searchVal').val('asc');
} else {
$('#sortIcon').removeClass('fa-sort-alpha-asc').addClass('fa-sort-alpha-desc');
$('#searchVal').val('desc');
}
$('form').submit();
});

Related

Link within a bootstrap list-group-item, but popup confirmation before clicking link

I have a 'bootstrap list group item'. I am trying to create a link inside the link area. The code below works:
// THIS CODE WORKS //
<a href="" class="list-group-item list-group-item-action active text-white rounded-0">
// --- JUST A BUNCH OF HTML COMES HERE -- //
<i class="fa fa-trash" aria-hidden="true" onclick="window.open('?delete=<?=$x?>','_self');return false;"></i>
</a>
Now what I would like to do is to add a confirmation to this so the user doesn't delete by mistake.
// WANT TO ADD THIS FEATURE //
return confirm('Are you sure you want to delete?');
How would I combine these to? When I try they will not execute. I have tried.
// WHAT I TRIED //
function Heya()
{
return confirm('Are you sure you want to delete?');
}
function Hoo()
{
window.open('?delete','_self');return false;
}
// AND ON THE PAGE //
<i class="fa fa-trash" aria-hidden="true" onclick="Heya(); Hoo();"></i>
It doesn't work... And I also need a way to pass on the variable 'x' to the script since it will differ..
Thanks a lot for help.
function checkDelete(x)
{
if (confirm('Are you sure you want to archive?')) {
var url = '?delete=' + x;
window.open(url,'_self');
}
return false;
}
<i class="fa fa-trash" aria-hidden="true" onclick="return checkDelete(<?=x?>);"></i>

Add external link to an <a> element inside a Click Event Listener Div

I'm having trouble adding a link to a button inside a card. the card is wrapped in a div element which when clicked automatically expands and closes.
Is there anyway to remove this functionality just when clicking on the details button? So it acts as a normal link?
Here is the code:
https://codepen.io/candroo/pen/wKEwRL
Card HTML:
<div class="card">
<div class="card__image-holder">
<img
class="card__image"
src="https://source.unsplash.com/300x225/?wave"
alt="wave"
/>
</div>
<div class="card-title">
<a href="#" class="toggle-info btn">
<span class="left"></span>
<span class="right"></span>
</a>
<h2>
Card title
<small>Image from unsplash.com</small>
</h2>
</div>
<div class="card-flap flap1">
<div class="card-description">
This grid is an attempt to make something nice that works on touch
devices. Ignoring hover states when they're not available etc.
</div>
<div class="card-flap flap2">
<div class="card-actions">
Read more
</div>
</div>
</div>
</div>
JS:
$(document).ready(function () {
var zindex = 10;
$("div.card").click(function (e) {
e.preventDefault();
var isShowing = false;
if ($(this).hasClass("show")) {
isShowing = true;
}
if ($("div.cards").hasClass("showing")) {
// a card is already in view
$("div.card.show").removeClass("show");
if (isShowing) {
// this card was showing - reset the grid
$("div.cards").removeClass("showing");
} else {
// this card isn't showing - get in with it
$(this).css({ zIndex: zindex }).addClass("show");
}
zindex++;
} else {
// no cards in view
$("div.cards").addClass("showing");
$(this).css({ zIndex: zindex }).addClass("show");
zindex++;
}
});
});
You can check the target of the event and see if it is an <a> using is()
Something like:
$("div.card").click(function (e) {
// only run when not an `<a>`
if(!$(e.target).is('a')){
e.preventDefault();
//the rest of your code
....
}
});
I don't know Jquery but with javascript you can do this inside your code:
const links = document.querySelectorAll('.btn');
links.forEach(link => link.addEventListener('click', (e)=>e.stopPropagation()))

Disable close dropdown after click href

I would like to keep my dropdown opened after a page load. For example if I click on an item(href) into an dropdown, I would like to keep the dropdown opened after the redirection.
I've seen that there is a method jquery named stopPropagation, but it seems that this does not work for me
HTML
<div class="sidenav">
<div class="item_sn">
Groups
</div>
<div class="item_list_body">
<div class="link_sidenav">
<a href="#" class="sub_item">
group 1
</a>
</div>
<div class="link_sidenav">
<a href="#" class="sub_item">
group 2
</a>
</div>
</div>
<div class="item_sn">
Users
</div>
<div class="item_list_body">
<div class="link_sidenav">
<a href="#" class="sub_item">
user 1
</a>
</div>
<div class="link_sidenav">
<a href="#" class="sub_item">
user 2
</a>
</div>
</div>
</div>
JQuery
<script>
$(document).ready(function () {
$('.item_list_body').hide();
$('.item_sn').on('click', function (event) {
var content = $(this).next('.item_list_body')
content.slideToggle();
$('.item_list_body').not(content).slideUp();
});
});
</script>
Solution 1 (not working) :
$(document).on('click', '.sub_item', function (e) {
$(this).parent('.link_sidenav').parent('.item_list_body').toggle();
});
you can use sessionStorage to store the state of the menu and then open the menu on page load by checking the state see below
EDIT
rather than using state of the menu we should save the index of the clicked menu as discussed in the comment so updated my answer
$(document).ready(function () {
//sessionStorage.removeItem('opened');
$('.item_list_body').hide();
if (sessionStorage.getItem('opened') !== null) {
$('.sidenav>div:eq(' + sessionStorage.getItem('opened') + ')').next('.item_list_body').show();
}
$('.item_sn').on('click', function (event) {
var content = $(this).next('.item_list_body');
var elem = $(this);
content.slideDown(0, function () {
sessionStorage.setItem('opened', elem.index());
});
$('.item_list_body').not(content).slideUp();
});
});
Hope it helps

How to control back and forward button in jQuery

In my responsive website, I have these buttons that show on my mobile views. I am trying to make them navigate through my page.
<div class="row" id="bottomNav">
<div class="col-xs-4 text-center">
<a href="#" onclick="history.go(-1); return false;" id="back-button">
<i class="fa fa-arrow-left"></i>
</a>
</div>
<div class="col-xs-4 text-center">
<a href="#">
<i class="fa fa-refresh"></i>
</a>
</div>
<div class="col-xs-4 text-center">
<a href="#" onclick="history.go(1); return false;" id="forward-button">
<i class="fa fa-arrow-right"></i>
</a>
</div>
</div>
What I want them to do is, obviously allow the user to go back and forward.
However, I would like to disable these buttons if:
Disable Back button if:
there is no previous page in a history
back url will leave my website
Disable Forward button if:
there is no next page in a history
This is what I have done so far. It's not much.
<script>
alert(document.referrer);
alert(window.location.hostname);
var str = window.location.hostname;
//if back page is own page
if (str.search(document.referrer) >= 0) {
history.go(-1);
}
else {
$('#back-button').prop('disabled', false);
}
</script>
To make back button work, you can use document.referrer:
function isBackAvailable()
{
if (document.referrer === "") return false;
if (document.referrer.substr(0, 16) !== "http://localhost") return false;
// it can be (!document.referrer.startsWith("http://domain.com")) in ES6
return true;
}
function goBack()
{
if (isBackAvailable()) {
history.go(-1);
}
}
$(document).ready(function() {
$("#back-button")
.prop('disabled', isBackAvailable())
.on('click', goBack);
});
What about forward button - there is no normal way to check if forward button is available. It is a "hardware" browser button and there is simply no such method in API. I guess, it is related to security somehow.
However, you can simply execute history.go(1);. It will do nothing if there is no such page.

How can I prevent an event from finish firing on jquery?

I'm trying to capture when someone tries to close "edit mode" on a page and tell them to save changes.
What triggers edit mode is a collapse element, first child is "View", second child is "Edit". I also have an event listener attached to the "hide" event of the edit child, so when they click to collapse the edit mode, they will receive a message asking them if they want to continue without saving. Problem is, I ask them, and if they hit continue, everything is fine, but if they hit cancel, I want the edit mode to STOP collapsing, and remain as it is.
I've tried with e.preventDefault, stopImmediatePropagation, return false, nothing works.
HTML:
<div class="accordion" id="my-accordion">
<div class="accordion-group">
<div class="accordion-heading">
<ul class="nav nav-tabs tab-items">
<li id="firstTab" class="active">First</li>
<li id="secondTab">Second</li>
</ul>
</div>
<div id="collapseOne" class="accordion-body collapse in">
</div>
</div>
<div class="accordion-group" id="edit" style="display:none;">
<div class="accordion-heading center">
<a id="edit-toggler" class="accordion-toggle" data-toggle="collapse" data-parent="#my-accordion" href="#collapseTwo">
<i class='icon-arrow-up'></i> Open Edit <i class='icon-arrow-up'></i>
</a>
</div>
<div id="collapseTwo" class="accordion-body collapse">
</div>
</div>
</div>
JavaScript:
$('#batch-edit').on('hide', function () { // THIS IS FOR THE BATCH EDIT BUTTON FUNCTIONALITY
$('#collapseOne').collapse('toggle');
$('#edit-toggler').html("<i class='icon-arrow-up'></i> Open Edit <i class='icon-arrow-up'></i>");
isEdit = false;
if(UserEditing){
if(!confirm('Leave without saving?')) {
return false;
}
}
// DO SOME STUFF
});
Any help would be greatly appreciated.
Unfortunately, there is no native hide/show event you can bind to. This just means we need to trigger these custom events ourselves.
Take a look at this SO answer. Here is the link to the fiddle.
I did something similar to the solution in the answer linked above in order to get beforeHide, afterHide, beforeShow and afterShow events.
The snippet below can demo the events mentioned above.
var $show = $('#show'),
$hide = $('#hide'),
$batchEdit = $('#batch-edit');
$show.hide();
$show.on('click', function()
{
$show.hide();
$hide.show();
$batchEdit.show();
});
$hide.on('click', function()
{
$show.show();
$hide.hide();
$batchEdit.hide();
});
$batchEdit.on('beforeHide', function ()
{
alert('triggered beforeHide');
$show.show();
$hide.hide();
})
.on('afterHide', function ()
{
alert('triggered afterHide');
})
.on('beforeShow', function ()
{
alert('triggered beforeShow');
$show.hide();
$hide.show();
})
.on('afterShow', function ()
{
alert('triggered afterShow');
});
(function($){
$.override ={'show': $.fn.show, 'hide': $.fn.hide};
$.each($.override,function(M,F){
var m=M.replace( /^\w/, function(r){ return r.toUpperCase(); });
$.fn[M] = function(speed, easing, callback) {
var args=[speed||0,easing||'',callback||function(){}];
if( $.isFunction(speed)){
args[2]=speed;
args[0]=0;
}
if( $.isFunction(easing)){
args[2]=easing;
args[1]='';
}
if(!this.selector){
F.apply(this, arguments);
return this;
}
return this.each(function () {
var obj = $(this),
oldCallback = args[args.length-1],
newCallback = function () {
if ($.isFunction(oldCallback)){
oldCallback.apply(obj);
}
obj.trigger('after'+m);
};
obj.trigger('before'+m);
args[args.length-1]=newCallback;
//alert(args);
F.apply(obj,args);
});
}
});
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="batch-edit">Batch Edit</div>
<input type='button' id="show" value='Show'>
<input type='button' id="hide" value = 'Hide'>

Categories