Rendering a list of objects left to right in React - html

I am working on my first React project, a project as part of a Udacity course.
The task (or this part of it) is to initially render a series of book objects horizontally in three shelves.
I have managed to render the shelves and the books within them, however the books within each shelf are being rendered top to bottom rather than left to right.
One of the solutions I have seen posted is to use display: inline; in the CSS file but I have done that with no success.
How can I fix the code so that books within shelves are rendered horizontally?
I have included the ListBooks.js and App.css files. Let me know if I need to add anything else.
ListBooks.js
import React, { Component } from 'react';
import PropTypes from 'prop-types'
import './App.css'
const shelves = [
{
key: 'currentlyReading',
name: 'Currently Reading'
},
{
key: 'wantToRead',
name: 'Want To Read'
},
{
key: 'read',
name: 'Read'
}
];
class ListBooks extends Component {
static propTypes = {
books: PropTypes.array.isRequired
}
state = {
showSearchPage: false,
query: ''
}
render() {
const { books } = this.props
function getBooksForShelf(shelfKey) {
return books.filter(book => book.shelf === shelfKey);
}
return(
<div className="app">
{this.state.showSearchPage ? (
<div className="search-books">
<div className="search-books-bar">
<a className="close-search" onClick={() => this.setState({ showSearchPage: false })}>Close</a>
<div className="search-books-input-wrapper">
{/*
NOTES: The search from BooksAPI is limited to a particular set of search terms.
You can find these search terms here:
https://github.com/udacity/reactnd-project-myreads-starter/blob/master/SEARCH_TERMS.md
However, remember that the BooksAPI.search method DOES search by title or author. So, don't worry if
you don't find a specific author or title. Every search is limited by search terms.
*/}
<input type="text" placeholder="Search by title or author"/>
</div>
</div>
<div className="search-books-results">
<ol className="books-grid"></ol>
</div>
</div>
) : (
<div className="list-books">
<div className="list-books-title">
<h1>My Reads</h1>
</div>
<div className="list-books-content">
<div>
{ shelves.map((shelf) => (
<div key={shelf.key} className="bookshelf">
<h2 className="bookshelf-title">{shelf.name}</h2>
<div className="bookshelf-books">
<ol className="books-grid">
<li>
{ getBooksForShelf(shelf.key).map((book) => (
<div key={book.id} className="book">
<div className="book-top">
<div className="book-cover" style={{ width: 128, height: 193, backgroundImage: `url(${book.imageLinks.thumbnail})` }}></div>
<div className="book-shelf-changer">
<select>
<option value="none" disabled>Move to...</option>
<option value="currentlyReading">Currently Reading</option>
<option value="wantToRead">Want to Read</option>
<option value="read">Read</option>
<option value="none">None</option>
</select>
</div>
</div>
<div className="book-title">{book.title}</div>
<div className="book-authors">{book.author}</div>
</div>
))}
</li>
</ol>
</div>
</div>
)) }
</div>
</div>
<div className="open-search">
<a onClick={() => this.setState({ showSearchPage: true })}>Add a book</a>
</div>
</div>
)}
</div>
)
}
}
export default ListBooks
App.css
html, body, .root {
height: 100%;
}
body {
line-height: 1.5;
}
body, .app {
background: white;
}
/* main page */
.list-books-title {
padding: 10px 0;
background: #2e7c31;
text-align: center;
}
.list-books-title h1 {
font-weight: 400;
margin: 0;
color: white;
}
.list-books-content {
padding: 0 0 80px;
flex: 1;
}
.bookshelf {
padding: 0 10px 20px;
}
#media (min-width: 600px) {
.bookshelf {
padding: 0 20px 40px;
}
}
.bookshelf-title {
border-bottom: 1px solid #dedede;
}
.bookshelf-books {
text-align: center;
}
.open-search {
position: fixed;
right: 25px;
bottom: 25px;
}
.open-search a {
display: block;
width: 50px;
height: 50px;
border-radius: 50%;
background: #2e7d32;
background-image: url('./icons/add.svg');
background-repeat: no-repeat;
background-position: center;
background-size: 28px;
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
font-size: 0;
}
/* search page */
.search-books-bar {
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 5;
display: flex;
box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 0 6px rgba(0,0,0,0.23);
}
.search-books-input-wrapper {
flex: 1;
background: #e9e;
}
.search-books-bar input {
width: 100%;
padding: 15px 10px;
font-size: 1.25em;
border: none;
outline: none;
}
.close-search {
display: block;
top: 20px;
left: 15px;
width: 50px;
height: 53px;
background: white;
background-image: url('./icons/arrow-back.svg');
background-position: center;
background-repeat: no-repeat;
background-size: 28px;
font-size: 0;
}
.search-books-results {
padding: 80px 10px 20px;
}
/* books grid */
.books-grid {
list-style-type: none;
padding: 0;
margin: 0;
display: inline;
justify-content: center;
flex-wrap: wrap;
}
.books-grid li {
padding: 10px 15px;
text-align: left;
}
.book {
width: 140px;
}
.book-title,
.book-authors {
font-size: 0.8em;
}
.book-title {
margin-top: 10px;
}
.book-authors {
color: #999;
}
.book-top {
position: relative;
height: 200px;
display: flex;
align-items: flex-end;
}
.book-shelf-changer {
position: absolute;
right: 0;
bottom: -10px;
width: 40px;
height: 40px;
border-radius: 50%;
background: #60ac5d;
background-image: url('./icons/arrow-drop-down.svg');
background-repeat: no-repeat;
background-position: center;
background-size: 20px;
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
}
.book-shelf-changer select {
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
/* book cover */
.book-cover {
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
background: #eee;
}
.book-cover-title {
padding: 20px 10px 0;
text-align: center;
font-size: 0.8em;
}

Try setting your shelf element, with display flex as it is suggested in your comments...
.list-books-content li {display: flex; flex-direction: row;}

Related

Replace an input file into image after selecting that image

i create a form where i upload image into database where i create icon input to select the image i want to convert that icon into that picture which i select after slecting the picture.
<label class="custom-file-upload">
<input asp-for="imge1" name="imge1" type="file" />
<i class="fa fa-camera"></i>
CSS
input[type="file"] {
display: none;
}
.custom-file-upload {
border: 1px solid #ccc;
display: inline-block;
padding: 6px 12px;
cursor: pointer;
height: 80px;
width: 100px;
display: flex;
align-items: center;
justify-content: center;
font-size: 30px;
color: var(--primary-color);
}
Using readAsDataURL you can get file path and set to img tag.
jQuery(document).ready(function() {
var readURL = function(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$('.input-img').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("input[type='file']").on('change', function() {
readURL(this);
});
});
.custom-input-file {
position: relative;
cursor:pointer;
}
.custom-input-file .input-file-wrapper {
height: 150px;
width: 150px;
border-radius: 10px;
position: relative;
}
.custom-input-file .input-file-wrapper .input-img {
height: 100%;
-o-object-fit: cover;
object-fit: cover;
border: 1px solid #ced4da;
border-radius: 10px;
width: 100%;;
}
.custom-input-file .input-file-wrapper input[type=file] {
position: absolute;
left: 0;
width: 100%;
height: 100%;
padding: 0;
opacity: 0;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div class="input-wrapper">
<div class="custom-input-file ">
<div class="input-file-wrapper ">
<img src="https://storage.googleapis.com/proudcity/mebanenc/uploads/2021/03/placeholder-image.png " class="input-img">
<input type="file" class="form-control ">
</div>
</div>
</div>
little bit change and add some javascrpt and jquery in it.
firslty add this
<div class="form">
<div class="grid">
<div class="form-element">
<input type="file" id="file-1" asp-for="imge1" name="imge1">
<label for="file-1" id="file-1-preview">
<div>
<span>+</span>
</div>
</label>
</div>
</div>
</div>
then add this javascript and jquery
<script>
function previewBeforeUpload(id){
document.querySelector("#"+id).addEventListener("change",function(e){
if(e.target.files.length == 0){
return;
}
let file = e.target.files[0];
let url = URL.createObjectURL(file);
document.querySelector("#"+id+"-preview div").innerText = file.name;
document.querySelector("#"+id+"-preview img").src = url;
});
}
previewBeforeUpload("file-1");
previewBeforeUpload("file-2");
previewBeforeUpload("file-3");
previewBeforeUpload("file-4");
previewBeforeUpload("file-5");
previewBeforeUpload("file-6");
previewBeforeUpload("file-7");
previewBeforeUpload("file-8");
previewBeforeUpload("file-9");
previewBeforeUpload("file-10");
</script>
Also add this CSS
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
body {
font-family: "Raleway",sans-serif;
background: #f8f8f8;
}
.form {
margin: 20px 0px 20px;
padding: 0px 10px;
}
.form h2 {
text-align: center;
color: #acacac;
font-size: 12px;
font-weight: 100;
}
.form .grid {
margin-top: 5px;
display: flex;
justify-content: space-around;
flex-wrap: wrap;
gap: 20px;
}
.form .grid .form-element {
width: 80px;
height: 80px;
box-shadow: 0px 0px 20px 5px rgba(100,100,100,0.1);
}
.form .grid .form-element input {
display: none;
}
.form .grid .form-element img {
width: 80px;
height: 80px;
object-fit: cover;
}
.form .grid .form-element div {
position: relative;
height: 30px;
margin-top: -40px;
background: rgba(0,0,0,0.5);
text-align: center;
line-height: 40px;
font-size: 13px;
color: #f5f5f5;
font-weight: 600;
}
.form .grid .form-element div span {
font-size: 15px;
}

Not working show and hide accordion? where is problem

There is a "show preview" / "hide preview" button that appears in edit mode between the textarea and the preview container. This toggle allows, well, to show and hide this preview.
So of course I thought that would solve my problem, until I realize that all it does is to set a display: none on the container.
-> NOT WORKING :( WHY
.panel-item {
position: relative;
margin-top: -1px;
}
.panel-title {
cursor: pointer;
min-height: 110px;
border: 1px solid #FEE4CF;
border-radius: 6px;
padding: 15px 65px 15px 20px;
background-image: url(https://cdn.myshoptet.com/usr/www.manulo.cz/user/documents/upload/sablona/arrow-down.svg);
background-repeat: no-repeat;
background-position: right 20px center;
}
.flex-between-center {
display: flex;
align-items: center;
justify-content: space-between;
}
.panel-title > div:first-of-type {
max-width: 540px;
}
.flex-center-wrap {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.in-doprava-a-platba .panel-title > div img {
margin-right: 20px;
}
img {
max-width: 100%;
height: auto;
}
.panel-body {
display: none;
padding: 0 20px 25px;
}
.type-page .content-wrapper-in ul {
list-style-type: none;
padding-left: 0;
}
.type-page .content-wrapper-in ul li {
font-size: 14px;
padding-left: 12px;
position: relative;
margin-bottom: 8px;
}
.type-page .content-wrapper-in ul li::before {
content: '';
width: 6px;
height: 6px;
display: block;
background-color: #AE6830;
border-radius: 50%;
position: absolute;
left: 0;
top: 6px;
}
.panel-show + .panel-body {
display: block;
}
#media screen and (max-width: 991px){
.panel-title {
background-size: 20px auto;
background-position: right 10px center;
padding: 15px 40px 15px 15px;
}
.panel-title > div > span, .panel-title > div > p {
font-size: 18px;
margin: 0 !important;
}
.panel-title.panel-show + .panel-body {
background-color: #FEE4CF;
display: block;
border: 1px solid #FEE4CF;
border-top: none;
border-radius: 0 0 6px 6px;
}
.panel-show + .panel-body {
display: block;
}
.panel-body {
padding: 0 20px 25px;
display: none;
}
.panel-body {
padding: 0 15px 25px;
}
}
<div class="panel-item">
<div class="panel-title flex-between-center">
<div class="flex-center-wrap"><img src="https://cdn.myshoptet.com/usr/446290.myshoptet.com/user/documents/upload/sablona/ppl.svg"> <span>PPL</span></div>
<div><span>99 Kč</span></div>
</div>
<div class="panel-body">
<ul>
<li>Když nakoupíte od 1900 Kč, máte dopravu zdarma. Jinak doručení stojí 99 Kč.</li>
<li>doručení a kontaktem na řidiče pro pohodlnější domluvu.</li>
<li>zkusí to ještě následující pracovní den. Následně váš balík uloží na nejbližší PPL zasielka.</li>
</ul>
</div>
</div>
where is problem not show and hide..
The quickest solution is
to change the .panel-title into an anchor tag <a>, making it an element that can receive focus.
and with CSS combinator selector +, the .panel-body can be toggled in/visible when the <a> loses/gets focus using the :focus pseudo selector.
I made those changes for you and added a second panel-item in <body> so you can see the accordion mechanism at work.
I also removed obsolete .panel-show references and cleaned up the #media.
Notice the two href="javascript:void(0)", without a href defined, an <a> cannot receive focus making the accordion fail to work...
Check the below snippet
/* NEW */
.panel-title {
/* To override standard <a> markup */
text-decoration: none;
color: currentColor;
}
.panel-title:focus+.panel-body {
/* make it visible */
display: block;
}
/**/
.panel-item {
position: relative;
margin-top: -1px;
}
.panel-title {
cursor: pointer;
min-height: 110px;
border: 1px solid #FEE4CF;
border-radius: 6px;
padding: 15px 65px 15px 20px;
background-image: url(https://cdn.myshoptet.com/usr/www.manulo.cz/user/documents/upload/sablona/arrow-down.svg);
background-repeat: no-repeat;
background-position: right 20px center;
}
.flex-between-center {
display: flex;
align-items: center;
justify-content: space-between;
}
.panel-title>div:first-of-type {
max-width: 540px;
}
.flex-center-wrap {
display: flex;
align-items: center;
flex-wrap: wrap;
}
.in-doprava-a-platba .panel-title>div img {
margin-right: 20px;
}
img {
max-width: 100%;
height: auto;
}
.panel-body {
display: none;
padding: 0 20px 25px;
}
.type-page .content-wrapper-in ul {
list-style-type: none;
padding-left: 0;
}
.type-page .content-wrapper-in ul li {
font-size: 14px;
padding-left: 12px;
position: relative;
margin-bottom: 8px;
}
.type-page .content-wrapper-in ul li::before {
content: '';
width: 6px;
height: 6px;
display: block;
background-color: #AE6830;
border-radius: 50%;
position: absolute;
left: 0;
top: 6px;
}
#media screen and (max-width: 991px) {
.panel-title {
background-size: 20px auto;
background-position: right 10px center;
padding: 15px 40px 15px 15px;
}
.panel-title>div>span,
.panel-title>div>p {
font-size: 18px;
margin: 0 !important;
}
/* Cleaned the clutter and removed obsolete code */
.panel-title:focus+.panel-body {
background-color: #FEE4CF;
display: block;
border: 1px solid #FEE4CF;
border-top: none;
border-radius: 0 0 6px 6px;
padding: 0 15px 25px;
}
/**/
}
<div class="panel-item">
<a class="panel-title flex-between-center" href="javascript:void(0)">
<div class="flex-center-wrap">
<img src="https://cdn.myshoptet.com/usr/446290.myshoptet.com/user/documents/upload/sablona/ppl.svg"> <span>PPL</span>
</div>
<div><span>99 Kč</span></div>
</a>
<div class="panel-body">
<ul>
<li>Když nakoupíte od 1900 Kč, máte dopravu zdarma. Jinak doručení stojí 99 Kč.</li>
<li>doručení a kontaktem na řidiče pro pohodlnější domluvu.</li>
<li>zkusí to ještě následující pracovní den. Následně váš balík uloží na nejbližší PPL zasielka.</li>
</ul>
</div>
<a class="panel-title flex-between-center" href="javascript:void(0)">
<div class="flex-center-wrap">
<img src="https://cdn.myshoptet.com/usr/446290.myshoptet.com/user/documents/upload/sablona/ppl.svg"> <span>PPL</span>
</div>
<div><span>99 Kč</span></div>
</a>
<div class="panel-body">
<ul>
<li>Když nakoupíte od 1900 Kč, máte dopravu zdarma. Jinak doručení stojí 99 Kč.</li>
<li>doručení a kontaktem na řidiče pro pohodlnější domluvu.</li>
<li>zkusí to ještě následující pracovní den. Následně váš balík uloží na nejbližší PPL zasielka.</li>
</ul>
</div>
</div>

CSS not changing text colour or size when targeting className in react

I'm trying to target the weather-location-container and location to change the text design / colour in CSS.
All my other CSS seems to be working fine. I'm not sure why it isn't working?
Thanks
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.app {
text-align: center;
background-image: url("./assets/376.png");
min-height: 100vh;
display: flex;
flex-direction: column;
}
main {
min-height: 100vh;
padding: 50px;
margin: 75px;
}
.search {
width: 100%;
}
.search .postcode-search-bar {
display: block;
width: 100%;
padding: 15px;
border: none;
background-color: rgba(255, 255, 255, 0.671);
border-radius: 16px 16px 16px 16px;
box-shadow: 3px 3px rgba(0, 0, 0, 0.2);
font-size: 1rem;
text-align: center;
transition: 0.4s ease;
}
.search .postcode-search-bar:focus {
background-color: rgba(255, 255, 255, 0.89);
}
h1::before {
content: "\01F31E";
padding: 10px;
}
h1::after {
content: "\01F30D";
padding: 10px;
}
h1 {
color: rgb(1, 55, 102);
padding: 30px;
}
/* Why isn't the below working? */
.weather-location-container .location {
color: red;
font-size: 3rem;
font-weight: 500;
text-align: center;
}
React
import "./App.css";
function App() {
let date = new Date().toDateString();
date = date.slice(3, 15);
return (
<div className="app">
<main>
<div className="search">
<h1>Local Weather</h1>
<input
type="text"
className="postcode-search-bar"
placeholder="Enter your postcode..."
/>
</div>
<div className="weather-location-container">
<div className="location">London</div>
<div className="date">{date}</div>
</div>
<div className="weather-container">
<div className="temp">8°c</div>
<div className="weather">Cloudy</div>
</div>
</main>
</div>
);
}
export default App;
try to be more specific
main .weather-location-container .location {
color: red;
font-size: 3rem;
font-weight: 500;
text-align: center;
}
The code works. After using the dev tools to inspect the div it showed the London text being in a container that was named something different.
It turns out I didn't save the app.js file - Still learning :)
It all works now.
Thanks to the comments for the tips on how to debug this

Altering background color of button to flow into header on select

I'm trying to altar two buttons (Easy, Hard) on a web app I'm building. I am trying to alter them to remove their borders, and when a button is selected, I want to background to flow up into the header as a visual indication for being selected.
Note: I am linking Bootstrap 4 at the moment.
Current Visual:
Desired Visual:
body {
background-color: #232323;
}
.header {
text-align: center;
color: white;
padding: 1.5rem;
background-color: #66b0c4;
}
.header h1 {
margin: 0;
}
.square {
width: 30%;
background: purple;
padding-bottom: 30%;
float: left;
margin: 1.66%;
}
#container {
max-width: 600px;
margin: 0 auto;
}
#stripe {
background-color: white ;
height: 30px;
text-align: center;
color: black;
}
.selected {
background:#66b0c4;
border: none;
}
<div class="header">
<h1>The Great <br><span id="colorDisplay">RGB</span><be>
Color Game</h1>
</div>
<div id="stripe">
<button id="reset">New Colors</button>
<span id="message"></span>
<button id="easyBtn">Easy</button>
<button id="hardBtn" class="selected">Hard</button>
</div>
I hope this can help you.
body {
background-color: #232323;
}
.header {
text-align: center;
color: white;
padding: 1.5rem;
background-color: #66b0c4;
}
.header h1 {
margin: 0;
}
.square {
width: 30%;
background: purple;
padding-bottom: 30%;
float: left;
margin: 1.66%;
}
#container {
max-width: 600px;
margin: 0 auto;
}
#stripe {
background-color: white ;
height: 30px;
text-align: center;
color: black;
padding-top: 5px;
}
.selected {
background:#66b0c4;
border: 0;
padding: 5px;
position: relative;
}
.selected::before {
position: absolute;
content: '';
top: -10px;
left: 0;
width: 100%;
background-color: #66b0c4;
height: 10px;
}
<div class="header">
<h1>The Great <br><span id="colorDisplay">RGB</span><be>
Color Game</h1>
</div>
<div id="stripe">
<button id="reset">New Colors</button>
<span id="message"></span>
<button id="easyBtn">Easy</button>
<button id="hardBtn" class="selected">Hard</button>
</div>
Solved by adjusting the height of background on the selected class. Also solved the selection issue with
*:focus {
outline: 0 !important;
}
CSS Now:
.selected {
background:#66b0c4;
border: none;
height: 30px;
}
*:focus {
outline: 0 !important;
}

Container with a fullscreen background image in Yii2

I'm trying to get full screen background image for this container:
<div class="header"
<div class="container">
<div class="row">
<div class="col-lg-12">
<h2 class="text-center">test1</h2>
<p class="lead text-center">test2</p>
<p class="text-center"><a class="btn btn-lg btn-success"
href="http://localhost/"><span
class="glyphicon glyphicon-plus"></span> something</a></p>
</div>
</div>
</div>
But, the picture is showing without fullscreen view and i'm trying to get something like this:
http://ironsummitmedia.github.io/startbootstrap-business-frontpage/
and i followed every tutorial for it, but nothing is worked.!
i'm not sure if i'm using Yii2 with this bootstrapmakes any sense.
Btw, this is my site.css
html,
.my-navbar {
background-color: #ffffff;
height: 10px;
border-bottom: 1px solid #eeeeee;
}
body {
height: 100%;
background: #F5F5F5;
}
.footer {
height: 180px;
background-color: white;
border-top: 1px solid #eeeeee;
padding-top: 20px;
}
.wrap {
min-height: 100%;
height: auto;
margin: 0 auto -60px;
padding: 0 0 60px;
}
.wrap > .container {
padding: 70px 15px 20px;
}
.header {
height: 400px;
background: url('../images/header.jpg') no-repeat center center;
min-height:100%;
background-size:100px 150px;
-webkit-background-size: cover;
-moz-background-size: cover;
width: 100%;
-o-background-size: cover;
}
.jumbotron .btn {
font-size: 21px;
padding: 14px 24px;
}
.not-set {
color: #c55;
font-style: italic;
}
/* add sorting icons to gridview sort links */
a.asc:after, a.desc:after {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings', fantasy;
font-style: normal;
font-weight: normal;
line-height: 1;
padding-left: 5px;
}
a.asc:after {
content: /*"\e113"*/ "\e151";
}
a.desc:after {
content: /*"\e114"*/ "\e152";
}
.sort-numerical a.asc:after {
content: "\e153";
}
.sort-numerical a.desc:after {
content: "\e154";
}
.sort-ordinal a.asc:after {
content: "\e155";
}
.sort-ordinal a.desc:after {
content: "\e156";
}
.grid-view th {
white-space: nowrap;
}
.hint-block {
display: block;
margin-top: 5px;
color: #999;
}
.error-summary {
color: #a94442;
background: #fdf7f7;
border-left: 3px solid #eed3d7;
padding: 10px 20px;
margin: 0 0 15px 0;
}
What should i do for achieve full screen background image like this example in header?
http://ironsummitmedia.github.io/startbootstrap-business-frontpage/
Add this to the header css
position: absolute;
top: 0;
left: 0;
right: 0;
It should work now.
Could you try to putt it up as an example on Codepen?
Your div class "header" doesn't have an ending ">" which might be causing some problems.
Try with the following in the CSS where the background img is specified:
background-size:cover;
Add a other class with container class and use background image with cover option. Here i use .bimg for example.
<div class="container bimg"></div>
.bimg{
width:100%;
background:url('PATH');
}