Filepond customize droparea - javascript

Using filepond I need to customize the filepond droparea, meaning that I need to add some custom HTML with some placeholder images to give an idea to the user about what kind of images should be uploaded and should allow multiple uploads.
Is there a way to do this?
I tried to add an absolutely positioned conatiner with the placeholders but I can't cover on upload my custom element.
Here is how I'm using Filepond inside react :
...
return (
<div className="uploads">
<div className="uploads__placeholders">{placeholderImages}</div>
<FilePond
ref={(ref) => (this.pond = ref)}
files={this.state.files}
labelIdle={""}
allowMultiple={true}
maxTotalFileSize={10485760}
acceptedFileTypes={this.props.acceptedFileTypes}
labelMaxTotalFileSize={"Total file size should be lesser than 10MB."}
maxFiles={maxFilesAllowed}
allowProcess={this.props.process ? this.props.process : true}
imagePreviewHeight={135}
//imagePreviewTransparencyIndicator={"grid"}
server={{...}}
onremovefile={(file) => {...}}
oninit={(t) => {...}}
onupdatefiles={(fileItems) => {...}}
/>
</div>
);
...
So I create a custom wrapper and I align with css on top of filepond wrapper but this seems to not be the ideal workaround.

The key answer is to use the labelIdle with beforeAddFile option, which gives you a way to change the default template HTML, and removing any content you want beforehand. You should add it to your Filepond initialisation.
I'm note sure how to remove the content in react, but a jQuery example would be something like this :
FilePond.parse(document.body);
const inputElement = document.querySelector('#file_upload');
FilePond.registerPlugin(FilePondPluginImagePreview);
const pond = FilePond.create(inputElement, {
allowMultiple: true,
imagePreviewHeight: 135,
labelIdle: `
<div style="width:100%;height:100%;">
<p>
Drag & Drop your files or <span class="filepond--label-action" tabindex="0">Browse</span><br>
Some samples to give you an idea :
</p>
</div>
<div class="images" id="allImages">
<div class="images_child">
<img src="https://live.staticflickr.com/4561/38054606355_26429c884f_b.jpg">
</div>
<div class="images_child">
<img src="https://live.staticflickr.com/4561/38054606355_26429c884f_b.jpg">
</div>
<div class="images_child">
<img src="https://live.staticflickr.com/4561/38054606355_26429c884f_b.jpg">
</div>
</div>
`,
beforeAddFile (e) {
$('#allImages').html('');
}
});
.filepond--drop-label {
background-color: #ECF7E9;
height: auto!important;
}
.images {
display: inline-block;
padding: 0 5px;
}
.images_child {
display: contents;
padding: 0 5px;
text-align: center;
}
.filepond--root * {
height: auto;
padding: 0 4px;
}
img {
width: 25%;
opacity: 0.8;
filter: grayscale(100%);
border-radius: 8px;
cursor: pointer;
}
/* Responsive layout - makes a two column-layout instead of four columns */
#media screen and (max-width: 800px) {
.column {
flex: 50%;
max-width: 50%;
}
}
/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 600px) {
.column {
flex: 100%;
max-width: 100%;
}
}
<script src="https://unpkg.com/filepond-plugin-image-preview#4.6.4/dist/filepond-plugin-image-preview.js"></script>
<script src="https://unpkg.com/filepond#4.17.1/dist/filepond.js"></script>
<link rel="stylesheet" type="text/css" media="screen" href="https://unpkg.com/filepond#4.17.1/dist/filepond.css" />
<link rel="stylesheet" type="text/css" media="screen" href="https://unpkg.com/filepond-plugin-image-preview#4.6.4/dist/filepond-plugin-image-preview.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<input type="file" name='file' class='filepond' multiple id='file_upload' />
https://jsfiddle.net/d6e2nh93/
Disclaimers :
1) I didn't NOT do the full CSS as your image example as I see no need to, you can easily do it yourself.
2) This is not a react answer, but an answer to guide you through the right direction on how to use filepond to achieve your desired result.

Related

Javascript works in codepen but not on browser

const toggleButton = document.getElementsByClassName('navbar-toggle')[0];
const navbarLinks = document.getElementsByClassName('navbar-links');
toggleButton.addEventListener('click', function() {
for(var i=0; i<navbarLinks.length; i++)
navbarLinks[i].classList.toggle('active');
});
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
font-family: "Montserrat", sans serif;
}
.navbar ul {
display: flex;
width: 100%;
align-items: center;
background-color: none;
color: black;
}
.navbar li {
list-style-type: none;
padding: 1rem;
}
.navbar a {
text-decoration: none;
}
.navbar-logo {
margin-right: auto;
width: 250px;
height: 150px;
user-select: none;
}
.navbar-toggle {
display: none;
}
.navbar-links:hover {
color: rgba(245, 40, 145, 0.8);
transition: all 0.3s ease 0s;
}
button {
padding: 9px 25px;
color:white;
background-color: rgba(245, 40, 145, 0.8);
border: none;
border-radius: 50px;
cursor: pointer;
transition: all 0.3s ease 0s;
}
button:hover {
background-color: rgba(245, 40, 145, 0.5);
}
#media (max-width: 600px) {
.navbar ul {
flex-wrap: wrap;
}
.navbar-toggle {
display: block;
cursor:pointer;
}
.navbar-links {
display: none;
width: 100%;
text-align: center;
}
.active {
display: block;
}
}
.slideshow {
max-width: auto;
height: 600px;
display: block;
position: relative;
overflow: hidden;
}
img.mySlides {
max-width: 100%;
max-height: 100%;
display: block;
object-fit: cover;
top: 0;
left: 0;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>KK Beauty Parlor </title>
<link rel="stylesheet" href="CSS/homestyle.css">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/3/w3.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght#400;500;600;700;800&display=swap" rel="stylesheet">
<script src="https://kit.fontawesome.com/a37ae7cae6.js" crossorigin="anonymous"></script>
<script src="JS/myScript.js"></script>
</head>
<body>
<nav class="navbar">
<ul>
<img class="navbar-logo" src="images/KKLogo.svg">
<li class="navbar-toggle"><i class="fa-solid fa-bars"></i></li>
<li class="navbar-links">Home</li>
<li class="navbar-links">Products</li>
<li class="navbar-links">Services</li>
<li class="navbar-links">Appointments</li>
<li class="navbar-links">Learn More</li>
<li class="navbar-links"><button>Login</button></li>
<li class="navbar-links"><button>Register</button></li>
</ul>
</nav>
<section class="slideshow">
<img class="mySlides" src="images/slideshow1.jpg" style="width:100%">
<img class="mySlides" src="images/slideshow2.jpg" style="width:100%">
<img class="mySlides" src="images/slideshow3.jpg" style="width:100%">
<img class="mySlides" src="images/slideshow4.jpg" style="width:100%">
</section>
<script>
// Automatic Slideshow - change image every 3 seconds
var myIndex = 0;
carousel();
function carousel() {
var i;
var x = document.getElementsByClassName("mySlides");
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
myIndex++;
if (myIndex > x.length) {myIndex = 1}
x[myIndex-1].style.display = "block";
setTimeout(carousel, 3000);
}
</script>
</body>
</html>
In the snippet, the hamburger icon does what its supposed to do, however, when I try to run it locally on my browser the hamburger icon doesn't work at all. Has anyone ever had an issue with this? Not sure why it's happening or how to fix it. Any ideas/advice? I'm working inside of Visual Studio Code and have tried both Safari and Google Chrome as a browser. JavaScript is enabled in both.
Your JavaScript is loading before the HTML does, which means that the following code will be undefined, as it doesn't exist yet.
console.log(document.getElementsByClassName('navbar-toggle')[0]);
<!-- It's like there's nothing here for JavaScript! -->
To fix this, you can do two things.
You can add the JavaScript at the end of the <body> tag. This makes the JavaScript load after all of the HTML has, as HTML loads line by line.
<body>
<!-- Some HTML here... -->
<script src="JS/myScript.js"></script>
</body>
If you want to leave the JavaScript in the <head>, then you can add the defer attribute.
According to MDN...
This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded.
So, you can simply change your code to below.
<head>
<!-- Some HTML here... -->
<script defer src="JS/myScript.js"></script>
</head>
Both of these will work, but it's up to you what you want to do.
I think it is happening because you're importing js file in the head tag. And that's why it is getting rendered before the HTML code does. And because of that the values of toggleButton and navbarLinks will be undefined.
So try moving your js import at the bottom after the body tag.
<body>...</body>
<script src="https://kit.fontawesome.com/a37ae7cae6.js" crossorigin="anonymous"></script>
<script src="JS/myScript.js"></script>
What is actually happening here...
First the page started loading.Then it found the js. it executes js when you are in head tag. but your elements are inside the body that isn't loaded yet. So the script found nothing.
const toggleButton = document.getElementsByClassName('navbar-toggle')[0];
const navbarLinks = document.getElementsByClassName('navbar-links');
Here:
toggleButton = undefined;
navbarLinks = undefined;
This means you don't have navbarLinks and toggleButton. Then it will never work.
To solve this you need to execute this javascript code after these elements.
It is better to use script tag just before the end of body tag or inside head tag using defer or async attribute.
In codepen or codeply this is automatically configured.
// Tips:
Why are you using ....
document.getElementsByClassName('navbar-toggle')[0]
Try this:
document.querySelector('.navbar-toggle')
Docs: https://www.w3schools.com/jsref/met_document_queryselector.asp
There are many ways to select an element.
document.getElementById()
document.getElementsByClassName()
document.getElementsByName()
document.getElementsByTagName()
document.querySelector()
document.querySelectorAll()
Here is an example.
<section class="parent-class" id="parent-id">
<div class="child">
</div>
<div class=child2>
</div>
</section>
If you want to select the child div using getElementById, then you can't do this normally because the div has no id.
getElementById finds just one element that contains all the id given here.
document.getElementById('a b c')
it will find an element that has a,b and c id.
Thinking using getElementsByClassName? Well you can do this, but if you want to select a div that is under a section then again you can't do this. It also works similar with id, it find an element with all the class names given here. there is also a big problem. this returns an array not a single element.
getElementsByName, getElementsByTagName are also similar, these find all elements with the tag given here. But querySelector querySelectorAll is a magic. It works similar with css.
document.querySelector('#parent-id .child'); // <div class='child'> document.querySelector('.parent-class .child'); // <div class='child'> document.querySelector('.child'); // <div class='child'> document.querySelector('.child2'); // <div class='child2'> document.querySelectorAll('#parent-id div'); // [div,div] document.querySelectorAll('.parent-class div'); // [div,div]
https://www.w3schools.com/jsref/met_document_getelementbyid.asp https://www.w3schools.com/jsref/met_document_getelementsbyclassname.asp https://www.w3schools.com/jsref/met_doc_getelementsbyname.asp https://www.w3schools.com/jsref/met_document_getelementsbytagname.asp https://www.w3schools.com/jsref/met_document_queryselector.asp https://www.w3schools.com/jsref/met_document_queryselectorall.asp

Can this be achieved without js?

I have this image gallery which I want to do without the javascript. Can this be done without using the javascript ?? Just need the big picture to change when mouseover or something similar.
function myFunction(imgs) {
var expandImg = document.getElementById('expandedImg')
var imgText = document.getElementById('imgtext')
expandImg.src = imgs.src
imgText.innerHTML = imgs.alt
expandImg.parentElement.style.display = 'block'
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial;
}
/* The grid: Four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
padding: 10px;
}
/* Style the images inside the grid */
.column img {
opacity: 0.8;
cursor: pointer;
}
.column img:hover {
opacity: 1;
}
/* Clear floats after the columns */
.row:after {
content: '';
display: table;
clear: both;
}
/* The expanding image container */
.container {
position: relative;
display: none;
}
/* Expanding image text */
#imgtext {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: white;
font-size: 35px;
cursor: pointer;
}
<div style="text-align: center">
<h2>Tabbed Image Gallery</h2>
<p>Click on the images below:</p>
</div>
<!-- The four columns -->
<div class="row">
<div class="column">
<img src="img_nature.jpg" alt="Nature" style="width: 100%" onclick="myFunction(this);" />
</div>
<div class="column">
<img src="img_snow.jpg" alt="Snow" style="width: 100%" onclick="myFunction(this);" />
</div>
<div class="column">
<img src="img_mountains.jpg" alt="Mountains" style="width: 100%" onclick="myFunction(this);" />
</div>
<div class="column">
<img src="img_lights.jpg" alt="Lights" style="width: 100%" onclick="myFunction(this);" />
</div>
</div>
<div class="container">
<span onclick="this.parentElement.style.display='none'" class="closebtn">×</span
>
<img id="expandedImg" style="width: 100%" />
<div id="imgtext"></div>
</div>
Any help is appreciated. Sorry for adding this text as StackOverflow won't let me post this without adding more text.
Thanks in advance.
Preface
Though not impossible, I nonetheless highly recommend using JavaScript instead of CSS for this task. You should not see the following content of this answer as an alternative to JavaScript's intended purpose, but see this as a playful "solution".
Another big point to use JavaScript instead of CSS is: Using CSS for this task is not accessible at all. You should always strive to make good, easy-to-use and accessible websites.
You should especially refrain from using this in a business environment for the aforementioned reason.
CSS-only solution
Necessary HTML changes
Since CSS is cascading, the image-previews need to come before either the big image itself or its ancestor. You can imagine this like this: The HTML is a tree, and effects are only carried through down to the leaves, but cannot affect neighbouring branches as that would require backtracking at some point.
In code, this could look like this:
<!-- Either this (case 1): -->
<img class="img-preview">
<img class="big-img">
<!-- Or this (case 2): -->
<img class="img-preview">
<div>
<img class="big-img"> <!-- May be nested deeper -->
</div>
The CSS
The CSS should be relatively simple. The only issue is, that for each image-preview, a new CSS-rule needs to be added. This makes adding a new image-preview a bit more work in the future, but more importantly: It crams your CSS full with unnecessary rules! This will probably result in unused CSS-rules in case you'll rewrite some, and will hinder maintenance and readability heavily.
Friendly reminder: This should better be done by using JavaScript!
CSS' :hover-pseudo-class is effectively the same as JS' mouseover. Using this and the general sibling-combinator ~ (and potentially the descendant combinator ), we can override the big image's background-image-property depending on the image-preview that is hovered:
/* Either this (case 1): */
.img-preview:hover~.big-img {/* ... */}
/* Or this (case 2): */
.img-preview:hover~* .big-img {/* ... */}
As I have already mentioned, every image-preview requires its own CSS-rule. This is because CSS cannot use HTML-attributes for its properties (except for pseudo-elements and their content-property, I think).
This means, the CSS could look like this for the current HTML:
/* The CSS */
.img-preview[data-src="https://picsum.photos/id/10/64/64"]:hover~.big-img {
background-image: url("https://picsum.photos/id/10/64/64");
}
.img-preview[data-src="https://picsum.photos/id/1002/64/64"]:hover~.big-img {
background-image: url("https://picsum.photos/id/1002/64/64");
}
/* etc. */
/* Ignore; for styling only */
img {border: 1px solid black}
.img-preview {
width: 2rem;
height: 2rem;
}
.big-img {
width: 4rem;
height: 4rem;
}
<img class="img-preview"
src="https://picsum.photos/id/10/32/32"
data-src="https://picsum.photos/id/10/64/64">
<img class="img-preview"
src="https://picsum.photos/id/1002/32/32"
data-src="https://picsum.photos/id/1002/64/64">
<!-- etc. -->
<img class="big-img">
(Sidenote: I used attribute-selectors here, but the same thing could be done using IDs or similar, as long as every image-preview can be selected individually.)
Endnote
Adding text-descriptions while hovering may be solved in a similar fashion, but is left as a task.
Unfortunately, the big image won't stay when using this approach. If you want it to stay, you should take a look at Abd Elbeltaji's answer. They use <input>- and <label>-tags to accomplish that, together with CSS' :checked-pseudo-class.
Despite looking so, changing the HTML as shown does not restrict you in how you can style your elements, especially when using FlexBox or CSS Grid. Not only do they make styling easier, they are also meant to easily make a website responsive.
Accessibility
Again: This is not an accessible solution! This whole task should certainly be handled by JavaScript.
Should this be a public website, then I advise adding alt-descriptions for every image, even the previews. Unfortunately updating the big image's alt-attribute via CSS is impossible, making it inaccessible, which in turn harms your SEO. This being said, I commend your effort in displaying the image's alt-attribute in your original code, though not perfect. You might want to take a look at <figure>.
While we're at it: I'd also advise learning some semantic HTML-tags for the purpose of accessibility.
Pseudo-elements (::after, ::before, etc.) are also inaccessible. You should not use them to contain any relevant information/text. Though they may be used for styling-purposes in every imaginable way.
Yes, you can achieve the same behavior without the use of javascript, you may use the concept of input elements (checkbox for single toggle value, radio for multiple select values) as adjacent siblings to your elements that they should be affected of the input, and by utilizing the :checked pseudo selector for inputs in css, in a compination with the adjacent sibling selector ~ you can affect the desired elements when the input is checked. You can also use labels which will allow you to hide your inputs and trigger their values with whatever is inside your label.
// No JS!
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial;
}
/* The grid: Four equal columns that floats next to each other */
.column {
float: left;
width: 25%;
padding: 10px;
}
/* Style the images inside the grid */
.column img {
opacity: 0.8;
cursor: pointer;
}
.column img:hover {
opacity: 1;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* The expanding image container */
.container {
position: relative;
}
/* Expanding image text */
#imgtext::after {
position: absolute;
bottom: 15px;
left: 15px;
color: white;
font-size: 20px;
}
/* Closable button inside the expanded image */
.closebtn {
position: absolute;
top: 10px;
right: 15px;
color: white;
font-size: 35px;
cursor: pointer;
}
.container .img {
height: 500px;
width: 100%;
background-image: url(https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
background-size: cover;
}
/* Tab select */
input[name=tabSelect],
#hideImage {
display: none;
}
#tabSelect1:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect2:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/869258/pexels-photo-869258.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect3:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/1183021/pexels-photo-1183021.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect4:checked~div.container .img {
background-image: url(https://images.pexels.com/photos/1124960/pexels-photo-1124960.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940);
}
#tabSelect1:checked~div.container #imgtext::after {
content: "Nature";
}
#tabSelect2:checked~div.container #imgtext::after {
content: "Snow";
}
#tabSelect3:checked~div.container #imgtext::after {
content: "Mountains";
}
#tabSelect4:checked~div.container #imgtext::after {
content: "Lights";
}
/* image hide btn */
#hideImage:checked~div.container {
display: none;
}
<div style="text-align:center">
<h2>Tabbed Image Gallery</h2>
<p>Click on the images below:</p>
</div>
<input type="radio" name="tabSelect" id="tabSelect1">
<input type="radio" name="tabSelect" id="tabSelect2">
<input type="radio" name="tabSelect" id="tabSelect3">
<input type="radio" name="tabSelect" id="tabSelect4">
<!-- The four columns -->
<div class="row">
<div class="column">
<label for="tabSelect1">
<img src="https://images.pexels.com/photos/15286/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Nature" style="width:100%">
</label>
</div>
<div class="column">
<label for="tabSelect2">
<img src="https://images.pexels.com/photos/869258/pexels-photo-869258.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Snow" style="width:100%">
</label>
</div>
<div class="column">
<label for="tabSelect3">
<img src="https://images.pexels.com/photos/1183021/pexels-photo-1183021.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Mountains" style="width:100%">
</label>
</div>
<div class="column">
<label for="tabSelect4">
<img src="https://images.pexels.com/photos/1124960/pexels-photo-1124960.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940" alt="Lights" style="width:100%">
</label>
</div>
</div>
<input type="checkbox" id="hideImage">
<div class="container">
<label for="hideImage" class="closebtn">×</label>
<div class="img"></div>
<div id="imgtext"></div>
</div>
Here is a working example in: JSFiddle
Note! this approach is not optimal and would be tricky to expand in case you need to add more values.
PS: I had to change the images since the ones provided in your code do not exist.

Show div when post has class

Update
I'd modded the CSS given by David Thomas a bit. Its now a banner.
.div.popular::before {
/* setting the default styles for
the generated content: */
display: block;
width: 10em;
height: 2em;
line-height: 2em;
text-align: center;
background: #F60;
color: #fff;
font-size: 1.4rem;
position: absolute;
top: 30px;
right: 0px;
z-index: 1;
}
I would like to make a folded corner sort of like in this post: Folded banner using css
--- Original post ---
Let me first explain what I'm trying to do. I'm trying to give some post some extra attention by making a little circle with some call-to-action text in it.
But I only want this to trigger when a div has a specific class.
So if the div the class populair or sale I would like to have a little circle show up on that post. This script what I am using right now.
$(document).ready(function($){
if($("#front-page-items").hasClass('populair')){
$(".populair-div").show();
}
if($("#front-page-items").hasClass('sale')){
$(".sale-div").show();
}
});
And this HTML:
<div class="populair-div" style="display:none;">
<strong>Populair</strong>
</div>
<div class="sale-div" style="display:none;">
<strong>Sale</strong>
</div>
But this only show's the populair-div and not the other one. I'm guessing my script is wrong. Should I use else for all the other call-to-action classes?
$(document).ready(function($){
if($("#front-page-items").hasClass('populair')){
$(".populair-div").show();
}
else($("#front-page-items").hasClass('sale')){
$(".sale-div").show();
}
else($("#front-page-items").hasClass('Free')){
$(".free-div").show();
} // and so on
});
Is there someone that could help me out? Also is it possible to echo the div so I don't have to write a whole div for every call-to-action div?
For something like this, where the displayed text is explicitly linked to the class-name of the element it's easiest to use CSS and the generated content available, effectively hiding the elements you don't wish to show by default and then explicitly allowing elements you want to show, along with the generated content of those elements (using the ::before and ::after pseudo-elements:
div {
/* preventing <div> elements
from showing by default: */
display: none;
}
div.populair-div,
div.sale-div {
/* ensuring that elements matching
the selectors above (<div>
elements with either the 'sale-div'
or 'populair-div' class-names
are shown: */
display: block;
}
div.populair-div::before,
div.sale-div::before {
/* setting the default styles for
the generated content: */
display: block;
width: 4em;
height: 4em;
line-height: 4em;
text-align: center;
border: 3px solid transparent;
border-radius: 50%;
}
div.populair-div::before {
/* setting the text with the
"content" property: */
content: "Popular";
/* providing a specific colour
for the generated contents'
border: */
border-color: #0c0;
}
div.sale-div::before {
content: "Sale";
border-color: #f90;
}
/* entirely irrelevant, just so you can
see a (slightly prettified) difference
should you remove the default display
property for the <div> elements: */
code {
background-color: #ddd;
}
em {
font-style: italic;
}
<div class="neither-popular-nor-sale">
<p>
This element should not be shown, it has neither a class of <code>"populair-div"</code> <em>or</em> <code>"sale-div"</code>.
</p>
</div>
<div class="populair-div">
</div>
<div>Also not to be shown.</div>
<div class="sale-div">
</div>
You can use toggle function for this. It will be shorter and clearer.
Display or hide the matched elements.
Note: The buttons is for tests.
$(document).ready(function($){
init();
});
function init() {
$(".populair-div").toggle($("#front-page-items").hasClass('populair'));
$(".sale-div").toggle($("#front-page-items").hasClass('sale'));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="front-page-items" class="populair sale"></div>
<div class="populair-div">populair-div</div>
<div class="sale-div">sale-div</div>
<hr />
<button onclick="document.getElementById('front-page-items').classList.toggle('populair');init()">toggle populair</button>
<button onclick="document.getElementById('front-page-items').classList.toggle('sale');init()">toggle sale</button>

Fix navbar to top of page when scrolling

I'm trying to make a navbar similar to the one on Linus Tech tips (https://linustechtips.com/main/) for a school assignment. I'm at the real basic level of Javascript and I cooked up a pinnable navbar but when I made it there was no banner above it. Now there is a banner above it and I don't know how to make the navbar push to the top when I start scrolling.
Here is my HTML:
<div class="navContainer">
<div class="topBanner">
<img src="images/topbanner.png" id="topBannerimg"/>
</div>
<div id="navbar">
<button onclick="pinfunc()"><i id="pin" class="fa fa-thumb-tack fa-2x navButton" id="pinbtn" aria-hidden="true"></i></button>
</div>
</div>
Here is my Javascript:
var pinned = 1;
console.log(pinned);
function pinfunc() {
if (pinned == 1) {
document.getElementById("navbar").style.position= "relative";
document.getElementById("pin").style.color = "black";
document.getElementById("pin").style.transform = "rotate(0deg)";
pinned=0;
}
else if (pinned == 0) {
document.getElementById("navbar").style.position="fixed";
document.getElementById("pin").style.color = "red";
document.getElementById("pin").style.transform = "rotate(270deg)";
pinned=1;
}
}
And here is my CSS:
body{
margin: 0 auto;
}
.navContainer{
width: 100%;
margin: 0 auto;
}
#topBannerimg{
width: 100%;
margin: 0;
display:block
}
.navButton{
height: 25px;
width: 25px;
}
.fa-thumb-tack{
font-size: 50px;
color: red;
transform: rotate(270deg);
}
.container{
height: 1000px;
width: 90%;
margin: 0 auto;
}
#navbar{
height: 50px;
width: 100%;
position: fixed;
margin: 0 auto;
background-color: #D35300;
}
#nav{
background-color: #D35300;
height: 50px;
}
I'm just looking to create a basic one of the LTT forum - no need for the toggle button to fade out or anything.
This is my first post so I'm not 100% sure how to do stuff.
Thanks in advance.
If you are allowed to use external JS or CSS libraries, then try the Affix plugin for bootstrap. (link: http://www.w3schools.com/bootstrap/bootstrap_affix.asp). It makes what you are trying to accomplish simple.
If you are not allowed to use any external libraries then, I suggest you read this: http://getbootstrap.com/javascript/#affix-examples and try to implement it yourself.
Good Luck!
So I got it working with the following HTML, JS, and CSS files:
HTML
<html>
<head>
<link rel="stylesheet" href="path/to/font-awesome.css/file" type="text/css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<!-- Custom CSS File Below -->
<link href="/path/to/custom/css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="topBanner">
<img src="images/topbanner.png" id="topBannerimg"/>
</div>
<div id="navbar" data-spy="affix" data-offset-top="100">
<button onclick="pinfunc()"><i id="pin" class="fa fa-thumb-tack fa-2x navButton" aria-hidden="true"></i></button>
</div>
<div id="SpaceFiller"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="path/to/custom/js/file"></script>
</body>
</html>
The key things to learn from this HTML are the loading the JS files at the bottom of the body tag so the page can load first, and the order in which the CSS and JS files are loaded. The SpacFiller div is just there to enable scrolling. Also, note that I removed your navbar-container as it didn't seem necessary.
Javascript
var pinned = true;
function pinfunc() {
var $pin = $("#pin");
var $navbar = $("#navbar");
if (pinned) {
$pin.css({
'color': 'black',
'transform': 'rotate(0deg)'
});
console.log("not pinned")
$(window).off('.affix');
$navbar.removeClass('affix affix-top affix-bottom');
$navbar.removeData("bs.affix");
pinned = false;
} else {
$pin.css({
'color': 'red',
'transform': 'rotate(270deg)'
});
$(window).on('.affix');
$navbar.addClass('affix');
$navbar.affix({
offset: 100
});
pinned= true;
}
}
This JS uses jQuery Selectors (which actually uses sizzle.js I believe) to get access to HTML elements via their IDs. Using the returned jQuery object, the function sets the appropriate CSS and then toggles affix using functions you can read about here: http://getbootstrap.com/javascript/#affix, https://api.jquery.com/removeclass/, https://api.jquery.com/jQuery.removeData/, http://api.jquery.com/off/. Also, you were using 0 and 1 for the pinned values but it is good practice to use boolean values (true and false) as shown.
CSS
body{
margin: 0 auto;
}
.affix {
top: 0;
width: 100%;
}
.affix + .container-fluid {
padding-top: 70px;
}
#topBannerimg{
width: 100%;
margin: 0;
display:block;
height: 100px;
top: 0px;
}
.navButton{
height: 25px;
width: 25px;
}
.fa-thumb-tack{
font-size: 50px;
color: red;
transform: rotate(270deg);
}
#navbar{
height: 50px;
width: 100%;
margin: 0 auto;
background-color: #D35300;
}
#SpaceFiller {
height: 10000px;
background-color: darkgreen;
}
I think the CSS is self-explanatory, but if it is unclear go ahead and ask for clarification. Hope this helps! :D
Edit: You can also put the onclick attribute on the i tag itself and get rid of the button wrapper if you want to get rid of the white button background.

Image responsiveness

I am using a content slider to display content on mostly mobile devices, and the majority of my content are images.
The slides of the content slider are placed inside a wrapper (.swiper-wrapper), which is set to take 100% of the screen size.
The issue I am having is that the images are not resizing correctly according to screen size and the images are cut off when I go to landscape mode. In other words, my images are not being responsive.
I tried width:100% and height:auto and it still doesn't work.
CSS
.swiper-container {
display: block; !important;
margin: 0 auto; !important;
width: 100%; !important;
background-color: #222;
color: white;
}
.swiper-slide {
max-width:100%;
height:auto;
position: relative;
display:block;
margin:0 auto;
padding-right: 15px;
padding-left: 15px;
}
.swiper-slide img{
width:100% !important;
height:100% !important;
display:block;
}
HTML
<div class="swiper-container">
<!-- Build the content slides dynamically|databound -->
<div id="slides" class="swiper-wrapper">
<div class="swiper-slide">
<img src='img/gallery-9.jpg' alt='YOLO' />
</div>
</div>
<div class="swiper-slide ">
<div>Image 2</div>
<img src='img/gallery-4.jpg' alt='YOLO'/>
</div>
</div>
<script type="text/javascript" src="js/idangerous.swiper-2.1.min.js"></script>
<script type="text/javascript" src="js/jquery-1.10.1.min.js"></script>
<script>
var mySwiper = new Swiper('.swiper-container',{
speed : 400,
freeMode : true,
freeModeFluid : true,
centeredSlides : true,
resizeReInit : true,
resistance : '100%',
pagination: '.pagination',
paginationClickable: true
});
$(window).resize(function(){
var height = $(window).height();
var width = $(window).width();
$('.swiper-container, .swiper-slide').height(height);
$('.swiper-container, .swiper-slide').width(width);
//Add reInit, because jQuery's resize event handler may occur earlier than Swiper's one
mySwiper.reInit()
})
$(window).resize();
</script>
Setting the below properties for the element will make the image responsive
.swiper-slide img{
max-width:100%;height:auto;
}
Using Normalize.css should fix that problem.
Just use this CSS if you don't want to use all of Normalize.css:
html {
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
If that doesn't work, adding this in the head should fix it:
<meta name="viewport" content="width=device-width,minimum-scale=0.8,initial-scale=1,maximum-scale=1.2" />
This will also mostly disable zooming in/out on the page.
Don't try to set both the width & height of the image. Just set any one and the other will be set accordingly depending on the aspect ration of the image.
.swiper-slide img{
width:100% !important;
display:block;
}

Categories