I have this design here:
You can see the material icon is a bit too close to the description. I thought I could create some padding between both by doing something like this:
.location-secondary-info span:first-child {
padding-right: 5px;
}
That has been ineffectual.
This is the component code:
renderLocation() {
const filteredLocations = this.props.locations.filter(location => {
return !location.name.match(/[A-Z0-9]+$/);
});
return filteredLocations.map(location => {
if (location.airport_code) {
return (
<div key={location.id}>
<div className="location">
<h1>
{location.name} ({location.airport_code})
</h1>
<div className="location-secondary-info">
<span>
<i className="material-icons">airplanemode_active</i>
{location.description}
</span>
</div>
</div>
</div>
);
} else {
return (
<div key={location.id}>
<div className="location">
<h1>{location.name}</h1>
<div className="location-secondary-info">
<span>
<i className="material-icons">location_city</i>
{location.description}
</span>
</div>
</div>
</div>
);
}
});
}
You should select the i element inside the span, so:
.location-secondary-info span i {
padding-right: 5px;
}
With span:first-child you were selecting the first span element inside .location-secondary.
Related
I have a list of messages, when the user scroll to the top of the list, the app loads more messages. This part is working fine.
But the scroll position is kept unchanged, it's not scrolling to the previously shown element, the scroll position is always on top (so we could load more messages again).
This behavior happens only when user has scrolled to the very top. If we load more message but user has scroll down even a very little bit, it keeps the same position.
Is there a css solution ?
Or should I programmatically scroll down user to the previous message ?
Or should I programmatically scroll down a very little bit juste before adding messages to the list ?
function addElement(id) {
const $element = $($('#TemplateItem').html().replace('{id}', id));
$('.list').prepend($element);
}
var loadCount = 0;
function loadMore() {
loadCount++;
for(let i=0; i < 5; i++) {
addElement(loadCount + '-' + (i+1));
}
}
$('button').click(() => {
loadMore();
});
loadMore();
.list {
width: 50%;
height: 20rem;
background: yellow;
overflow-y: auto;
}
.item {
background: lime;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.2/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<button class="btn btn-primary mt-3" type="button">
Load more
</button>
<div class="list mt-3 p-2"></div>
<template id="TemplateItem">
<div class="item mt-1 p-2">I am fantastic item #{id} !</div>
</template>
</div>
Refering to this answer, I have created my own solution.
Once the nodes has been added, update the scroll top of the container to the last node that existed before adding the new nodes.
Working example.
function addElement(id) {
const $element = $($('#TemplateItem').html().replace('{id}', id));
$element[0].id = `list-node-${id}`;
$('.list').prepend($element);
}
var loadCount = 0;
var incrementer = 5;
function loadMore() {
loadCount++;
for (let i = 0; i < incrementer; i++) {
addElement(loadCount + '-' + (i + 1));
}
if (loadCount > 1) {
initialNode = $(`#list-node-${loadCount - 1}-${incrementer}`);
$('#wrapper').animate({
scrollTop: initialNode.offset().top - $('#wrapper').offset().top + $('#wrapper').scrollTop()
}, 1000);
}
}
$('button').click(() => {
loadMore();
});
loadMore();
.list {
width: 50%;
height: 20rem;
background: yellow;
overflow-y: auto;
}
.item {
background: lime;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.2/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<button class="btn btn-primary mt-3" type="button">
Load more
</button>
<div class="list mt-3 p-2" id="wrapper"></div>
<template id="TemplateItem">
<div class="item mt-1 p-2">I am fantastic item #{id} !</div>
</template>
</div>
I'd like to show the buttons row direction.
I've given disply:flex but it still shows column.
It should be the button has a first character of the name which is underneath the button
and these buttons should be next to each other.
Not like button on the left and the name on the right.
Would be appreciated if I could get help.
RoomList.js
import React from 'react';
import './RoomList.css';
import PropTypes from 'prop-types';
const RoomList = ({ roomList }) => {
return (
<div>
{roomList.map((room) => {
const firstToChar = room.split('');
const firstChar = firstToChar[0];
return (
<div>
<li className="list">
<div className="room-list">
<button type="submit">{firstChar}</button>
<div>{room}</div>
</div>
</li>
</div>
);
})}
</div>
);
};
RoomList.propTypes = {
roomList: PropTypes.func.isRequired,
};
export default RoomList;
RoomList.css
button {
height: 40px;
min-width: 40px;
display: block;
border-radius: 50%;
margin-bottom: 5px;
}
.room-list {
}
.list {
list-style-type: none;
display: flex;
}
The problem is with the HTML you produce. You produce one list by room. Which is not what you want, you want one list, and one item by room in your list.
button {
height: 40px;
min-width: 40px;
display: block;
border-radius: 50%;
margin-bottom: 5px;
}
.room-list {
}
.list {
list-style-type: none;
display: flex;
}
<div>
<div>
<li class="list">
<div class="room-list">
<button type="submit">K</button>
<div>Kitchen</div>
</div>
</li>
</div>
<div>
<li class="list">
<div class="room-list">
<button type="submit">B</button>
<div>Bathroom</div>
</div>
</li>
</div>
</div>
What you want is:
button {
height: 40px;
min-width: 40px;
display: block;
border-radius: 50%;
margin-bottom: 5px;
}
.room-list {
}
.list {
list-style-type: none;
display: flex;
}
<div>
<div>
<li class="list">
<div class="room-list">
<button type="submit">K</button>
<div>Kitchen</div>
</div>
<div class="room-list">
<button type="submit">B</button>
<div>Bathroom</div>
</div>
</li>
</div>
</div>
So you actually want:
const RoomList = ({ roomList }) => {
return (
<div>
<div>
<li className="list">
{roomList.map((room) => {
const firstToChar = room.split('');
const firstChar = firstToChar[0];
return (
<div className="room-list">
<button type="submit">{firstChar}</button>
<div>{room}</div>
</div>
);
})}
</li>
</div>
</div>
);
};
The flex should be on the room list instead
I am getting HTML from an external source and can't change the code, so in order to get the result we need I need to conditionally hide things.
In this example, where I have a level-0 and level-1 I need to set display:none on the h2 (finance in this case).
<section class="level-0">
<h2 id="4001567002">Finance</h2>
<section class="child level-1">
<h2 id="4008036002">Fusion</h2>
<div class="opening" department_id="4001567002,4008036002" office_id="4000758002" data-office-4000758002="true" data-department-4001567002="true" data-department-4008036002="true">
<a data-mapped="true" target="_top" href="google.com">Business Systems Executive</a>
<br>
<span class="location">Sydney</span>
</div>
</section>
It could be that there is no level-1 in which case the level-0 header should be visible:
<section class="level-0">
<h2 id="4008036002">Fusion</h2>
<div class="opening" department_id="4001567002,4008036002" office_id="4000758002" data-office-4000758002="true" data-department-4001567002="true" data-department-4008036002="true">
<a data-mapped="true" target="_top" href="google.com">Business Systems Executive</a>
<br>
<span class="location">Sydney</span>
</div>
The ids are not predictable, so I cannot hide the levels based on that.
Is this possible in pure CSS or should I come up with another solution?
I was not able to do what you want with Pure CSS, and I don't think it is possible as you cannot add conditional statements within CSS.
Please find below a solution with a little bit of jquery:
var count = $(".level-0").length +1;
for (i = 1; i < count; i++) {
if ($(".level-1").parents('.container > .level-0:nth-of-type(' + i + ')').length == 1) {
$( '.level-0:nth-of-type(' + i + ')').addClass( "has-lv1" );
} else {
$( '.level-0:nth-of-type(' + i + ')').addClass( "no-lv1" );
}
}
.container {
border: solid 1px black;
padding: 20px;
background-color: lightblue;
}
.container > h2{
color: green;
}
.has-lv1 > h2 {
display: none;
}
.no-lv1 > h2 {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h2>Example with <strong>Level 1</strong></h2>
<section class="level-0">
<h2 id="4001567002">Finance</h2>
<section class="child level-1">
<h2 id="4008036002">Fusion</h2>
<div class="opening" department_id="4001567002,4008036002" office_id="4000758002" data-office-4000758002="true" data-department-4001567002="true" data-department-4008036002="true">
<a data-mapped="true" target="_top" href="google.com">Business Systems Executive</a>
<br>
<span class="location">Sydney</span>
</div>
</section>
</section>
<hr>
<h2>Example without <strong>Level 1</strong></h2>
<section class="level-0">
<h2 id="4001567002">Finance</h2>
</section>
</div>
I hope this helps
I am new to AngularJS and I am working on creating fadein animation. I added all the required js files in my my header and element.ng-enter and element.ng-enter-ng-enter.active classes in css file as per documents from AngularJS. When I browse the URL, I dont get fadein effects. Here is my JSFiddle link.
HTML code:
<div ng-app="Dashboard">
<div id="dashboard" ng-controller="dashboardCtrl">
<div class="app-nav">
<button onclick="location.href = '/';">Dashboard</button>
</div>
<br>
<div class="app-nav">
<button onclick="location.href = 'Applications';">Healthchecks</button>
</div>
<br>
<div class="app-nav">
<button>Contact US</button>
</div>
<br>
</div>
</div>
JS Script:
angular.module('Dashboard', ['ngAnimate'])
.controller('dashboardCtrl', function ($scope) {
});
CSS:
#dashboard {
margin-top: 50px;
}
.app-nav {
max-width: 350px;
min-height: 75px !important;
margin: 0 auto;
}
.app-nav button:hover {
background-color: #154995;
}
.app-nav button {
min-width: 350px;
min-height: 75px;
}
button.ng-enter {
transition: 3s linear all;
opacity: 0;
}
button.ng-enter.ng-enter-active {
opacity: 2;
}
Do not mix pure javascript in your html file with angular. You should replace onclick with ng-click because then angular can inject correct class to div and show you animation
index.html
<div ng-app="Dashboard">
<div id="dashboard" ng-controller="dashboardCtrl">
<div class="app-nav">
<button ng-click="functionOne()">Dashboard</button>
</div>
<br>
<div class="app-nav">
<button ng-click="functionTwo()">Healthchecks</button>
</div>
<br>
<div class="app-nav">
<button>Contact US</button>
</div>
<br>
</div>
</div>
controller.js
(function () {
'use strict';
angular
.module('Dashboard')
.controller('dashboardCtrl', dashboardCtrl);
dashboardCtrl.$inject = ['$scope', 'ngAnimate'];
function dashboardCtrl($scope, ngAnimate) {
$scope.functionOne = function () {
// your action
};
$scope.functionTwo = function () {
// your action
};
}
}());
I wanted the div id='cancelReq' to be displayed when the mouse hover at span id='requestSent'
I've tried this code, but it's not working.
<style>
#cancelReq {
display: none;
}
#requestSent:hover + #cancelReq {
display: block;
}
</style>
<div id='addUser'>
<span id='requestSent'>Add Friend</span>
</div>
<div id='cancelReq' >hello there</div>
You can use the javascript for that.
Here is the code for your problem:
<script type="text/javascript">
function fun(){
document.getElementById("cancelReq").style.display = "block";
}
function fun1(){
document.getElementById("cancelReq").style.display = "none";
}
</script>
And make your HTML code like following:
<div id='addUser'><span id='requestSent' onmouseover="fun();" onmouseout="fun1();" >Add Friend</span></div>
<div id='cancelReq' >hello there</div>