Capture navigation text on click of item - javascript

I'm trying to capture using jQuery or Javascript the text value from parent classes in a site navigation
Example navigation:
Level 1 - bish
Level 2 - bash
if I click on Level 2 - 'bash' I'd like to capture level 1 text 'bish' into variable
An example of code I'm working with
`<li class="class1">
<a href="/bish" class="class2">
<div class="class3">
<p class="class4 level1">bish</p>
</div>
</a>
<ul class="class5">
<div class="class4">
<li class="class6">
<div class="class7">
bash
</div>
</li>
</ul>
</div>
</li>`
Id be grateful for any help.
I'm expecting that the value bish will output to a variable. The challenges I'm having is that because it's navigation the same class values are being used for other navigation.

For example:
$('.level2').click(function(e) {
e.preventDefault()
let level1 = $(this).closest('.class1').find('.level1').text();
console.log(level1);
});

Related

Bootstrap 4 change accordion behaviour

I'm using HTML templates, which are based on Bootstrap 4.3.1 to present my students with learning content. In the current templates, all accordion panels are closed on page load and each accordion panel can be opened regardless of how many others have also been opened.
A working example can be found on this CodePen: https://codepen.io/hagelslag1001/pen/MWGeZJr
The HTML code is as follows:
<h2>Accordion: Group of 2</h2>
<p class="small">Accordion: start copy</p>
<!-- Accordion headings should be changed to respect page hierarchy -->
<div class="accordion shadow mb-5">
<div class="card">
<div class="card-header">
<h2 class="card-title">
Accordion 1 of 2
</h2>
</div>
<div class="collapse">
<div class="card-body">
<p>Insert Accordion 1 of 2 content here.</p>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h2 class="card-title">
Accordion 2 of 2
</h2>
</div>
<div class="collapse">
<div class="card-body">
<p>Insert Accordion 2 of 2 content here.</p>
</div>
</div>
</div>
</div>
<p class="small">Accordion: end copy</p>
Is it possible to change this default behaviour so that only one panel can be opened at a time? (i.e. as soon as a new panel is opened, the previously opened panel will automatically close)
The Bootstrap examples use (data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne") to accomplish this for the accordions in these templates
I can't figure out how to accomplish this, since the HTML code for the accordions in these templates look different than the Bootstrap 4 examples, which use either an a or button tag to trigger the collapsible event.
Here is a simpler answer based on your CodePen: https://codepen.io/mrtcntn/pen/MWGeZdP
According the Bootstrap 4 docs, you need id="accordion" on the top level div and you don't need to give ids like id="accordion_1" and id="accordion_2".
Therefore I removed the first portion from the JS and added id="accordion" at line 18 in the HTML.
You can do this by letting javascript check for active classes and only allowing one at the time. Here's a simplified example.
// DOM here
let nav = document.querySelector(".nav");
// Handlers here
const clickHandler = function (e) {
if (e.target.classList.contains("nav__link")) {
const link = e.target;
const siblings = link.closest(".nav").querySelectorAll(".nav__link");
link.classList.toggle("active");
// removes all actives except for the clicked one
siblings.forEach((el) => {
if (el !== link) el.classList.remove("active");
});
}
};
// Listeners here
nav.addEventListener("click", clickHandler);
body {
font-family: sans-serif;
}
.nav__link {
display: block;
width: 100%;
}
.active {
background: #0f0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<div class="nav">
<ul class="nav__links">
<li class="nav__item">
<a class="nav__link" href="#accordeon--1">Accordeon 1</a>
</li>
<li class="nav__item">
<a class="nav__link" href="#accordeon--2">Accordeon 2</a>
</li>
<li class="nav__item">
<a class="nav__link" href="#accordeon--3">Accordeon 3</a>
</li>
<li class="nav__item">
<a class="nav__link" href="#accordeon--4"
>Accordeon 4</a
>
</li>
</ul>
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>

How Can I expand the list and choose dynamic value.

I'm trying to find out the solution how to get the target of Add New from Prod2 from the code below.
To get this target at first I have to click on ptv-icon ptv-collapse-icon. This is possible using XPATH but each time when I run the script xpath is changing.
Does it possible to use any method to localize Add New directly.
Another problem is that: Add New element is only visible after I will click on ptv-icon ptv-collapse-icon.
<li class="ptv-listitem" data-id="1">
<div class="ptv-item">
<span class="ptv-icon ptv-expand-icon"></span>
<span class="ptv-text">
<span class="tree-text">Prod1</span>
<span class="tree-counts"></span>
</span>
</div>
</li>
<li class="ptv-listitem" data-id="2">
<div class="ptv-item">
<span class="ptv-icon ptv-collapse-icon"></span>
<span class="ptv-text ptv-selected">
<span class="tree-text">Prod2</span>
<span class="tree-counts"></span>
</span>
</div>
<ul class="ptv-list ptx-expanded">
<li class="ptv-listitem" data-id="-1">
<div class="ptv-item">
<span class="ptv-text">
<span class="tree-text">**Add New**</span>
<span class="tree-counts"></span>
</span>
</div>
</li>
</ul>
</li
(Assuming you're using Java) You should try using xpath with text which would never be change as below :-
//to click on prod2
driver.findElement(By.xpath(".//li[contains(.,'Prod2')]//span[#class = 'ptv-icon ptv-expand-icon']").click();
//to click on add new
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath(".//li[contains(.,'Add New')]"))).click();
You can select the element by the 2 classes of ul and one class of the span:
WebDriver.findElement(By.cssSelector("ul.ptv-list.ptx-expanded span.tree-text")).click()
This means select a span element having tree-text class, which is inside an ul elemenent having both ptv-list and ptx-expanded classes.

AngularJS/CSS Move one div out and another in on the same modal

I am working on an app and want to use AngularJs for doing this :-
<div class="main">
<div class="one">Content 1 here ...</div>
<div class="two">Content 2 here ...</div>
</div>
div one contains a button which on click brings out div two and replaces div one.
Can anyone help regarding this, (Do i need to use ng-Animate or a better CSS trick) ?
EDIT: I will make it a little more clear
Div one has a list and a button called ADD which on click brings a list which is in div two, I select what to add and then submit, the list in div one appears updated.
Try this JS FIDDLE
HTML
<div ng-app="myApp">
<div ng-controller="listCtrl">
<div class="one">
<ul>
<li ng-repeat="list in lists">{{list}}</li>
</ul>
<button ng-click="showOptions = !showOptions">{{showOptions?'Hide':'Show'}} Options</button>
</div>
<div class="two" ng-show="showOptions">
<ul>
<li ng-repeat="list in options" ng-click="add($index)">{{list}}</li>
</ul>
</div>
</div>
Controller
var myApp = angular.module('myApp',[]);
myApp.controller('listCtrl',function($scope){
$scope.lists =['Monday','Tuesday'];
$scope.options =['Sunday','Saturday'];
$scope.add = function(index){
$scope.lists.push($scope.options[index]);
$scope.options.splice(index,1);
};
});

how to show li tag based on index value in angularjs

i have a html like this,
<div class="main">
<ul>
<li ng-repeat='save in saves'>
<h3>{{save.name}}</h3>
<div >
<ul>
<li ng-repeat='story in stories'>
<div ng-show="story.display"><label>welcome</label></div>
<div ng-show="!story.display"><input type="text"></div>
</li>
</ul>
</div>
<div ng-click="add()">Click</div>
</li>
</ul>
<div ng-click="theme()">Add theme</div>
</div>
my contoller like this
$scope.saves=[];
$scope.stories=[];
$scope.theme=function()
{
$scope.saves.push({name:'joseph',name:'john',name'peter'});
};
$scope.add=function()
{
$scope.stories.push({display:'false'});
};
Here i am doing this ,
When user click on addtheme button i am pushing name into saves (Array) and then repeating it with li tag so out put like this
joseph
click
john
click
peter
click
so when again user click on click , i want to show only one textbox for specific clicked li..but here what happened , when i click on click button it is showing three text box for three li tag....
How to open specific textbox?
your can replace
<div ng-show="!story.display"><input type="text"></div>
to
<div ng-hide="story.display"><input type="text"></div>

How to access the dom by knowing the value of a node && Getting the index of accordion by just knowing value

I have 2 questions:
1) Since I have similar structure for the html contents and the only difference is that class title contents are different. I tried using $(div .title:contains("cat")) also
$(div .title).text()="cat")
2)How can I get the index of the accordion by just checking the $(div a) contents are required ones. I tried using $(div a).text()=="cat"
Check the codes here:
HTML1 contents
<div class="mod moduleselected" id="mod969">
<div class="content module moduleselect">
<div class="hd" ><div class="inner">
<div class="title">cat</div>
<ul class="terminallist"></ul>
<ul class="buttons">
<li class="help"></li>
<li class="show" ></li>
</ul>
</div>
</div>
</div>
<div class="mod moduleselected" id="mod969">
<div class="content module moduleselect">
<div class="hd" ><div class="inner">
<div class="title">rat</div>
<ul class="terminallist"></ul>
<ul class="buttons">
<li class="help"></li>
<li class="show" ></li>
</ul>
</div>
</div>
</div>
<div class="mod moduleselected" id="mod969">
<div class="content module moduleselect">
<div class="hd" ><div class="inner">
<div class="title">dog</div>
<ul class="terminallist"></ul>
<ul class="buttons">
<li class="help"></li>
<li class="show" ></li>
</ul>
</div>
</div>
</div>
Accordian
<div id="dia">
<div id="dialog" title="Detailed FeedBack ">
<div id="accordion">
<h3>dog</h3>
<h3>cat</h3>
<h3>rat</h3>
</div>
</div>
</div>
Javascript
$('div .title').mouseover(function() {
if($("div a").text().indexOf("cat")!=-1)
{
$("#accordion").accordion("activate", 1);
}
$('div .title').mouseleave(function(){$("#accordion").accordion("activate", -1); });
});
Here is what I am trying to do with this javascript code. When I mouse over the cat contents I want the accordion with cat contents to open. And when I leave it to close the accordion selection.
When I hover my mouse over the html contents cat ,rat. It should side by side open the accordion button of those contents. Example: I hovered over rat (of html contents) I should see accordion rat open (or active i.e. contents visible).
Updated (see demo)
It sounds like you want something like this: when a content section is hovered over, find the title of that section, match its text against the text of the <a> elements in the accordion, and activate that section:
$(function() {
$("#accordion").accordion();
var links = $('#accordion a').map(function() {
return $(this).text().trim().toLowerCase();
}).toArray();
$('div.content').mouseover(function() {
var title = $(this).find('div.title').text().toLowerCase();
var index = links.indexOf(title);
if (index != -1) {
$("#accordion").accordion("activate", index);
}
});
});​
P.S. jQuery does have a .hover() method for this as well.
It should be as succinct as the following (with potential minor tweaks):
$('.content .title').hover(function(e){
var index = this.textContent.split(/\W/)[1] - 1;
$("#accordion").accordion('activate', index);
});
​
Be careful with the HTML as this regular expression is overly simple in that it just grabs the last "word" which in the case of your example is a number. We subtract one to get a zero-based index. That will break if you add further text to the element.
See: http://jsfiddle.net/35yGV/

Categories

Resources