Select all elements between two known elements by CSS selector - css-selectors

I have two elements with defined ids having any html between them, for example:
<div id='d1'>Hello</div>
<!-- Here come any html code -->
<div>Example</div><hr/>Example
<div id='d2'>World</div>
Is there CSS selector that selects all the elements between #d1 and #d2?

Answer: No.
But you always have the option of JQuery:
$('#id').nextUntil('#id2')
Keep in mind, the .nextUntil method selects all elements in between, exclusive. To select the elements including the two elements, use this:
$('#id').nextUntil('#id2').andSelf().add('#id2')
<!DOCTYPE html>
<html>
<head>
<style>
.siblings * {
display: block;
border: 2px solid lightgrey;
color: lightgrey;
padding: 5px;
margin: 15px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$("li.start").nextUntil("li.stop").css({"color": "red", "border": "2px solid red"});
$("li.start1").nextUntil("li.stop1").andSelf().add("li.stop1").css({"color": "red", "border": "2px solid red"});
});
</script>
</head>
<body>
<p>Just selecting all elements in between, exclusive.</p>
<div style="width:500px;" class="siblings">
<ul>ul (parent)
<li>li (sibling)</li>
<li>li (sibling)</li>
<li class="start">li (sibling with class name "start")</li>
<li>li (the next sibling of li with class name "start")</li>
<li>li (the next sibling of li with class name "start")</li>
<li>li (the next sibling of li with class name "start")</li>
<li class="stop">li (sibling with class name "stop")</li>
</ul>
</div>
<p>Just selecting all elements in between, inclusive.</p>
<div style="width:500px;" class="siblings">
<ul>ul (parent)
<li>li (sibling)</li>
<li>li (sibling)</li>
<li class="start1">li (sibling with class name "start")</li>
<li>li (the next sibling of li with class name "start")</li>
<li>li (the next sibling of li with class name "start")</li>
<li>li (the next sibling of li with class name "start")</li>
<li class="stop2">li (sibling with class name "stop")</li>
</ul>
</div>
</body>
</html>
In my opinion, that's the easiest option.

Related

AngularJs If a parent element has class, hide child element

If in ng-repeat a parent div has "loaded" class i need to hide appropriate child element.
<div ng-repeat="item in array" class="loading loaded">
<div class="hide_it"></div>
</div>
.loaded .hide_it{
display: none;
}
CSS:
.loaded .hide_it {
display: none;
}

AngularJS 1.4, bootstrap multi level Accordion sample

I want to build a menu something like as below but I am not finding an appropriate sample utilising AngularJS 1.4, bootstrap & accordion.
Accordion is a must. Please advise.
menu1
menu2
submenu2.1
submenu2.2
sub-submenu2.2.1
sub-submenu2.2.2
menu3
I have added the code below. Style sheet is Bootstrap.css. Also some custom stylesheet used in project. Accordion menu elements should have different colours at each level of menu. Also the one selected should be displayed in different color. When we hover over elements it should display different color.
As per the below implementation I have 2 main level elements in menu. The first element is displaying proper accordion behaviour. Second element is always open.
No stylesheet is getting applied to either of the menu elements. Please advise.
HTML:
<script type="text/ng-template" id="menuTree">
<uib-accordion-group is-open="firstMenuItemStatus.isFirstOpen" is-disabled="firstMenuItemStatus.isFirstDisabled">
<uib-accordion-heading ng-if="c.pDtos">
{{c.name}}
</uib-accordion-heading>
<div ng-repeat="p in c.pDtos" ng-include="'smenuTree'"></div>
</uib-accordion-group>
</script>
<script type="text/ng-template" id="smenuTree">
<uib-accordion-group>
<uib-accordion-heading>
{{p.name}}
</uib-accordion-heading>
<div ng-show="p.aDtos" ng-repeat="a in p.aDtos">
<a ui-sref="crhDetail({ crhId : a.crhId})">{{a.name}}</a>
</div>
</uib-accordion-group>
</script>
<div class="menuSec" ng-controller="menuCtrl">
<uib-accordion close-others="true">
<div ng-repeat="c in menuTreeSet" ng-include="'menuTree'" >
</div>
</uib-accordion>
</div>
Custom CSS:
.menuSec {top: 80px;left: 0;right: 0;bottom: 0;}
.menuSec>ul {position: absolute;background:#2166b3;width:100%;}
.menuSec>ul>li, .secondLevelList>li, .thirdLevelList>li{position: relative;float: right;display:block;list-style: none;width: 100%;height: 40px;line-height: 44px;text-align: right;font-size: 12px;padding-right: 14px;box-shadow: 0 1px 0 #3A76C4;cursor: pointer;}
.secondLevelList, .thirdLevelList{width:220px;}
.secondLevelList>li, .thirdLevelList>li{width:220px;height:30px;line-height: 32px;float: right;list-style: none;}
.selected{height:auto !important;background:#135aa9;border-left: 3px solid #000033;border-bottom:none;box-shadow:none !important;}
.secondLevelList>.selected{background:#004388;}
.menuText{position:absolute;text-align:right;right:47px;}
.menuSec ul li:hover {background: #135aa9;border-left: 3px solid #000033;}
.menuSec ul li .fa {margin-left: 14px;line-height: 40px;}
.secondLevelList, .thirdLevelList{position:relative !important;float:right;display:block;border-top:1px solid #000033;}
.secondLevelList{margin-right:-14px;}
.thirdLevelList{margin-right:-24px;}
.secondLevelList>li{background:#0a4d99;border-bottom:1px solid #2a66a9;padding-right:24px;}
.selected>.secondLevelList>li:hover{background:#004388 !important;}
.secondLevelList>li:hover{background:#003b78;}
.thirdLevelList>li{background:#004388;border-bottom:1px solid #18589f;padding-right:34px;}
.thirdLevelList>li:hover{background:#003871 !important;}
.thirdLevelList>.selected, .thirdLevelList>.selected:hover{padding-right:10px;background-image:url(../images/NowWeAt.png) !important;background-position:right !important;background-repeat:no-repeat !important;}
.menuSecCT{width:80px;overflow:hidden;}
.menuSecCT .menuText{display:none;}
.menuSec ul li{padding-right:34px;}
.secondLevelList, .thirdLevelList{display:none;}}
Here is an example of multi-level (3 levels) UI Bootstrap accordion. You have to adapt to your needs.
This example is based on ng-include:
<script type="text/ng-template" id="menuTree">
<uib-accordion-group>
<uib-accordion-heading ng-if="menu.listChilds">
{{menu.label}}
</uib-accordion-heading>
<div ng-repeat="submenu in menu.listChilds" ng-include="'smenuTree'"></div>
</uib-accordion-group>
</script>
<script type="text/ng-template" id="smenuTree">
<uib-accordion-group>
<uib-accordion-heading >
{{submenu.label}}
</uib-accordion-heading>
<div ng-show="submenu.listChilds" ng-repeat="item in submenu.listChilds">
{{item.label}}
</div>
</uib-accordion-group>
</script>
<div ng-controller="MenuController">
<uib-accordion close-others="oneAtATime">
<div ng-repeat="menu in items" ng-include="'menuTree'"></div>
</uib-accordion>
</div>
http://plnkr.co/edit/ERURCsdvjhts1ujkYTrz?p=preview

Add class to accordion heading using AngularJS ui-bootstrap?

I want use ng-class to conditionally add a class to the accordion-heading, but it appears that not even setting a class explicitly on the element gets preserved. I have this:
<div accordion close-others="true">
<div ng-repeat="currItem in items" accordion-group>
<div accordion-heading class="myClass">My Heading {{$index}}</div>
<div class="accordion-inner myClass">asdf asdf asdf</div>
</div>
</div>
And the fiddle: http://jsfiddle.net/Zmhx5/1/
When I inspect the accordion heading element, the class myClass is nowhere to be found. Is there some reason I can't add classes to the accordion heading?
You can put the CSS inside the directive accordion-heading tags:
<accordion-heading>
<div class="myClass">My Heading {{$index}}</div>
</accordion-heading>
In Angular UI Bootstrap, they have created a directive for accordion-heading. Template for this is written in ui-bootstrap-tpls.js. Try to modify directive for accordion-heading.
I ran into the same issue trying to conditionally apply a background color to the heading with ng-class. This is a bit of a workaround, but it does the trick.
First we need to remove the padding from the heading. If you inspect it, you'll see that it generates a div with a .panel-heading class and a padding: 10px 15px (see note below). The padding is what causes issues when trying to apply a background to a nested div, so lets remove it.
.panel-heading {
padding: 0;
}
Now we can add our nested div and give it the same padding to get back our previous look.
<accordion-heading>
<div class="myClass" style="padding: 10px 15px">My Heading {{$index}} </div>
</accordion-heading>
Here's the updated jsfiddle
Note my code above is from a different version of ui-bootstrap. The classes were slightly different in this jsfiddle, so you will see a slightly different solution. The concept, however, is the same.
you could just apply your CSS to an outer div like this:
HTML:
<div ng-app="myApp" ng-controller="MyCtrl">
<div accordion close-others="true">
<div class="myClass" ng-repeat="currItem in items" accordion-group>
<div accordion-heading>
<div>My Heading {{$index}}</div>
</div>
<div class="accordion-inner">asdf asdf asdf</div>
</div>
</div>
</div>
CSS:
.myClass {
background-color: gray;
color: black;
}
.accordion-inner {
background-color: green;
color: black;
}
JS:
angular.module("myApp", ['ui.bootstrap'])
.controller("MyCtrl", function ($scope) {
$scope.items = [{}, {}, {}, {}];
});
then, change it to use ng-class and it should work just fine
pd: (Sorry about the bad english)

How to change the class on one div while hovering over another div with AngularJS?

I want to change the class of one div while hovering over another div using AngularJS directives. Here is what I have so far http://jsfiddle.net/E8nM5/38/
HMTL
<div ng-controller="Ctrl" ng-app>
<div ng-class="my-class">This div will change class when one hovers over bottom DIV </div>
<br/>
<div class="hover-div" ng-mouseenter="my-class = 'highlight'" ng-mouseleave="my-class = 'lowlight'">HOVER OVER ME TO CHANGE THE UPPER DIV's CLASS</div>
</div>
CSS
div.highlight {
padding: 10px;
background: red;
color: white;
}
div.lowlight {
padding: 10px;
background: blue;
color: white;
}
div.hover-div {
padding: 10px;
background: green;
color: white;
}
JS
function Ctrl($scope){
}
Any ideas?
Change my-class to myclass (i.e. the dash causes problem).
<div ng-controller="Ctrl" ng-app>
<div ng-class="myclass">This div will change class when one hovers over bottom DIV </div>
<br/>
<div class="hover-div" ng-mouseenter="myclass = 'highlight'" ng-mouseleave="myclass = 'lowlight'">HOVER OVER ME TO CHANGE THE UPPER DIV's CLASS</div>
</div>
Updated: the reason my-class isn't allowed in the expression is because AngularJS treats the dash as minus symbol and tries to parse it that way. Apparently, it can't parse the statement my - class = 'highlight'. Unfortunately, after reading AngularJS parser code, I can't find a way to "help" it distinguish between dash and minus.
You need to remove the hyphen from my-class so it will work properly in your Controller. Other than that it looks like you have it mostly done. Here's a little snippet - I also added it as text in the div so you can see it change
Your HTML File:
<div class="{{myClass}}"> {{myClass}} </div>
<div class="hover" style="height:50px; width:50px; border:1px solid black;" ng-mouseleave="myClass='test'" ng-mouseenter="myClass='hola'"> </div>
Controller
function Ctrl($scope){
$scope.myClass="test";
}

Vertical inline-block?

Currently I have something like this. The "Page" and "Row" elements are created dynamically using javascript.
The problem rises when there are multiple Pages, and a Row in the Page 1 is deleted, for example. The empty space should be filled by the element that is below, if the empty space is at the end of the page, then the first element of the next page should fill the empty space, and so on. At the end it should look like this.
I can solve this rearranging/recreating the entire PageCont.
Is there a way I can achieve this using pure CSS? So the rearranging would be handled by the rendering engine of the browser.
Something like this inline-block but with vertical direction.
Any help is highly apreciated.
​HTML:
<div class="PageCont">
<div class="Page">
<div class="Row">1</div>
<div class="Row">2</div>
<div class="Row">3</div>
<div class="Row">4</div>
</div>
<div class="Page">
<div class="Row">5</div>
<div class="Row">6</div>
<div class="Row">7</div>
<div class="Row">8</div>
</div>
<div class="Page">
<div class="Row">9</div>
</div>
</div>​
CSS:
.PageCont
{
height: 300px;
width: 350px;
border:2px solid red
}
.Page
{
float:left;
margin-left:10px;
}
.Row
{
height:50px;
width:50px;
background-color:blue;
color:white;
margin-top:10px;
}
​
The operation could be successfully performed trivially if it included horizontal wrapping, with plain simple CSS. However since this case involves vertical wrapping javascript be necessary with your current implementation. If you were to use columns you wouldn't need the javascript and CSS is all that's needed.
Here is a fiddle where I've implemented it http://jsfiddle.net/eQvaZ/
The HTML is as follows:
<body>
<div class="pageCont">
<div class="Row">C1</div>
<div class="Row">C2</div>
<div class="Row" id="to-remove">C3</div>
<div class="Row">C4</div>
<div class="Row">C5</div>
<div class="Row">C6</div>
<div class="Row">C7</div>
</div>
<div>Removing C3 in 5 seconds...</div>
</body>
The CSS:
.pageCont{
column-count:2;
column-rule:0px;
-webkit-column-count: 2;
-webkit-column-rule: 0px;
-moz-column-count: 2;
-moz-column-rule: 0px;
padding:10px;
height: 250px;
width: 200px;
border:2px solid red
}
.Row {
height:50px;
width:50px;
background-color:blue;
color:white;
margin-bottom:10px;
}
The bit of JavaScript to remove an item:
setTimeout( function(){
var to_remove = document.getElementById('to-remove');
to_remove.parentNode.removeChild(to_remove);
}, 5000);
Let me know if you have any questions regarding this implementation.

Resources