select elements which have a special css attribute with jquery - css

I have the following structure:
<div class="main">
<div class="submain">
.....
<div class="sub..submain">
</div>
.....
</div>
<div class="submain">
</div>
</div>
Some of the subelements have the css property float:right;, and I dont know how many levels there are.
How can I select all elements with this css property using the selector $('.main')?
I have an idea, but I am trying to find an easier way to do it:
var elemsArray=[];
function findNeededChildren(elem){
var hasChildren = elem.children().length>0?true:false;
if(hasChildren ){
$.each(elem.children(),function(){
if($(this).css('float')=='right')elemsArray.push($(this));
findNeededChildren($(this));
});
}
}
findNeededChildren($('.main'));

You can select elements by an attribute, so you could try
$('div[style="float:right"]')
This should select all the divs with that attribute. But I am not sure if it will also select something with more than this one style.
Edit:
I just remembered that some people here where I work use classes for this sort of thing. It makes maintainability easier. Make a css rule that says:
.floatRight {
float:right
}
Then just assign this class to everything that needs floating. These should be even easier to select.

You can do something like
$(document).ready(function(){
$(".main").find("div").each(function(){
if($(this).css("float") == "right") {
// This is the required div
}
});
})
And if you don't know that children of .main are divs or other tags then use
$(document).ready(function(){
$(".main").children().each(function(){
if($(this).css("float") == "right") {
// This is the required element with float: right property
}
});
})

Related

Vuejs apply loop in css to put hover

In VueJS, I have elements that have hover property in my object.
So, I want to put a foreach in style, but it is not possible.
I want to do that kind of thing :
<style>
#foreach (element in elements) {
if (element.has_backgroundhover) {
'#'+element.id:hover {
background : element.background_hover;
}
}
}
</style>
Notice that each element has a background color different (it is stored in his oibject property)
Thank you
The #mouseenter and #mouseleave event listeners would allow for css classes to be applied to each element.
For example, toggle a .hovered class that has the background color defined.
Something like this?
The HTML:
<div id="app">
<div
v-for="element of elements"
#mouseenter="element.hover=true"
#mouseleave="element.hover=false"
:style="{
background: element.hover? element.background_hover : element.background
}"
>{{element.name}}</div>
</div>
And the JS:
new Vue({
el: "#app",
data: {
elements:[
{
name:"element1",
background:"#f8f",
background_hover:"#a4a",
hover:false
},
{
name:"element2",
background:"#ff8",
background_hover:"#aa4",
hover:false
},
]
},
})
This is not using the CSS, rather using events as suggested by #DigitalDrifter. I think the point is that reactive css is not a good idea, and not supported in vue. Instead you need to have the HTML element properties dependent on your vue data object. A fiddle for this is: https://jsfiddle.net/edzaokum/

Change CSS class's property on click

I've read around a little bit and have a good start to what I ultimately want. This was helpful, along with another article which I forgot the link to. However, everything I've read ADDS a CSS class or property to an element. I want to CHANGE a property of an existing CSS class, but I don't know how to target it.
I think I want to use ng-class in one of these use cases taken from the Angular documentation:
If the expression evaluates to a string, the string should be one or more space-delimited class names.
If the expression evaluates to an object, then for each key-value pair of the object with a truthy value the corresponding key is used as a class name.
My existing code uses ng-class along with some controller logic.
HTML
<div ng-controller="ngToggle">
<div ng-class="{'inset-gray-border' : style}">
<div class="subcontainer" ng-click="toggleStyle()">{{item.name}}</div>
</div>
</div>
This currently adds the inset-gray-border class to the nested div, but I just want to change the border property in the subcontainer class.
Controller
angular.module('app').controller('ngToggle', ['$scope', function($scope) {
$scope.style = false;
$scope.toggleStyle = function() {
$scope.style = $scope.style === false ? true: false;
};
}]);
I considered using a directive, but I believe that would be overkill. I think this can be achieved in a controller.
EDIT: After further research I think jQLite can do the trick, but that would probably require a directive.
CHANGE a property of an existing CSS class
Add a css rule that does that using the new class you added using ng-class. The specificity will over ride the original rule
.subcontainer{
color : blue
}
.inset-gray-border .subcontainer{
color:red
}
Instead of a big toggleStyle function, you can write that stuff in UI side only.
Here is fiddle. As you want to change border property of .subcontainer, Overwrite that property by adding .insert-gray-border
<div ng-controller="ngToggle">
<div >
<div ng-class="{'subcontainer':true,'inset-gray-border' : style}" ng-click="style=!style">{{item.name}}</div>
</div>
</div>
The benifit of this is , it uses local scope instead of controller scope.
The best bet would be to have two CSS classes defined, one for the base (untoggled) case, another with all the properties that you want for when the property is toggled on.
In this case you may want something like:
.container .subcontainer {}
.container .subcontainer-bordered { border: solid 1px #123456}
Then your HTML code be updated to reflect this structure
<div ng-controller="ngToggle">
<div class="container">
<div class="subcontainer" ng-class="{'subcontainer-bordered': style}" ng-click="style = !style">{{item.name}}</div>
</div>
</div>

Hide a whole div with CSS with part of it is empty

Is there a way to hide a whole div if part of it is empty? For example if "dd" is empty as shown below can I hide the whole class "test" so the keyword Restrictions does not show either. I tried .test dd:empty { display: none; } but this does not work. thanks!
<div class="test"><dt>Restrictions:</dt>
<dd></dd></div>
I don't think there's any easy way to do what you're talking about with just CSS. Better to test it server-side if you can. But if you can't here's some JS that will do the job.
<script type="text/javascript">
// handles multiple dt/dd pairs per div and hides them each conditionally
function hideIfEmpty() {
// get all the elements with class test
var els = document.getElementsByTagName('dl');
// for every 'test' div we find, go through and hide the appropriate elements
Array.prototype.map.call(els, function(el) {
var children = el.childNodes;
var ddEmpty = false;
for(var i = children.length - 1; i >= 0; i--) {
if(children[i].tagName === 'DD' && !children[i].innerHTML.trim()) {
ddEmpty = true;
} else if(children[i].tagName === 'DT') {
if(ddEmpty) {
children[i].style.display = 'none';
}
// reset the flag
ddEmpty = false;
}
}
});
}
window.addEventListener('load', hideIfEmpty);
</script>
<div class="test">
<div style="clear: both;"></div>
<dl>
<dt>Restrictions:</dt>
<dd></dd>
<dt>Other Restrictions:</dt>
<dd>Since I have content, I won't be hidden.</dd>
</dl>
</div>
Just a fair warning: the code uses some functions that may not exist in older IE, such as Array.prototype.map, String.prototype.trim, and addEventListener. There are polyfills available for these and you could also write your own pretty easily (or just do it with a for loop instead).
CSS alone can't do that. Either, you need a javascript to retrieve empty elements and hide their parents, or your CMS applies special CSS classes if there's no content.
Put as an answer as requested by #Barett.
You could update your CSS to be
.test{
display: none;
color: transparent;
}
This would make the text transparent too, but display:none should hide it anyway.
To make the div with the id test ONLY show when the dd tag is EMPTY, and you can use jQuery, try the following JavaScript along with the CSS:
if($("dd").html().length ==0)
{show();
}
Note: this solution requires jQuery, which is a JavaScript library.

Applying style to a parent block depending on the child's state

With the following block structure:
<div class="container">
<div class="title"></div>
<div class="subject"></div>
</div>
is it possible to hide (display:none) a .container if it's child .subject is empty?
Thanks!
well... you could try to fake it... make title position: absolute and for container set overflow: hidden; container itself will only be visible if you put something into .subject tag. Like this:
jsfiddle example
I believe you'll have to use javascript to do this. In jQuery:
$(".container").each( function() {
if ( $(this).children('.subject').html() == '' ) {
$(this).hide();
}
} );
Example at: http://jsfiddle.net/m5jjs/
Not currently possible in pure CSS in any browser I know of.
There is a jQuery plugin cssParentSelector polyfill for the upcoming parent selector in CSS Selectors Level 4 if you already have a jQuery dependency in the project.
:empty psuedo class can be used if element has no node but you have. Need JS though.
$(".container *") {
if($.trim($(this).html()).length == 0 && $.trim($(this).text()).length == 0 ) {
$(".container").css({ "display" : "none" });
}
});

Is there a CSS "haschildren" selector? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a CSS parent selector?
Is there a css selector I can use only if a child element exists?
Consider:
<div> <ul> <li></li> </ul> </div>
I would like to apply display:none to div only if it doesn't have at least one child <li> element.
Any selector I can use do this?
Sort of, with :empty but it's limited.
Example: http://jsfiddle.net/Ky4dA/3/
Even text nodes will cause the parent to not be deemed empty, so a UL inside the DIV would keep the DIV from being matched.
<h1>Original</h1>
<div><ul><li>An item</li></ul></div>
<h1>No Children - Match</h1>
<div></div>
<h1>Has a Child - No Match</h1>
<div><ul></ul></div>
<h1>Has Text - No Match</h1>
<div>text</div>
DIV {
background-color: red;
height: 20px;
}
DIV:empty {
background-color: green;
}
Reference: http://www.w3.org/TR/selectors/#empty-pseudo
If you go the script route:
// pure JS solution
​var divs = document.getElementsByTagName("div");
for( var i = 0; i < divs.length; i++ ){
if( divs[i].childNodes.length == 0 ){ // or whatever condition makes sense
divs[i].style.display = "none";
}
}​
Of course, jQuery makes a task like this easier, but this one task isn't sufficient justification to include a whole libary.
Nope, unfortunately that's not possible with CSS selectors.
CSS does not (yet) have any parent rules unfortunately, the only way around it if you must apply it only parents that contain a specific child is with the Javascript, or more easily with a library of javascript called jQuery.
Javascript can be written in a similair way to CSS in someways, for your example we would do something like this at the bottom of our HTML page:
<script type="text/javascript">
$('div:has(ul li)').css("color","red");
</script>
(For this you would need to include the jQuery library in your document, simply by putting the following in your <head></head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
If you use jquery, you can try out this function
jQuery.fn.not_exists = function(){
return this.length <= 0;
}
if ($("div#ID > li").not_exists()) {
// Do something
}
There is another option
$('div ul').each(function(x,r) {
if ($(r).find('li').length < 1){
$(r).css('display','block'); // set display none
}
})

Resources