Rebind .toggle() event after unrelated event? - javascript

I have a filter for a grid that is being shown/hidden with toggle like so:
$("#btnFilter").toggle(function () {
// show filter
}, function () {
// hide filter
});
The grid is interactive and double-clicking it will overlay the existing grid with new dynamic HTML. I do not want my filter to be shown when interacting with the grid, so in my grids onClick() event I am putting the appropriate // hide filter code which is the same as in the toggle function.
The only issue is, since I am bypassing the .toggle() event, I'll need to click on #btnFilter twice when attempting to hide it manually (which is what I do not want).
Any thoughts would be great!
I appreciate the answers but the logic isn't really what concerns me, any idea why toggle has been removed? Possibly related to my issue?

Toggle is removed you can use a boolean variable or just ask jQuery if it's visible
$('#btnFilter').on('click', function () {
if ($("#filterDiv").is(":visible")) {
$("#filterDiv").hide();
} else {
$("#filterDiv").show();
}
});

toggle(function,function...) is removed, create a bool and use an if statement
var toggle = false;
$('#btnFilter').on('click', function () {
toggle = !toggle;
if (toggle) {} else {}
});
toggle(function,function...) remove because:
This is the "click an element to run the specified functions"
signature of .toggle(). It should not be confused with the "change the
visibility of an element" of .toggle() which is not deprecated. The
former is being removed to reduce confusion and improve the potential
for modularity in the library. The jQuery Migrate plugin can be used
to restore the functionality.

Related

Why does jquery not respond accordingly to my conditions?

I want my tablerows to have the class 'clickable' only if edit mode is turned on. With element inspect I can see that this works. It succesfully removes the 'clickable' class if I turn off edit mode.
If a table row has the class clickable it will click it's checkbox upon clicking the table row. This works too, however when I turn off edit mode, I'm still able to click tablerows and by doing so, also check the checkbox.
If you can see something that I've overlooked please let me know.
function clickableTableRow(isClickable) {
if (isClickable) {
$(tableBody).find('tr').each(function () {
$(this).addClass("clickable");
$(this).click(function () {
$(this).find('input[type=checkbox]').click();
});
})
} else {
$(tableBody).find('tr').each(function () {
$(this).removeClass("checked").removeClass("clickable");
$(this).find('input[type=checkbox]').prop("checked", false);
})
}
}
So to clarify, in element inspect I can see that it does all as it should, so I think the problem lays in the function where I make a checkbox click upon clicking on a tablerow
Use .off()
$(this).off('click');
The off() Method in jQuery is used to remove event handlers attached
with the on() method -or the .click() method. The off() method brings a lot of consistency to
the API and it replace unbind(), die() and undelegate() methods.
The event handler was still active, using .off() turns it off. Adding this line of code tot the else statement solved the issue:
$(this).off('click');

From Bootstrap 4 collapse events, is it possible to extract which elements have been hidden/shown?

I'd like to add some additional functionality to a Bootstrap 4 accordion, and am considering using their events (https://getbootstrap.com/docs/4.0/components/collapse/#events). However, from their example,
$('#myCollapsible').on('hidden.bs.collapse', function () {
// do something…
})
It seems that no information is passed into the callback function.
I would like to know which element(s) were shown or hidden. Do I understand correctly that this is not possible using the .bs.collapse events?
It seems from http://api.jquery.com/Types/#Event that the shown/hidden element is simply accessible as this in the callback function. A little experiment with the debugger shows that this is indeed the case:
This is way late in the game but maybe someone will have benefit. For any of the 4 events you should be able to do something similar (in this case I want the id of the element that is being shown:
$('#accordionProperty').on('shown.bs.collapse', function (e) {
CallingSomeFunctionOfMineWithId(e.target.id);
})
And for hidden:
$('#accordionProperty').on('hidden.bs.collapse', function (e) {
CallingSomeFunctionOfMineWithId(e.target.id);
})
Hope this helps.

Changing Bootstrap panel CSS class for "active" panel (clicked/focused)

I have a page with multiple Bootstrap panels, and I want to make it so that only the "active" panel has the panel-primary class (so, highlighted, in a sense). The definition of "active" in this case is that the user has clicked anywhere inside a panel or changed focus with keyboard or something.
So, I started with this:
function highlightActivePanel($activePanel) {
$('.panel-primary').toggleClass('panel-primary panel-default');
$activePanel.toggleClass('panel-default panel-primary');
}
$(document).on('click', '.panel-default', function () {
highlightActivePanel($(this));
});
The trouble is, I have a table with jquery DataTables plugin inside the panels. So, if I register the click event, it generally works, but not when you click on of the DataTables paging number buttons at the bottom of the panel for some reason. The click even doesn't fire. Probably due to DT's own click events, I'm guessing.
So, I then tried the focus event:
$(document).on('focus', '.panel-default', function () {
highlightActivePanel($(this));
});
... and that works better with clicking on DataTables buttons and fields, but doesn't work if the user simply clicks on the text (or in a table cell) inside a panel.
Finally, if I just simply leave both event listeners registered, it seems to work, but I'm wondering if this is smart, or if there is a better/cleaner way of doing this?
$(document).on('click', '.panel-default', function () {
highlightActivePanel($(this));
});
$(document).on('focus', '.panel-default', function () {
highlightActivePanel($(this));
});
Here's a JsFiddle that better illustrates what I'm talking about.
Edit: Just realized I can easily combine the two events like this:
$(document).on('click focus', '.panel-default', function () {
highlightActivePanel($(this));
});
But if there is still a better way to do this, let me know.
Clicking on the DataTables paging numbers triggers page.dt, so you could do click page.dt in place of click focus to avoid potentially losing focus to something else on the page (though you could also do that by using a more specific selector).

Input:Checked jQuery vs CSS?

Unless I am mistaken. jQuery and CSS handle the :checked selector very differently. In CSS when I use :checked, styles are applied appropriately as I click around, but in jQuery it only seems to recognize what was originally in the DOM on page-load. Am I missing something?
Here is my Fiddle
In jQuery:
$('input:checked').click(function () {
$('input:checked').css('background','#FF0000');
$('input:checked+label').css('background','#ff0000');
});
In CSS:
input:checked+label {font-weight:bold;color:#5EAF1E}
UPDATE:
I should clarify that what I am looking to do is trigger behavior if a user clicks an already selected radio button.
Try setting up the handler this way:
$('body').on('click', 'input:checked', function() {
// ...
});
The way you have it, you're finding all the elements that are checked when that code runs. The above uses event bubbling so that the test is made when each "click" happens.
Inside your handler, you're updating the style for all checked elements, even though any particular click will only change one. That's not a huge deal if the number of checkboxes isn't too big.
edit — some further thought, and a helpful followup question, makes me realize that inside an event handler for a radio button "click" event, the button will always be ":checked". The value of the "checked" property is updated by the browser before the event is dispatched. (That'll be reversed if the default action of the event is prevented.)
I think it'll be necessary to add a class or use .data() to keep track of a shadow for the "checked" property. When a button is clicked, you'd see if your own flag is set; if so, that means the button was set before being clicked. If not, you set the flag. You'll also want to clear the flag of all like-named radio buttons.
You bound the event only to the inputs that were initially checked. Remove :checked from the first selector and it works as intended (but ugly.)
http://jsfiddle.net/8rDXd/19/
$('input').click(function () {
$('input:checked').css('background','#FF0000');
$('input:checked+label').css('background','#ff0000');
});
you would of course need to "undo" the css change you made with jQuery to make it go away when the input is unchecked.
$('input').click(function () {
$('input').css('background','').filter(":checked").css('background','#FF0000');
$('input+label').css('background','');
$('input:checked+label').css('background','#ff0000');
});
http://jsfiddle.net/8rDXd/20/
AFTER UPDATE
Keep track of the status of the radio buttons. For example, use .data() to keep an in-memory state of the radio buttons.
$(function () {
var $radio = $(":radio");
$radio.filter(":checked").data("checked", true);
$radio.on("click", function () {
if ($(this).data("checked")) {
alert("Already selected");
}
$radio.data("checked", false).filter(":checked").data("checked", true);
});
});
See it live here.
BEFORE UPDATE
I think you want to use .change() here.
$('input:radio').change(function () {
$('input, input+label').css('background', '');
$('input:checked, input:checked+label').css('background', '#f00');
}).change();
See it live here.

toggling between two classes jQuery = works but extra click

Sort
$(".sort").click(function (event) {
$(this).toggle(function() {
$(this).toggleClass("sortUp","sortDown");
}, function() {
$(this).toggleClass("sortDown","sortUp");
});
});
it works but I need to click once before it works.
so -
click (nothing happens), click (sortUP), click (sortDown)
I would like to remove first click.
Thank you community for the help !
Firstly, you're using toggleClass incorrectly. You appear to want to toggle sortDown and sortUp on each click. That's done with toggleClass("sortDown sortUp").
Secondly, you need your class .sort to either have sortUp or sortDown set in its class property when you load the page. e.g. <a href="#" class="sort sortDown">. This makes sure you can reason about your code (i.e. it's always true that exactly one of sortUp, sortDown are set on your div).
Thirdly, $(this).click(function() { /* code */ }) means "when somebody clicks, do /*code*/". You've wrapped your
$(this).click(function() { $(this).toggleClass("sortUp sortDown"); })
which sets up the click behaviour, in a $(".sort").click(function () { which means you are requiring an initial click on "sort" just to start the behaviour.
So the correct version is:
Sort
$(document).ready(function () {
$(".sort").click(function() {
$(this).toggleClass("sortUp sortDown");
});
});
if you dont' want to begin with a sortUp or sortDown class, do this:
Sort
$(".sort").click(function (event) {
if($(this).hasClass("sortUp") || $(this).hasClass("sortDown")){
$(this).toggleClass("sortUp sortDown");
}else{
$(this).addClass("sortUp");
}
});
It looks like you are adding the click events on the first click, also if you want to switch between sortUp and sortDown you can simply specify them both. As long as the element starts with one or the other (not both and not neither), it will swap them each time.
$(".sort").click(function() {
$(this).toggleClass('sortUp sortDown');
});
You can see this running on JSFiddle.

Categories

Resources