Lots of examples can be found to hide a parent div when ONE inner div is empty, but in my case I need to hide the parent div if TWO inner divs are empty:
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
</div>
Background: I am using Angular with ng-content select to fill the child divs with content. Sometimes none of these templates are used thus both child divs will be empty.
<div class="parent">
<div class="child1"><ng-content select="[child1]"></ng-content></div>
<div class="child2"><ng-content select="[child2]"></ng-content></div>
</div>
Sorry I run out of time, but would be a shame to not share what I was trying to make. Maybe not perfect because of the time but hopefully you get the idea. PS using jQuery.
$(".parent").each(function() {
var empty1 = 0;
var empty2 = 0;
var who = $(this);
$(this).find(".check").each(function() {
var check = $(this).html();
if(check == '<ng-content select="[child1]"></ng-content>') {
var empty1 = 1;
}
if(check == '<ng-content select="[child2]"></ng-content>') {
var empty2 = 1;
}
if(empty1 == 1 && empty2 == 1) {
$(who).slideUp(100);
}
});
});
.parent {
height:10vh;
background:#F00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
<div class="check child1"><ng-content select="[child1]"></ng-content></div>
<div class="check child2"><ng-content select="[child2]"></ng-content></div>
</div>
<div class="parent">
<div class="check child1"><ng-content select="[child1]">a</ng-content></div>
<div class="check child2"><ng-content select="[child2]"></ng-content></div>
</div>
I solved it using Angular ViewChild:
<div class="column column-3" [class.hidden]="!hasContentInColumn3">
<div class="line-1" #c3a>
<ng-content select="[c3a]"></ng-content>
</div>
<div class="line-2" #c3b>
<ng-content select="[c3b]"></ng-content>
</div>
</div>
export class ListItemComponent implements OnInit {
public hasContentInColumn3 = false;
#ViewChild('c3a', { static: true }) c3a: ElementRef;
#ViewChild('c3b', { static: true }) c3b: ElementRef;
ngOnInit () {
// Hide div.column-3 when line-1 and line-2 are not provided
this.hasContentInColumn3 = (
(this.c3a.nativeElement.childNodes.length > 0) ||
(this.c3b.nativeElement.childNodes.length > 0)
);
}
}
I hope this helps someone.
Related
I have tried :nth-of-type and :nth-child, but those don't work for selecting a specific instance on the entire page. For example, if I wanted to select the 8th div.box element below ("plane") how can I do this?
<div>
<div class="box">blueberry</div>
<div class="box">cherry</div>
<div class="box">pineapple</div>
<div class="box">orange</div>
<div class="box">grape</div>
</div>
<div>
<div class="box">car</div>
<div class="box">boat</div>
<div class="box">plane</div>
<div class="box">bike</div>
<div class="box">motorcycle</div>
</div>
You can do this with javascript. I don't think you can do such a specific task with CSS, but I'm not sure.
let base = document.getElementsByTagName("div");
let divs = [];
for (let i = 0; i < base.length; i++) {
let elems = base[i].getElementsByTagName("div");
for (let j = 0; j < elems.length; j++) {
divs.push(elems[j])
}
}
function findNElement(n) {
return divs[n-1].textContent; // This is to return text. Remove .textContent to remove th element
}
console.log(findNElement(8));
<div>
<div class="box">blueberry</div>
<div class="box">cherry</div>
<div class="box">pineapple</div>
<div class="box">orange</div>
<div class="box">grape</div>
</div>
<div>
<div class="box">car</div>
<div class="box">boat</div>
<div class="box">plane</div>
<div class="box">bike</div>
<div class="box">motorcycle</div>
</div>
You can use this snippet to select a certain element of the textContent of the element.
For the completely general case, where you do not know the document's structure (i.e. div.box elements are 'scattered' as you say) I think you'll need Javascript.
The element you want is
document.querySelectorAll('div.box')[7]
of course you'll want to check that it actually exists before trying to do anything with it so something like:
function findBox(n) { //n starts at 1
const boxes = document.querySelectorAll('div.box');
if (boxes.length >= n) return boxes[n-1];
else return false;
}
let n = 8;
let box = findBox(n);
if (box) {
box.style.backgroundColor = 'silver';
}
else {
console.log('There is no ' + n + 'div.box');
}
<div>
<div class="box">blueberry</div>
<div class="box">cherry</div>
<div class="box">pineapple</div>
<div class="box">orange</div>
<div class="box">grape</div>
</div>
<div>
<div class="box">car</div>
<div class="box">boat</div>
<div class="box">plane</div>
<div class="box">bike</div>
<div class="box">motorcycle</div>
</div>
I am trying to add vertical movement to a list of stacked titles time I change page changes in FullPageJS. I get no error at all, but the action is not happing. My guess is that I am wrong trying to modify the CSS property transition using the element ref. Can anyone spot something wrong with the code below?
Thank you in advance.
React
componentDidMount() {
titleWidth = this.title.current.clientHeight
titleHeight = this.title.current.clientHeight
this.mask.current.css = {
height: titleHeight + "px",
width: titleWidth + "px",
}
this.frame.current.css = { top: titleHeight + "px" }
}
onLeave(origin, destination, direction) {
console.log("Leaving section " + origin.index)
// Actions not working
if (direction == "down") {
this.frame.current.style.transition = { top: "-=" + titleHeight }
} else if (direction == "up") {
this.frame.current.style.transition = { top: "+=" + titleHeight }
}
}
HTML
<div id="wrapper--frame" className="flex justify-center">
<div ref={this.mask} id="mask" className="w-5/6 overflow-hidden">
<div ref={this.frame} id="frame">
<div ref={this.title} className="text-p frame--title ">
One
</div>
<div ref={this.title} className="text-p frame--title ">
Two
</div>
<div ref={this.title} className="text-p frame--title ">
Three
</div>
<div ref={this.title} className="text-p frame--title ">
Four
</div>
</div>
</div>
</div>
App doesn't cover all display on mobile - there is a slim black bar on the bottom.
<body>
<div data-role="page" id="main" data-theme="b" data-fullscreen="true">
<div data-role="header" data-fullscreen="true">
<h1>Scheduler</h1>
Dodaj
</div>
<div data-role="main" class="ui-content" id="list">
</div>
<div data-role="footer" data-position="fixed" data-fullscreen="true" data-tap-toggle="false">
<div data-role="navbar">
<ul>
<li>Settings</li>
<li>Info</li>
</ul>
</div>
</div>
</div>
<!--Adding goals-->
<div data-role="page" id="adding">
<div data-role="header">
<h1>Adding new goal</h1>
</div>
<div data-role="main" class="ui-content">
<form data-theme="e">
<form onsubmit="return false;">
<label>
NEW GOAL:<input type="text" id="goal" />
</label>
<input type="button" value="ADD" id="addBtn"/>
</form>
</form>
</div>
</div>
<!--Settings-->
<div data-role="page" id="settings">
<div data-role="header">
<h1>Settings</h1>
</div>
<div data-role="main" class="ui-content">
<form data-theme="e">
<input type="button" value="Clear all elements" id="delBtn"/>
</form>
</div>
</div>
<!-- Info -->
<div data-role="page" id="info">
<div data-role="header">
<h1>Info</h1>
</div>
<div data-role="main" class="ui-content">
Here help will be. ~~Yoda
</div>
</div>
CSS code is like this:
#main{height:100% !important;}
html,body{
margin:0;
padding:0;
border:none;
}
javascript code:
var db = new PouchDB('goals');
var remoteCouch = 'goals_remote';
db.changes({
since: 'now',
live: true
}).on('change', createList);
createList();
//creating goals
document.getElementById('addBtn').addEventListener('click', function(){
var txt = document.getElementById('goal').value;
var goal = {
_id: new Date().toISOString(),
text: txt,
completed: false
}
db.put(goal, function callback(err, result){
if(!err){
console.log('success');
refresh();
}
});
}, false);
//deleting elements
document.getElementById('delBtn').addEventListener('click', function(){
db.destroy().then(function() {
refresh();
});
}, false);
function refresh(){
location.reload(true);
}
//pressing goal
function pressGoal(goal){
if(goal.completed){
goal.completed = false;
} else {
goal.completed = true;
}
db.put(goal);
createList();
}
function createList() {
var completedTasks = [];
var notCompletedTasks = [];
db.allDocs({
include_docs: true,
descending: true
}).then(function(result) {
for(var k = 0; k < result.rows.length; k++){
if(result.rows[k].doc.completed){
completedTasks.splice(completedTasks.length, 0, result.rows[k].doc);
} else {
notCompletedTasks.splice(notCompletedTasks.length, 0, result.rows[k].doc);
}
renderList(completedTasks, notCompletedTasks);
}
}).catch(function(err) {
console.log(err);
});
}
function renderList(completedTasks, notCompletedTasks){
var code = '';
var notCode = '';
var elementsArr = [];
//creating lists
for(var i = 0; i < notCompletedTasks.length; i++){
code += '<div class="ui-checkbox" id="'+notCompletedTasks[i]._id+'"><label class="ui- checkbox-off ui-btn ui-btn-corner-all ui-fullsize ui-btn-icon-left ui-btn-up-b" data-corners="true" data-shadow="false" data-iconshadow="true" data- wrapperels="span" data-icon="checkbox-off" data-theme="b" data-mini="false"> <span class="ui-btn-inner"><span class="ui-btn-text">'+notCompletedTasks[i].text+'</span><span class="ui-icon ui-icon-checkbox-off ui-icon-shadow"> </span></span></label><input type="checkbox"></div>';
}
for(var j = 0; j < completedTasks.length; j++){
notCode += '<div class="checked" id="'+completedTasks[j]._id+'">'+'<div class="ui-icon ui-icon-check">'+'</div>'+'<span class="field">'+completedTasks[j].text+'</span>'+'</div>';
}
//build
document.getElementById('list').innerHTML = code + notCode;
for(var k = 0; k < notCompletedTasks.length; k++){
(function(){
var arg = notCompletedTasks[k];
document.getElementById(arg._id).addEventListener('click', function(){
pressGoal(arg);
}, false);
})();
}
for(var k = 0; k < completedTasks.length; k++){
(function(){
var arg = completedTasks[k];
document.getElementById(arg._id).addEventListener('click', function(){
pressGoal(arg);
}, false);
})();
}
}
I hope that code will be enough. I don't know why CSS code doesn't work like it should.
Is there any way to do this? I couldn't find answer to this question.
Edit: I added javascript code. Unfortunately I don't know what created that problem so code is kinda huge. Sorry for that.
I used pouchDB for storing users data and compiled with cocoon.io for mobiles.
You may look at this post from Omar: set content height 100% jquery mobile. It is updated with a working solution for the current JQM 1.4.5 version and is also covering the issues related to html{ height: 100%; }.
I'm trying to edit the border-bottom-color individual depending on a property of the element in ng-repeat.
Here is an example how the html is structured. The changed style is
.active-tool::after {border-bottom-color: rgb(247, 153, 248)}
html:
<div data-ng-repeat="row in rows">
<div class='container'>
<div
data-ng-style="getPrimaryColor(tvShow)"
class='folder tvshow'
data-ng-class="isActiveFolder(tvShow)"
id='{{tvShow.id}}'
data-ng-repeat="tvShow in row track by $index">
<div data-ng-click="setSelectedTvShow(tvShow)">
<p class="tvshow-name">{{tvShow.name}}</p>
</div>
</div>
</div>
controller.js
$scope.isActiveFolder = function(tvShow) {
if($scope.selectedTvShow !== null && tvShow.id !== null) {
return $scope.selectedTvShow===tvShow.id ? 'active-tool' : '';
}
};
$scope.getPrimaryColor = function(tvShow) {
if($scope.selectedTvShow !== null) {
var result = '{' + tvShow.id + '.active-tool::after {border-bottom-color: rgb(247, 153, 248)}}';
console.log(result);
return result;
};
Any ideas how this could be done?
I use this quick hack:
put this inside your template:
<style type="text/css">
.active-tool::after {
border-bottom-color: {{getShowBorderColor(tvShow)}};
}
</style>
and then in your controller:
$scope.getShowBorderColor = function(tvShow){
return tvShow.color; // change this for how you want to calculate the color
};
You cannot use ng-style like this, because html style attribute does not support css selectors.
Actually, you can do it with no javascript at all:
markup:
<div data-ng-repeat="row in rows">
<div class='container'>
<div class='folder tvshow'
data-ng-class="{active-tool : selectedTvShow === tvShow.id}"
id='{{tvShow.id}}'
data-ng-repeat="tvShow in row track by $index">
<div data-ng-click="selectedTvShow = tvShow.id">
<p class="tvshow-name">{{tvShow.name}}</p>
</div>
</div>
</div>
</div>
css:
.active-tool::after {
border-bottom-color: rgb(247, 153, 248);
}
I want to make something like that:
#if ( some-statement )
{
<div class="row-link">
}
else
{
<div class="row">
}
<div class="new">some content</div>
</div>
but the compiler keeps telling me that the if has no closing character!
What's wrong?
Thanks!
I'm not fluent in c# but why don't you use a variable to hold the classname?
#string classname;
#if ( some-statement ) {
classname = "row-link";
} else {
classname = "row";
}
<div class="#classname">
<div class="new">some content</div>
</div>
Or you could use a helper function. It keeps your html cleaner.
Use <text>
#if ( some-statement)
{
<text>
<div class="row-link">
</text>
}
else
{
<text>
<div class="row">
</text>
}
<div class="new">some content</div>
</div>
and check out
http://weblogs.asp.net/scottgu/archive/2010/12/15/asp-net-mvc-3-razor-s-and-lt-text-gt-syntax.aspx
hope this helps
try
#if ( some-statement )
{
#:<div class="row-link">
}
else
{
#:<div class="row">
}
<div class="new">some content</div>
</div>
You may consider closing your <div> and remove your common end </div>
#if ( some-statement )
{
<div class="row-link"></div>
}
else
{
<div class="row"></div>
}
<div class="new">some content</div>