toggling between two classes jQuery = works but extra click - javascript

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.

Related

JavaScript Function, Click Button and Resizing (Reverses Button Function)

My code has a button that changes some CSS via adding and removing classes. I have the JS working fine to do this. The first click adds the class, clicking again removes it and so on around it goes, nothing unusual there.
However, I've also incorporated a function that removes the classes if the browser window is resized at all. My issue is, if I then go back to press the button again after resizing the window, it thinks it should be doing the second click (almost reversing the function) and removes the classes (even though they've already been removed by the resizing), whereas I need the button function to almost reset and have it think the button hasn't been clicked yet after the resizing, so the process can be started from the beginning.
I really hope this makes sense, because its been driving me around the bend, and nothing I've tried will make it work how I would like it to.
Thank you for any help!
Heres the code:
JS/jQuery
{
/* Button Function to add and remove classes. */
$("#nav-icon").click(function () {
var clicks = $(this).data("clicks");
if (!clicks) {
$(".logo-container").addClass("border-change-image");
$(".container-fluid").addClass("border-change-header");
} else {
$(".logo-container").removeClass("border-change-image");
$(".container-fluid").removeClass("border-change-header");
}
$(this).data("clicks", !clicks);
});
/* Window Resizing Function */
$(window).on("resize", function () {
var size = $(this).on("resize");
if (size) {
$(".logo-container").removeClass("border-change-image");
$(".container-fluid").removeClass("border-change-header");
} else {
}
});
}
Removed the variable storing the data and just "asked" if one of the div's had one of the classes then add or remove, based on that. Works like a charm.
JS
$("#nav-icon").click(function () {
if ($(".logo-container").hasClass("border-change-image")) {
$(".logo-container").removeClass("border-change-image");
$(".container-fluid").removeClass("border-change-header");
} else {
$(".logo-container").addClass("border-change-image");
$(".container-fluid").addClass("border-change-header");
}
});

use intro.js on bootstrap dropdown element

I cannot figure out how to use intro.js on dropdown elements.
I found a similar question with no answer there: IntroJS Bootstrap Menu doesnt work
If you want to reproduce the error, follow these steps:
http://recherche.utilitaire.melard.fr/#/carto
You have to click on "Aide" (The green button on the top right), the problem occurs for the second step. on the change event, I do:
$scope.ChangeEvent = function (e) {
if (e.id === 'step2') {
document.getElementById('step1').click();
}
console.log("Change Event called");
};
When debugging, everything is working like a charm until that function end: _showElement
After that, I get lost in JQuery events, and the dropdown is closed...
If you want to reproduce, just add a breakpoint at the end of the _showElement function and you will understand what I mean...
Here a clearer solution
function startIntro(){
var intro = introJs();
intro.setOptions({
steps: [
{
element: "#mydropdown",
intro: "This is a dropdown"
},
{
element: '#mydropdownoption',
intro: "This is an option within a dropdown.",
position: 'bottom'
},
]
});
intro.onbeforechange(function(element) {
if (this._currentStep === 1) {
setTimeout(function() {
$("#mydropdown").addClass("open");
});
}
});
intro.start();
};
$(document).ready(function() {
setTimeout(startIntro,1500);
});
Note the setTimeout with no second argument (milliseconds) allows you to queue the function on event loop and run it after all events were processed (including the click closing the dropdown), also, it is better to add the class open to the dropdown if you want to set it to open state
In your template i.e. in
/views/nav/body-create.html
You have a code where ng-disabled is based on !currentPath.name. And the value of currentPath.name is null. Try inspecting the value on the following element. You will see that it is null.
<button class="dropdown-toggle btn btn-sm btn-default no-radius" ng-disabled="!currentPath.name">
Niveau{{currentPath.level?": "+currentPath.level:""}} <strong><b class="caret"></b>
</strong>
</button>
Make sure you have proper name or use different condition - I am not sure what you are trying to do with the condition.
Proof: Inspect the above element in chrome debugger at your recherche.utilitaire.melard.fr/#/carto link. Type the following in console and hit enter.
$scope.currentPath.name='Hello You';
And your "Niveau" menu starts working.
I found a workaround, it's quite ugly, but does the job:
$scope.ChangeEvent = function (e) {
if (e.id === 'step2') {
document.getElementById('step1').click();
setTimeout(function () {
document.getElementById('step2').style.display = 'block';
}, 500);
}
console.log("Change Event called");
};
I set the display attribute to block just after the click event I added in the change event
When clicking executing the click on the element 1, I noticed that jquery set the state of the style.display of the element 2 to '', so I wait a bit after clicking in order to set it back to 'block', I know it's ugly, but I didn't find anything better at the time
This happens because of the fixed position..
By using CSS, change the position for the parent item from fixed to absolute and it works perfectly.
For example:
position of .sidebar is fixed, leave it like that.
change position for .sidebar.introjs-fixParent to absolute.
Hope it helps you

Toggling one thing with two different elements

In my previous question I asked about how can I toggle a textarea with a paragraph. I got the answer. Now I want to do the opposite of it. First I was showing the already hidden textarea + 2 buttons by a click of a hyperlink. Now on the click of one of the buttons I want to hide the text + 2 buttons and show the paragraph that was first already shown.
I have tried this JS so far but it's not working:
$(document).ready(function () {
$(".no_link").click(function (e) {
e.preventDefault();
});
$(".edit_offer").on('click', function () {
toggleEditPanel($(this));
});
$("#cancel_edits").on('click', function () {
$(this).closest("button").hide();
$(this).closest("textarea").hide();
$(this).closest("p.content").show();
});
});
function toggleEditPanel(link) {
link.parent().parent().parent().find("textarea").toggle();
link.parent().parent().parent().find("button").toggle();
link.parent().parent().parent().find("p.content").toggle();
}
But its not working. How can I solve this error?
If I am trying to call the function toggleEditPanel() again. Its not working then aswell.
You can find the markup in the fiddle. Here's the fiddle.
UPDATE 1:
Just came up with a solution. I can use the $.siblings() function to toggle the elements beside the button. Still, is there any better solution?
Here's the code that I came up with:
$("#cancel_edits").on('click', function () {
$(this).hide();
$(this).siblings("button").hide();
$(this).siblings("textarea").hide();
$(this).siblings("p.content").show();
});
UPDATE 2:
The problem in the above code is that if there are more than one panels like this then the code is not working. How can I solve that issue aswell?
You are using Id for selector $("#cancel_edits") .
Id selectors returns only first element , so if there are multiple pannel it will work only for first.
Instead give some class name and use it for selector. Further you can use chaining and caching in your code for better performance.
$(".cancel_edits").on('click', function () {
var elm=$(this);
elm.add(elm.siblings("button,textarea")).hide();
elm.siblings("p.content").show();
});
I would recommend referencing your elements by ID:
$("#cancel_edits").on('click', function () {
$('#save_edits').hide();
$('#edited_content').hide();
$(this).hide();
$("p.content").show();
});
JSFiddle
The great thing about using IDs is that you are guaranteed they are unique - no need to use closest() to find the element you want. If, however, you're using classes instead, closest() might be necessary or helpful.

Rebind .toggle() event after unrelated event?

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.

jQuery Checkbox/Target _Blank

I have the following jQuery on my website:
$(function() {
$('#newtab').toggle(function() {
$('a').attr('target', '_blank');
},
function() {
$('a').removeAttr('target');
});
});
The code is for a checkbox that toggles the target of links on my page (when checked, links open in a new tab (target="_blank"), otherwise, they open in the same page.
I have two issues:
I want to make it so only links in a particular div are affected by the toggle (I essentially just don't want links in my menu to be affected by it).
When clicking the checkbox, the check is never shown for some reason. I have <input type="checkbox" id="newtab" /><label for="newtab">Open links in new tab</label>
on my page which shows the checkbox (unselected). When I click on it, it changes the target attribute, but the checkbox never appears to be selected; it still shows the empty box. Clicking the checkbox again removes the target attribute as expected.
Thanks.
This should solve your problem: http://jsfiddle.net/UJMgQ/2/
$(function () {
$('#newtab').click(function () {
if ($(this).is(':checked')) {
$('#wanted a').attr('target', '_blank');
} else {
$('#wanted a').removeAttr('target');
}
});
});
To limit the a's that are selected just change #wanted to what ever div(container) the a's you want are in. It works like a css selector.
For part 1: $('.divYouWant a').attr(...) will limit it, just like a CSS selector would.
For part 2: According to the docs of toggle() "The implementation also calls .preventDefault() on the event, so links will not be followed and buttons will not be clicked if .toggle() has been called on the element.". If you don't want that, either use .click(), or just set $('#newtab').checked equal to one in the selected function, and 0 for the unselected function.
Try: $('#mydiv').find('a').attr('target', '_blank');
I think toggle wants you to return true to make the click event propagate to the checkbox. Not sure, but checking the docs may be in order here...
Nevermind, docs say that toggle prevents propagation. Perhaps use something like $.change() instead, and use the value of the checked property to set the values you want.

Categories

Resources