accordion display to find the next div - javascript

Progress: https://jsfiddle.net/zigzag/jstuq9ok/4/
There are probably a few ways to do this but I have a class called sub that I add to hide a 'nested' Div and then use jQuery to toggle the Glyphicon along with display the 'nested' Div. Some asks:
$('.menu-toggle').click(function() {
$(this).find('span').toggleClass('glyphicon-menu-down').toggleClass('glyphicon-menu-up');
//How to do something like this to traverse the click and structure $(this).parent.find('.sub:first-child').toggle();
$('.sub').toggle();
$('.subsecond').toggle();
});
The nested team structure intended is this:
Adam
Lily
2.1 Sen
2.1.1 Tank
2.2 Another Sen
Justin
What I'm trying to do do is have this traverse through the DOM based on where the click happens to display the sub section under there. I have the content coming from a source system so can't hard code class directly.
Let me know if you have any question.

You can find the next div by using .closest('.row') to get the parent .row and .next('.row') to get the next .row of the parent .row if it has class or not using hasClass() so you can use
$('.menu-toggle').click(function(e) {
e.preventDefault(); // prevent <a> to redirect to the top of the page
$('.row:not(.sub):not(.subsecond)').not($('.sub').prev('.row')).not($('.subsecond').prev('.row')).not($(this).closest('.row')).find('span.glyphicon-menu-up').toggleClass('glyphicon-menu-down glyphicon-menu-up');
$(this).find('span').toggleClass('glyphicon-menu-down glyphicon-menu-up');
var Nextrow = $(this).closest('.row').next('.row'); // get the next row
if(Nextrow.hasClass('sub')){ // if next row has class sub
$('.sub').not(Nextrow).hide(); // hide all sub but not this one
Nextrow.slideToggle(function(){
if($(this).is(':hidden')){ // check if the .sub is hidden
$('.subsecond').hide(); // hide subsecond
$('span.glyphicon-menu-up').toggleClass('glyphicon-menu-down glyphicon-menu-up'); // toggle arrows to the down
}
}); // toggle this sub row
return false;
}
if(Nextrow.hasClass('subsecond')){ // if next row has class subsecond
$('.subsecond').not(Nextrow).hide(); // hide all subsecond but not this one
Nextrow.slideToggle(); // toggle this subsecond row
return false;
}
});
See Example

Related

Toggling same class names except for one (JavaScript)

I am trying to prevent a paragraph element with a class attribute of 'show' from toggling away on the click event on updateButton. I've tried if else statements but to no avail.
I'm essentially trying to create an editing state when I click update button and all the text on the bottom of these buttons need to show (the paragraph elements). Though there is one button with text underneath it already which I want to prevent from toggling the class .hide.
The other buttons already have the .hide class attribute on them already so when toggled from the click event, they appear.
TLDR: I want to prevent the one paragraph element with no .hide class attribute from toggling it on when I toggle all the other paragraph elements in the .risk-text container.
// select indicator div
const riskIndicator = document.getElementById("Risk__indicator");
// select update button
const updateButton = document.getElementById("Update_button");
// Indicator buttons
const indicatorButton = document.getElementsByClassName("Risk_indicator_button");
// Indicator 'check every..' text
const checkIndicatorText = document.querySelectorAll(".risk-text");
// select update button
updateChange: updateButton.addEventListener("click", function (event) {
riskIndicator.classList.toggle("active");
});
// If statement to check whether the Risk Indicator is active to apply background changes
editState: updateButton.addEventListener("click", function(el) {
[].map.call(document.querySelectorAll('.risk-text'), function(el) {
// loop through text indicator elements checking to see if it's got a hidden class attribute
el.classList.toggle('hide');
});
});
Depending on your use case:
If you want to exclude it only once, and then toggle this element with others, do something like:
editState: updateButton.addEventListener("click", function(el) {
[].map.call(document.querySelectorAll('.risk-text:not(.hide)'), function(el) {
// loop through text indicator elements checking to see if it's got a hidden class attribute
el.classList.toggle('hide');
});
});
If you want to leave the "ember" element alone, then
editState: updateButton.addEventListener("click", function(el) {
[].map.call(document.querySelectorAll('.risk-text:not(.low_risk_text__wrap--risk-middle-amber)'), function(el) {
// loop through text indicator elements checking to see if it's got a hidden class attribute
el.classList.toggle('hide');
});
});
You can also add new class, like "spareMe", and exclude it with .not()

how to make node become selectable (add active class).?

Can you please tell me how to make node become selectable (add active class) automatically? When user select any node it become selectable, in other word it become blue.
But now when I click by child button i got the child of "b", but it is not selectable. Can we make "b" selectable? When a user clicks on "child button", can we move this active class by using next and previous button? It goes to top and bottom when user click next and previous button.
http://jsfiddle.net/fuu94/44/
$('#child').click(function () {
for(i in $('#tree').jstree(true).get_node('b').children){ alert($('#tree').jstree(true).get_text($('#tree').jstree(true).get_node('b').children[i.toString()]));
}
});
To set unset active on next and pre click:
$('#next').click(function () {
if($('.jstree-clicked').closest('li').next().length)
$('.jstree-clicked').removeClass('jstree-clicked').closest('li').next().find('a:eq(0)').addClass('jstree-clicked')
});
$('#pre').click(function () {
if($('.jstree-clicked').closest('li').prev().length)
$('.jstree-clicked').removeClass('jstree-clicked').closest('li').prev().find('a:eq(0)').addClass('jstree-clicked')
});
Demo
You can make 'b' selectable by using select_node(node). http://jsfiddle.net/23NAG$('#tree').jstree(true)
.select_node('b'); from http://www.jstree.com/docs/interaction/
The next and previous can use the same select_node using the child ids.

Conditional jQuery Toggle Function

I want to hide and show list items based on their attributed class.
The problem is that certain list items have multiple classes. So if I toggle one class then toggle another, any items with both selected classes will be removed.
I created a demo of my problem: http://jsfiddle.net/a4NkN/2/
Here's the JS CODE:
$('#easy').click(function(){
$(this).toggleClass( "checked" );
$('.easy').toggle();
});
$('#fun').click(function(){
$(this).toggleClass( "checked" );
$('.fun').toggle();
});
$('#silly').click(function(){
$(this).toggleClass( "checked" );
$('.silly').toggle();
});
If you select the "Easy" and "Fun" buttons, Boating will disappear.
How can I get Boating to stay?
This might be a good point to start from. Although you can do this cheaper and cleaner, that gives the idea:
Use an array to save the status of your selection buttons and one corresponding to hold the class names. Whenever your select buttons get clicked, you set all your elements invisible and reset those visible again, that are already selected by other buttons or the currently clicked, which is all saved in the switcher array.
//saves whether button is active
var switcher = [false, false, false];
//holds your classes selectable
var classes = ['easy', 'fun', 'silly'];
$('.toggler').click(function () {
// toogle the select button and save status
var x = $(this).hasClass('checked');
switcher[$(this).data('switch')] = !x;
$(this).toggleClass("checked", !x);
// iterate through your elements to set them active if needed
$('li').each(function () {
var cur = $(this);
cur.addClass('hidden');
$.each(switcher, function (index, data) {
if (data && cur.hasClass(classes[index])) {
cur.removeClass('hidden');
}
});
});
});
Whole solution in this fiddle: http://jsfiddle.net/BMT4x/
You cannot unconditionally toggle elements based on a click on one of the button filters if it is possible for an element to satisfy multiple filters at once. The correct approach is a little more involved.
Since your checked class means that only items corresponding to that button should be shown, do exactly this: toggle them based on the current status of the button. The items should be shown if and only if the corresponding button is checked as a result of clicking it.
$('#easy').click(function(){
$(this).toggleClass( "checked" );
$('.easy').toggle($(this).is(".checked"));
});
This code uses the last version of .toggle, the one accepting a boolean argument.
It can also be done more succintly:
$('.easy').toggle($(this).toggleClass( "checked" ).is(".checked"));

Fundamentally doing something wrong with function calls. Functions do work in the console

This is a solid, proper syntax set of functions, and for the life of me I can't figure out why, but the function ServiceHover() will not run unless I trigger it manually in the console, while it's almost exact equal CategoryHover() runs perfectly each time. It has to be something about the way that I'm calling the functions, and clearly there's something about functions that I fundamentally missed in javascript, because this happens to me often, where I'm unsure why my functions are not executing.
I keep my code all very well commented, so I shouldn't have to explain the functions's purposes, and furthermore, this is more a question of the fundamental execution of the functions rather than their inner functionality. Each function does work if called manually in the console.
//this function generates the content of the page based on which category the user selects,
//which services the user selects, and help maneuver through each stage of the feature selection
//so that the QuoteEngine function can display the user's selected hour count, price per hour
// and total cost of the needed service so that the user can see very clearly what services
//he is getting and where every dollar of his total cost is coming from so that the user can
//make a well informed purchase decision, and be able to clearly understand the services offered
//and related pricing.
$(document).ready(function () {
function BasicDropdown() {
//hide the drop-downs to begin with
//hide element with class dropdown-category
$(".dropdown-category").hide();
//hide element with class dropdown-service
$(".dropdown-service").hide();
//when the category list title is hovered over, show the category drop-down list
//when element with class category is hovered, do this:
$(".category").hover(function () {
//show the list
$(".dropdown-category").show();
//when element with class category is no longer hovered, do this:
}, function () {
//hide the list
$(".dropdown-category").hide();
});
//when the service list title is hovered over, show the service drop-down list
//when element with class service is hovered, do this:
$(".service").hover(function () {
//show the list
$(".dropdown-service").show();
//when element with class service is no longer hovered, do this:
}, function () {
//hide the list
$(".dropdown-service").hide();
});
}
//change the selected service based on an id input
//create a function to change the selected service
function ChangeService(id) {
//clear the service list element
$(".dropdown-service").empty();
//make the name inside the service drop-down title show the new title
$("#ServiceOutput").text(ServiceArray[id][0][1]);
//loop through the chosen section of the service array for as many times as the
//section is in length
for (var i = 0; i < ServiceArray[id].length; i++) {
//each loop, append a paragraph element with a data key equal to the current
//loop count, an id equal to the id of the array area based on the loop count,
//and also insert the element's text according to that loop count also.
$(".dropdown-service").append('<p data-key="' + i + '" id="' + ServiceArray[id][i][0] + '">' + ServiceArray[id][i][1] + "</p>");
}
//set the variable "Category" to be equal to the chosen id.
Category = id;
}
function CategoryHover() {
//make the category drop-down list open and show its list of services
//when the user hovers over an element in the category drop-down, do this:
$(".dropdown-category > p").hover(function () {
//hide the welcome wrapper
$(".welcomeWrapper").hide();
//set the variable "thisKey" based on the value of the data "key" attached
thisKey = $(this).data("key");
//create a variable "outputList" and assign a value to it from "CategoryArray"
outputList = CategoryArray[thisKey];
//set the title of the category drop-down lists title to the currently hovered text
$("#CategoryOutput").text($(this).text());
//call the ChangeService function and pass the variable "thisKey" into it
ChangeService(thisKey);
//show the service drop-down list
$(".dropdown-service").show();
//show the ListOutput element (this shows a short description of the hovered element)
$(".ListOutput").show();
//append the variable "outputList" as the value of a paragraph element
$(".ListOutput").append('<p>' + outputList + '</p>');
}, function () {
//hide the service drop-down list
$(".dropdown-service").hide();
//empty the ListOutput element
$(".ListOutput").empty();
//hide the ListOutput element
$(".ListOutput").hide();
//show the welcome wrapper again
$(".welcomeWrapper").show();
});
}
function ServiceHover() {
//make the service drop-down list open and show the list of services for the category
//when the user hovers over an element in the service drop-down, do this:
$(".dropdown-service > p").hover(function () {
//hide the welcome wrapper
$(".welcomeWrapper").hide();
//set the variable "thisKey" based on the value of the data "key" attached
thisKey = $(this).data("key");
//create a variable "outputList" and assign a value to it from "CategoryArray"
outputList = ServiceArray[Category][thisKey][2][0];
//show the ListOutput element (this shows a short description of the hovered element)
$(".ListOutput").show();
//append the variable "outputList" as the value of a paragraph element
$(".ListOutput").append('<p class="blue">' + outputList + '</p>');
}, function () {
//empty the ListOutput element
$(".ListOutput").empty();
//hide the ListOutput element
$(".ListOutput").hide();
//show the welcome wrapper again
$(".welcomeWrapper").show();
});
}
BasicDropdown();
CategoryHover();
ServiceHover();
//initiate
ChangeService(0);
});
What am I doing wrong with these calls?
JS Fiddle: http://jsfiddle.net/gbJcg/4/
Note: I mentioned in my question but for some reason the update didn't show up, that all of the arrays should be assumed defined. I'll now include them to remove confusion, but it will make the scripts extensively long
Added detail: ChangeCategory works. ChangeService doesn't appear to. If I copy and paste ChangeService, however, in the console, and call it, in the console, the functionality works perfectly. Does that help? I have no idea what I'm doing wrong here...
Well what I know is, since your dropdown-service is added dynamically, you need to delegated it to closest static parent present in the document which is dropdown-service in your case.
$(".dropdown-service").on("mouseenter" ,"p",function () {
..
});
$(".dropdown-service").on("mouseleave" ,"p",function () {
...
});
Since live is deprecated in latest version of jQuery you need to use on delegated event and break the hover into mouseenter and mouseleave function.
fiddle here
Check your console, you have Uncaught ReferenceError: ServiceArray is not defined
This Exception is thrown and the rest of the program is not ran
EDIT: after fiddle changed with the missing Arrays initialization is seems like the code works. I added alerts in the begining of 2 functions to make sure they are called (see http://jsfiddle.net/gbJcg/3/)
EDIT #2:
The call to $(".dropdown-service > p").hover(...) is done when you do not have any elements that respond to ".dropdown-service > p" selector, They are probably added later via ajax or some other html manipulation that is done by js
You should use the equivalent for jquery live instead:
$(document).on("mouseenter",".dropdown-service > p",function() {
....
});
$(document).on("mouseleave",".dropdown-service > p",function() {
....
});

how to do a group "unhighlight" on highlighted rows in a table

I have a table in which any time a user clicks on one of the rows it highlights the row. However as of if I have multiple rows highlighted i have to click each individual highlighted row to get rid of the highlight. I want to make it so when an individual is not clicking on the table it will get rid of the highlight on all the rows. This is the code that I am using.
//this highlights the table that has been clicked on
$('.tr_highlight').live('click',(function () {
$(this).parent().toggleClass("tr_highlight_ed");
}));
How do I get it to unhighlight(if thats a word) when clicking anywhere but the table?
You really need to post an example of the rendered markup. You don't want to do a toggleClass, you would do a removeClass selecting the parent nodes...
Assuming the following markup...
<body>
...
<table id="myTable">...</table>
...
</body>
You could bind the following..
$('body').click(function(evt){
//evt.target is what was clicked on, which bubbles up to body
//if it's anything inside #myTable, you will get the #myTable
var el = $(evt.target).closest('#myTable');
//if you didn't get #myTable, you clicked outside the table
//remove the given class from all the tr's
if (!el.length) $('#myTable .tr_highlight_ed').removeClass('tr_highlight_ed');
});
$(document).bind('click.table', function (e) {
if ( $("#my-table").has(e.target).length === 0 ) {
$("#my-table").find("tr").removeClass('tr_highlight_ed');
}
});
Everytime a user clicks anywhere on the page, it will check if the element that was clicked is inside the table; if not, we unhighlight all the rows.

Categories

Resources