function count() {
var para = document.getElementById("myInput");
var result = document.getElementById("result");
if (para.value === "") {
alert("Enter text!");
} else {
var str = para.value;
var c = 0;
for (var i = 0; i < str.length; i++) {
str[i] = str[i].toLowerCase();
if (str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u') {
c++;
}
}
result.innerHTML = "The number of vowels = " + c;
}
}
body {
font-family: 'helvetica';
text-align: center;
background-color: cadetblue;
}
* {
box-sizing: border-box;
}
h1 {
color: white;
margin-top: 50px;
font-family: 'Montserrat';
font-size: 40px;
}
#container {
width: 50%;
margin-top: 50px;
margin-left: 25%;
margin-right: 50%;
background-color: #f5f5f5;
border-radius: 10px;
box-shadow: 0 0 10px #505050;
}
#header {
padding: 30px 40px;
text-align: center;
}
#header:after {
content: "";
display: table;
clear: both;
}
input {
margin: 0;
border-radius: 0;
width: 75%;
padding: 10px;
float: left;
font-size: 16px;
border: 0.1px solid #ddd;
border-right: none;
}
#myBtn {
padding: 10px;
width: 25%;
background-color: cadetblue;
opacity: 0.8;
color: white;
float: left;
text-align: center;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
border-radius: 0;
border: 0.1px solid #ddd;
border-left: none;
}
#myBtn:hover {
opacity: 1;
}
#result {
padding-left: 40px;
text-align: left;
font-size: 25px;
}
<h1>Vowel Counter</h1>
<div id="container">
<div id="header">
<input type="text" id="myInput" placeholder="Enter text...">
<button onclick="count()" id="myBtn">Go</button>
</div>
<p id="result"></p>
</div>
The text is entered in the input and when the button is clicked, I want the number of vowels to be displayed in the paragraph by changing its innerHTML. Where am I going wrong? I want to use javascript only. I tried doing it by taking a string and checking each of its character. If it is a vowel then increment the value of c.
You are setting the p#result to be display none here.
#result {
display: none;
padding-left: 40px;
text-align: left;
font-size: 25px;
}
You need to change the style to display: block once the user clicks on the button.
result.style.display= 'block';
<html>
<head>
<title>Vowel Counter</title>
<link type="text/css" href="https://fonts.googleapis.com/css2?family=Commissioner&family=Montserrat&family=Roboto&display=swap" rel="stylesheet">
<style type="text/css">
body
{
font-family: 'helvetica';
text-align: center;
background-color: cadetblue;
}
*
{
box-sizing: border-box;
}
h1
{
color: white;
margin-top: 50px;
font-family: 'Montserrat';
font-size: 40px;
}
#container
{
width: 50%;
margin-top: 50px;
margin-left: 25%;
margin-right: 50%;
background-color: #f5f5f5;
border-radius: 10px;
box-shadow: 0 0 10px #505050;
}
#header
{
padding: 30px 40px;
text-align: center;
}
#header:after
{
content: "";
display: table;
clear: both;
}
input
{
margin: 0;
border-radius: 0;
width: 75%;
padding: 10px;
float: left;
font-size: 16px;
border: 0.1px solid #ddd;
border-right: none;
}
#myBtn
{
padding: 10px;
width: 25%;
background-color: cadetblue;
opacity: 0.8;
color: white;
float: left;
text-align: center;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
border-radius: 0;
border: 0.1px solid #ddd;
border-left: none;
}
#myBtn:hover
{
opacity: 1;
}
#result
{
display: none;
padding-left: 40px;
text-align: left;
font-size: 25px;
}
</style>
</head>
<body>
<h1>Vowel Counter</h1>
<div id="container">
<div id="header">
<input type="text" id="myInput" placeholder="Enter text...">
<button onclick="count()" id="myBtn">Go</button>
</div>
<p id="result"></p>
</div>
<script type="text/javascript">
function count()
{
var para = document.getElementById("myInput");
var result = document.getElementById("result");
if(para.value === "")
{
alert("Enter text!");
}
else
{
var str = para.value;
var c = 0;
for(var i=0; i<str.length; i++)
{
str[i] = str[i].toLowerCase();
if(str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u')
{
c++;
}
}
result.innerHTML = "The number of vowels = " + c;
result.style.display= 'block';
}
}
</script>
</body>
</html>
Your code works. This is your mistake :
#result {
display: none;
}
Fix :
result.style.display = "block";
Also you can count the vowels with a regex :
const vowelsCount = "some string with vowels".match(/a|e|i|o|u/ig).length
As #sabbir mentioned you need to change the style of paragraph to make it visible to show the result. Along with that your can also improve the count method using javascript regex like below. In this regex we are only match the vowels from the given string and will return an array contains all the vowels and then you can count the length of array which only contains the vowels.
function count() {
var para = document.getElementById("myInput");
var result = document.getElementById("result");
if (para.value === "") {
alert("Enter text!");
} else {
var str = para.value.match(/[aeiou]/g);
result.innerHTML = "The number of vowels = " + str.length;
result.style.display = 'block';
}
}
Related
I have an search bar which is working perfectly.
But getting an issue. I want only 5 results to be vsible at a time and other results should be seen by sliding from the slider.
For example if it contains 10 results. Then is shoould show ony 5 on searching and to see other user can sllide from the slidebar....
here is my code
function filterFunction() {
let isInputAvail = false;
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toLowerCase();
if (filter.length > 0) {
document.getElementById("myDropdown").classList.add("show");
} else {
document.getElementById("myDropdown").classList.remove("show");
}
div = document.getElementById("myDropdown");
a = div.getElementsByTagName("a");
for (i = 0; i < a.length; i++) {
txtValue = a[i].innerText;
if (txtValue.toLowerCase().indexOf(filter) > -1) {
isInputAvail = true;
a[i].style.display = "block";
} else {
a[i].style.display = "none";
}
}
if (!isInputAvail) {
document.getElementById("noMatches").classList.add('show');
} else {
document.getElementById("noMatches").classList.remove('show');
}
}
.div {
display: none;
}
.dropbtn {
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
border-radius: 25px;
}
#myInput {
box-sizing: border-box;
background-position: 14px 12px;
background-repeat: no-repeat;
font-size: 16px;
padding: 14px 20px 12px 45px;
border: 5px solid #ddd;
border-radius: 25px;
}
#myInput:focus {
outline: 4px solid #f2f2f2;
border-color: #171313;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f6f6f6;
min-width: 230px;
overflow: auto;
border: none;
z-index: 1;
border-radius: 25px;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {
background-color: #ddd;
}
.show {
display: block;
}
<div class="dropdown">
<input type="text" class="dropbtn" placeholder="Search Here..." id="myInput" onInput="filterFunction()">
<div id="myDropdown" class="dropdown-content">
Result 1
Result 2
Result 3
Result 4
Result 5
Result 6
Result 7
Result 8
Result 9
Result 10
Result 11
Result 12
Result 13
Result 14
Result 15
</div>
<div id="noMatches" class="dropdown-content">
No Matches
</div>
</div>
Here i want that when i write result then all the matching result is shown but that show a huge list. I want to make it to show ony 5 result and there should be a slidebar at right side from which on sliding other results can be seen.
Hope you got my point.
Thanks in advance.
Check out this snippet:
function filterFunction() {
let isInputAvail = false;
var input, filter, ul, li, a, i;
input = document.getElementById("myInput");
filter = input.value.toLowerCase();
if (filter.length > 0) {
document.getElementById("myDropdown").classList.add("show");
} else {
document.getElementById("myDropdown").classList.remove("show");
}
div = document.getElementById("myDropdown");
a = div.getElementsByTagName("a");
for (i = 0; i < a.length; i++) {
txtValue = a[i].innerText;
if (txtValue.toLowerCase().indexOf(filter) > -1) {
isInputAvail = true;
a[i].style.display = "block";
} else {
a[i].style.display = "none";
}
}
if (!isInputAvail) {
document.getElementById("noMatches").classList.add('show');
} else {
document.getElementById("noMatches").classList.remove('show');
}
}
.div {
display: none;
}
.dropbtn {
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
border-radius: 25px;
}
#myInput {
box-sizing: border-box;
background-position: 14px 12px;
background-repeat: no-repeat;
font-size: 16px;
padding: 14px 20px 12px 45px;
border: 5px solid #ddd;
border-radius: 25px;
}
#myInput:focus {
outline: 4px solid #f2f2f2;
border-color: #171313;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
max-height: 215px;
display: none;
position: absolute;
background-color: #f6f6f6;
min-width: 230px;
overflow-y: scroll;
border: none;
z-index: 1;
border-radius: 25px;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {
background-color: #ddd;
}
.show {
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Test</title>
</head>
<body>
<div class="dropdown">
<input type="text" class="dropbtn" placeholder="Search Here..." id="myInput" onInput="filterFunction()">
<div id="myDropdown" class="dropdown-content">
Result 1
Result 2
Result 3
Result 4
Result 5
Result 6
Result 7
Result 8
Result 9
Result 10
Result 11
Result 12
Result 13
Result 14
Result 15
</div>
<div id="noMatches" class="dropdown-content">
No Matches
</div>
</div>
</body>
</html>
I have limited maximum height of .dropdown-content using max-height property and set vertical overflow to scroll using overflow-y: scroll;. Removed overflow: auto from .dropdown-content.
Don't use IDs, programming should be writing reusable code.
To show the dropdowns or to switch the list/no-matches, use two classes on the parent element ("hasvalue" and "nomatch"), the rest is all pure CSS and the :focus selector
Use CSS max-height to limit the height of your overflow element
UI/UX tip: half-cut the last list word, to additionally give the user a clue that there's more items in the scrollable element.
function dropdown(EL) {
const EL_input = EL.querySelector(".dropdown-input");
const ELS_li = EL.querySelectorAll(".dropdown-box--list a");
const filter = () => {
const val = EL_input.value.trim().toLowerCase();
const fil = [...ELS_li].filter(el => {
const match = el.textContent.trim().toLowerCase().includes(val);
el.classList.toggle("hide", !match);
return match;
});
EL.classList.toggle("hasvalue", val.length);
EL.classList.toggle("nomatch", val.length && !fil.length);
};
EL_input.addEventListener("input", filter);
EL_input.addEventListener("focus", filter);
ELS_li.forEach(el => el.addEventListener("mousedown", () => {
EL_input.value = el.textContent.trim()
}));
}
document.querySelectorAll(".dropdown").forEach(el => dropdown(el));
/* QuickReset */ * {margin: 0; box-sizing: border-box;}
/* DROPDOWN COMPONENT */
.dropdown {
--item-height: 30px;
--visible: 5;
font-family: sans-serif;
position: relative;
display: inline-block;
}
.dropdown-input {
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
font-size: 16px;
padding: 15px 20px;
border: 5px solid #ddd;
border-radius: 25px;
background: #fff;
}
.dropdown-input:focus {
outline: none;
border-color: #000;
}
.dropdown.hasvalue .dropdown-input:focus {
border-bottom: 1px solid #ddd;
border-radius: 25px 25px 0 0;
}
.dropdown-box {
display: none;
position: absolute;
top: 100%;
z-index: 1;
min-width: 100%;
overflow: auto;
border-radius: 0 0 10px 10px;
max-height: calc(var(--item-height) * var(--visible));
border: 5px solid #000;
border-top: 0;
}
.dropdown.hasvalue .dropdown-input:focus~.dropdown-box--list {
display: block;
}
.dropdown.nomatch .dropdown-input:focus~.dropdown-box--list {
display: none;
}
.dropdown.nomatch .dropdown-input:focus~.dropdown-box--nomatch {
display: block !important;
}
.dropdown-box a {
display: flex;
align-items: center;
padding: 7px 20px;
min-height: var(--item-height);
color: black;
text-decoration: none;
transition: background 0.24s;
}
.dropdown-box a.hide {
display: none;
}
.dropdown-box a:hover {
background-color: #acf;
}
.dropdown-box::-webkit-scrollbar {
width: 10px;
height: 10px;
}
.dropdown-box::-webkit-scrollbar-track {
background: transparent;
border-radius: 10px;
}
.dropdown-box::-webkit-scrollbar-thumb {
background-color: #000;
border-radius: 10px;
}
<div class="dropdown">
<input type="text" class="dropdown-input" autocomplete="off" placeholder="🔍︎ Search...">
<div class="dropdown-box dropdown-box--list">
Result 1
Result 2
Result 3
Result 4
Result 5
Result 6
Result 7
Result 8
Result 9
Result 10
Result 11
Result 12
Result 13
Result 14
Result 15
</div>
<div class="dropdown-box dropdown-box--nomatch">
<i>No Matches</i>
</div>
</div>
<div class="dropdown">
<input type="text" class="dropdown-input" autocomplete="off" placeholder="🔍︎ Yet another...">
<div class="dropdown-box dropdown-box--list">
Lorem
Ipsum
Dolor sit amet
Lorem ut florem
</div>
<div class="dropdown-box dropdown-box--nomatch">
<i>No Matches</i>
</div>
</div>
I wanted to add line numbering to a textarea.
I get the number of lines by using
textAreaElement.value.split("\n").length;
and maintain a div with span elements that use the count as content on before to add line numbers.
.line-number {
width: 100%;
display: block;
text-align: right;
line-height:1.5em;
border-bottom: thin;
font-family:'CascadiaCode Nerd Font', monospace;
font-size: 2rem;
color: #fff;
opacity: 0.8;
padding: 0 0.4em;
}
.line-number::before {
counter-increment: line;
content: counter(line);
font-size: 1em;
user-select: none;
}
However this has a fixed height, I want to implement this for a text area with word wrap (no horizontal scrollbar), where every line can technically have multiple lines terminated by a "\n".
My line of thought was to prepare an array of heights for each lines but I have no idea how to get the height of each separate line.
update:
I switched to an editable div, but i want my line number to be of the same height as its corresponding div.
const lineEnum = {
state: false,
count: 0,
gutter: document.getElementsByClassName("line-numbers")[0],
update: (box) => {
let delta = box.children.length - lineEnum.count;
if (box.children.length == 0) delta++;
console.log({
delta: delta,
count: lineEnum.count,
length: box.children.length,
});
if (delta > 0 && lineEnum.state) {
const frag = document.createDocumentFragment();
while (delta > 0) {
const line_number = document.createElement("span");
line_number.className = "line-num";
frag.appendChild(line_number);
lineEnum.count++;
delta--;
}
lineEnum.gutter.appendChild(frag);
} else {
if (lineEnum.count + delta === 0) delta++;
while (delta < 0 && lineEnum.gutter.lastChild) {
lineEnum.gutter.removeChild(lineEnum.gutter.lastChild);
lineEnum.count--;
delta++;
}
}
},
init: (box) => {
if (lineEnum.state) return;
lineEnum.state = true;
lineEnum.update(box);
},
remove: (box) => {
if (!lineEnum.state || !lineEnum.gutter.firstChild) return;
lineEnum.gutter.innerHtml = "";
lineEnum.state = false;
},
};
const callback = (mutationList, observer) => {
let mutation = mutationList[mutationList.length - 1];
if (mutation.type === "childList") {
console.log(mutation);
lineEnum.update(mutation.target);
}
};
const observer = new MutationObserver(callback);
const config = { childList: true };
const editor = document.getElementsByClassName("code-input")[0];
observer.observe(editor, config);
lineEnum.init(editor);
.window-body{
position: fixed;
height: 100%;
top: 25px;
width: 100%;
display: flex;
}
.line-numbers {
width: 5em;
padding: 0;
height: 100%;
word-break: break-all;
overflow: hidden;
display: inline-block;
counter-reset: line;
background-color: gray;
opacity: 0.8;
}
.line-num {
width: 100%;
display: block;
text-align: middle;
line-height:1.5em;
border-bottom: thin;
font-family:'Arial', monospace;
font-size: 2rem;
color: #fff;
opacity: 0.8;
padding: 0 1em;
}
.line-num::before {
counter-increment: line;
content: counter(line);
font-size: 1em;
user-select: none;
}
.code-input{
margin: 0;
border: 0;
padding: 0;
outline: 0;
list-style: none;
display: inline-block;
flex-grow: 1;
height: 100%;
word-break: break-all;
overflow: hidden;
border:none;
font-family:'Arial', monospace;
font-size:2rem;
background: white;
white-space:pre-wrap;
line-height:1.5em;
word-wrap: break-word;
resize:none;
}
<div class="window-body">
<div class="line-numbers"></div>
<div class="code-input" contenteditable="true"></div>
</div>
Man I wasted so much time on using javascript when css magic would just have done the trick.
Here is how I did it,
body {
background-color: #000;
height: 100vh;
width: 100vw;
margin: 0px;
}
.editor-wrapper {
height: 100vh;
width: 100vw;
overflow-y: auto;
counter-reset: line;
}
.editor{
margin: 0;
border: 0;
padding: 0;
outline: 0;
list-style: none;
height: 100%;
width: 100%;
word-wrap: break-word;
word-break: break-all;
font-size:2rem;
line-height: 1.5em;
font-feature-settings: common-ligatures;
-ms-font-feature-settings: common-ligatures;
color:rgba(255, 255, 255, 0.7);
resize:none;
}
.editor div {
padding-left: 5rem;
position: relative;
}
.editor div::before {
counter-increment: line;
content: counter(line);
font-size: 1em;
user-select: none;
width: 5rem;
text-align: right;
left: 0;
position: absolute;
}
<div class="editor-wrapper">
<div class="editor" contenteditable="true">
<div></div>
</div>
</div>
You can use a background image like so:
.lined-textarea {
background: url(http://i.imgur.com/2cOaJ.png);
background-attachment: local;
background-repeat: no-repeat;
padding-left: 35px;
padding-top: 10px;
border-color: #ccc;
font-size: 13px;
line-height: 16px;
resize: none;
}
<textarea rows="8" cols="30" class="lined-textarea"></textarea>
If it's a code block with line numbers you want then https://www.prowaretech.com/Computer/JavaScript/AddLineNumbersToPre demonstrates this well.
function addLineClass (pre) {
var lines = pre.innerText.split("\n"); // can use innerHTML also
while(pre.childNodes.length > 0) {
pre.removeChild(pre.childNodes[0]);
}
for(var i = 0; i < lines.length; i++) {
var span = document.createElement("span");
span.className = "line";
span.innerText = lines[i]; // can use innerHTML also
pre.appendChild(span);
pre.appendChild(document.createTextNode("\n"));
}
}
Along with the CSS using the essential part:
pre span.line::before {
content: counter(linecounter);
See https://jsfiddle.net/Abeeee/12cx5ruf/6/ for a running example
I'm a level 0 newbie, and I'm cloning some divs (here the script works very well), to which I added some inputs with different values, and what I'm looking for is to be able to sum the values ​​(only of the cloned inputs), but the script does not he reads. Only sum ALL the html inputs.
// Script for clone the div´s
$(document).ready(function() {
$("#comp-p1").click(function() {
$("#cont-p1").clone().appendTo(".derecha");
});
// =============
$("#comp-p2").click(function() {
$("#cont-p2").clone().appendTo(".derecha");
});
// =============
$("#comp-p3").click(function() {
$("#cont-p3").clone().appendTo(".derecha");
});
});
// =============================================================
// New Script for sum inputs
const suma = function() {
var x = document.getElementsByClassName("add-prod");
let sum = 0;
for (var i = 0; i < x.length; i++) {
console.log(x[i].value)
sum += parseFloat(x[i].value);
}
console.log(sum);
return sum;
}
//console.log(suma());
document.getElementById("total").value = suma();
// =============================================================
// Old Script for sum inputs
/*$(document).ready(function() {
function sumInputs(e) {
e.preventDefault();
var valores = $('.derecha').children('input');
var suma = 0;
$.each(valores, function() {
valor = $(this).val();
suma += Number(valor);
});
valores = document.getElementById('total');
$(valores).val(suma);
}
$('#sumup').on('click', sumInputs);
});*/
body {
margin: 0 auto;
color: #323232;
width: 100%;
height: 100%;
line-height: 1.5;
font-family: 'Roboto', serif
}
#container {
width: 500px;
margin: 0 auto
}
#container p {
display: inline-block;
margin-top: 20px
}
span {
font-weight: bold;
text-decoration: underline
}
#productos {
display: none
}
.img-prod {
display: inline-block;
float: left;
background: #000;
margin-right: 10px
}
.img-prod img {
width: 100%;
height: auto;
max-width: 70px;
display: block;
border: 0
}
#comp-p1,
#comp-p2,
#comp-p3 {
width: 120px;
height: 30px;
margin-top: 15px;
background: green;
padding: 10px 0 5px;
text-align: center;
vertical-align: middle;
color: #fff;
cursor: pointer
}
.derecha {
border: solid 1px #999;
max-height: 400px;
width: 350px;
margin: 0 auto;
text-align: center;
padding: 10px 0;
overflow-y: auto;
float: right
}
#producto-1,
#producto-2,
#producto-3 {
display: inline-block;
width: 220px;
padding: 10px;
float: left;
text-align: left;
font-size: .9em;
margin-right: 5px
}
#producto-1 {
background: green;
color: #fff
}
#producto-2 {
background: #add8e6;
color: #000
}
#producto-3 {
background: #666;
color: #fff
}
.cont-p {
display: inline-block;
margin: 7px auto;
line-height: 1
}
.bbp {
display: inline-block;
float: right;
width: 24px;
height: 24px;
text-align: center;
background: red;
color: #fff;
margin-left: 5px;
line-height: 1.5;
cursor: pointer
}
.cont-num {
float: left;
width: 24px;
height: 24px;
margin: 20px 5px 0 18px;
padding: 4px 3px 3px;
background: red;
text-align: center;
font-size: 16px;
font-family: Arial, sans-serif;
color: #fff
}
#mostrar {
display: none
}
#mostrar {
width: 100px;
margin: 70px 0 0;
padding: 10px;
text-align: center;
background: grey;
color: #fff;
cursor: pointer
}
/* ==== Style of Sume ==== */
.derecha input {
width: 40px;
display: block;
margin: 0 auto 10px 0;
padding: 2px 0;
background: #f2f2f2;
border: none;
border: 1px solid #000;
text-align: center
}
#cont-resultado {
text-align: center;
width: 110px;
margin-top: 70px;
background: grey;
padding: 5px 10px 10px;
color: #fff
}
#cont-resultado input {
display: inline-block;
margin: 10px auto;
background: #fff;
color: #000;
border: 1px solid #000;
padding: 8px 0
}
#cont-resultado p {
display: inline-block;
text-decoration: none;
color: #fff;
background: grey;
padding: 8px 10px;
cursor: pointer
}
#total {
display: block;
width: 80px;
text-align: center
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="productos">
<!-- =============== -->
<div id="cont-p1" class="cont-p">
<div id="producto-1">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"> </div>cont-p1 cloned!<br><br>Input Value = 1</div>
<input class="add-prod" type="num" value="1">
<div class="bbp" onclick="restar();restardos();this.parentNode.parentNode.removeChild(this.parentNode);">X</div>
</div>
<!-- =============== -->
<div id="cont-p2" class="cont-p">
<div id="producto-2">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"></div>
cont-p2 cloned!<br><br>Input Value = 1</div>
<input class="add-prod" type="num" value="1">
<div class="bbp" onclick="restar();restardos();this.parentNode.parentNode.removeChild(this.parentNode);">X</div>
</div>
<!-- =============== -->
<div id="cont-p3" class="cont-p">
<div id="producto-3">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"></div>
cont-p3 cloned!<br><br>Input Value = 198</div>
<input class="add-prod" type="num" value="198">
<div class="bbp" onclick="restar();restardos();this.parentNode.parentNode.removeChild(this.parentNode);">X</div>
</div>
<!-- =============== -->
</div>
<!-- // productos -->
<div class="derecha"></div>
<div id="comp-p1" onClick="clickME();clickME2();">Clone 1</div>
<div id="comp-p2" onClick="clickME();clickME2();">Clone 2</div>
<div id="comp-p3" onClick="clickME();clickME2();">Clone 3</div>
<div class="cont-num" id="clicks">0</div>
<div class="cont-num" id="clicksdos">0</div>
<div id="cont-resultado">
<span>RESULT:</span><br>
<input name="total" id="total">
<br>Is the sum of the cloned divs
<!--<p id='sumup'>Ver total</p>-->
</div>
<p><span>NOTE:</span><br>Here we are looking for only the cloned inputs can be sumed (and see the result in the box color gray).<br><br>The problem is that the current script does not apply a sume of the cloned inputs only... it adds ALL the inputs presents
in the html...<br><br>So (1), how do you sum only the cloned inputs, ignoring those that are outside...?<br><br>And (2) also, how to subtract from the total result all the cloned divs that are deleted...?</p>
</div>
<!-- // container -->
<script>
// Script that adds and subtracts the clicks
var clicks = 0;
function clickME() {
clicks += 1;
document.getElementById("clicks").innerHTML = clicks
}
var clicksdos = 0;
function clickME2() {
clicksdos += 1;
document.getElementById("clicksdos").innerHTML = clicksdos;
if (clicksdos === 1) {
document.getElementById("cont-resultado").style.display = "block";
}
}
if (clicksdos === 0) {
document.getElementById("cont-resultado").style.display = "none";
}
function restar() {
if (clicks > 0) clicks -= 1;
document.getElementById("clicks").innerHTML = clicks;
}
function restardos() {
if (clicksdos > 0) clicksdos -= 1;
document.getElementById("clicksdos").innerHTML = clicksdos;
if (clicksdos === 0) {
document.getElementById("cont-resultado").style.display = "none";
}
}
</script>
Ok, you need a couple of changes.
First of you need to run a query selector and get only the elements inside the destination.
const suma = function () {
// NOTE: The query selector is very specific
let x = Array.from(document.querySelectorAll(".derecha div .add-prod"));
console.log(x);
let sum = 0;
for (var i = 0; i < x.length; i++) {
console.log(x[i].value)
sum += parseFloat(x[i].value);
}
console.log(sum);
return sum;
}
Next you will need to call you SUM method each time you add an item:
$(document).ready(function () {
$("#comp-p1").click(function () {
$("#cont-p1").clone().appendTo(".derecha");
document.getElementById("total").value = suma();
});
// =============
$("#comp-p2").click(function () {
$("#cont-p2").clone().appendTo(".derecha");
document.getElementById("total").value = suma();
});
// =============
$("#comp-p3").click(function () {
$("#cont-p3").clone().appendTo(".derecha");
document.getElementById("total").value = suma();
});
});
Here it is working:
Added code to deal with the removal of elements also.
// Script for clone the div´s
$(document).ready(function() {
$("#comp-p1").click(function() {
$("#cont-p1").clone().appendTo(".derecha");
displaySuma();
});
// =============
$("#comp-p2").click(function() {
$("#cont-p2").clone().appendTo(".derecha");
displaySuma();
});
// =============
$("#comp-p3").click(function() {
$("#cont-p3").clone().appendTo(".derecha");
displaySuma();
});
});
const getParent = (match, node) => (node.matches(match)) ? node : getParent(match, node.parentNode);
// Deal with remove
document.addEventListener('click', (event) => {
let target = event.target;
if (target.matches('.bbp')) {
restar();
restardos();
getParent('.derecha', target).removeChild(target.parentNode);
displaySuma();
}
})
// New Script for sum inputs
const displaySuma = () => document.getElementById("total").value = suma();
const suma = function() {
let x = Array.from(document.querySelectorAll(".derecha div .add-prod"));
let sum = 0;
for (var i = 0; i < x.length; i++) {
sum += parseFloat(x[i].value);
}
console.log(sum);
return sum;
}
//console.log(suma());
document.getElementById("total").value = suma();
body {
margin: 0 auto;
color: #323232;
width: 100%;
height: 100%;
line-height: 1.5;
font-family: 'Roboto', serif
}
#container {
width: 500px;
margin: 0 auto
}
#container p {
display: inline-block;
margin-top: 20px
}
span {
font-weight: bold;
text-decoration: underline
}
#productos {
display: none
}
.img-prod {
display: inline-block;
float: left;
background: #000;
margin-right: 10px
}
.img-prod img {
width: 100%;
height: auto;
max-width: 70px;
display: block;
border: 0
}
#comp-p1,
#comp-p2,
#comp-p3 {
width: 120px;
height: 30px;
margin-top: 15px;
background: green;
padding: 10px 0 5px;
text-align: center;
vertical-align: middle;
color: #fff;
cursor: pointer
}
.derecha {
border: solid 1px #999;
max-height: 400px;
width: 350px;
margin: 0 auto;
text-align: center;
padding: 10px 0;
overflow-y: auto;
float: right
}
#producto-1,
#producto-2,
#producto-3 {
display: inline-block;
width: 220px;
padding: 10px;
float: left;
text-align: left;
font-size: .9em;
margin-right: 5px
}
#producto-1 {
background: green;
color: #fff
}
#producto-2 {
background: #add8e6;
color: #000
}
#producto-3 {
background: #666;
color: #fff
}
.cont-p {
display: inline-block;
margin: 7px auto;
line-height: 1
}
.bbp {
display: inline-block;
float: right;
width: 24px;
height: 24px;
text-align: center;
background: red;
color: #fff;
margin-left: 5px;
line-height: 1.5;
cursor: pointer
}
.cont-num {
float: left;
width: 24px;
height: 24px;
margin: 20px 5px 0 18px;
padding: 4px 3px 3px;
background: red;
text-align: center;
font-size: 16px;
font-family: Arial, sans-serif;
color: #fff
}
#mostrar {
display: none
}
#mostrar {
width: 100px;
margin: 70px 0 0;
padding: 10px;
text-align: center;
background: grey;
color: #fff;
cursor: pointer
}
/* ==== Style of Sume ==== */
.derecha input {
width: 40px;
display: block;
margin: 0 auto 10px 0;
padding: 2px 0;
background: #f2f2f2;
border: none;
border: 1px solid #000;
text-align: center
}
#cont-resultado {
text-align: center;
width: 110px;
margin-top: 70px;
background: grey;
padding: 5px 10px 10px;
color: #fff
}
#cont-resultado input {
display: inline-block;
margin: 10px auto;
background: #fff;
color: #000;
border: 1px solid #000;
padding: 8px 0
}
#cont-resultado p {
display: inline-block;
text-decoration: none;
color: #fff;
background: grey;
padding: 8px 10px;
cursor: pointer
}
#total {
display: block;
width: 80px;
text-align: center
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="productos">
<!-- =============== -->
<div id="cont-p1" class="cont-p">
<div id="producto-1">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"> </div>cont-p1 cloned!<br><br>Input Value = 1</div>
<input class="add-prod" type="num" value="1">
<div class="bbp">X</div>
</div>
<!-- =============== -->
<div id="cont-p2" class="cont-p">
<div id="producto-2">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"></div>
cont-p2 cloned!<br><br>Input Value = 1</div>
<input class="add-prod" type="num" value="1">
<div class="bbp">X</div>
</div>
<!-- =============== -->
<div id="cont-p3" class="cont-p">
<div id="producto-3">
<div class="img-prod"><img src="https://upload.wikimedia.org/wikipedia/commons/3/39/Lichtenstein_img_processing_test.png"></div>
cont-p3 cloned!<br><br>Input Value = 198</div>
<input class="add-prod" type="num" value="198">
<div class="bbp">X</div>
</div>
<!-- =============== -->
</div>
<!-- // productos -->
<div class="derecha"></div>
<div id="comp-p1" onClick="clickME();clickME2();">Clone 1</div>
<div id="comp-p2" onClick="clickME();clickME2();">Clone 2</div>
<div id="comp-p3" onClick="clickME();clickME2();">Clone 3</div>
<div class="cont-num" id="clicks">0</div>
<div class="cont-num" id="clicksdos">0</div>
<div id="cont-resultado">
<span>RESULT:</span><br>
<input name="total" id="total">
<br>Is the sum of the cloned divs
<!--<p id='sumup'>Ver total</p>-->
</div>
<p><span>NOTE:</span><br>Here we are looking for only the cloned inputs can be sumed (and see the result in the box color gray).<br><br>The problem is that the current script does not apply a sume of the cloned inputs only... it adds ALL the inputs presents
in the html...<br><br>So (1), how do you sum only the cloned inputs, ignoring those that are outside...?<br><br>And (2) also, how to subtract from the total result all the cloned divs that are deleted...?</p>
</div>
<!-- // container -->
<script>
// Script that adds and subtracts the clicks
var clicks = 0;
function clickME() {
clicks += 1;
document.getElementById("clicks").innerHTML = clicks
}
var clicksdos = 0;
function clickME2() {
clicksdos += 1;
document.getElementById("clicksdos").innerHTML = clicksdos;
if (clicksdos === 1) {
document.getElementById("cont-resultado").style.display = "block";
}
}
if (clicksdos === 0) {
document.getElementById("cont-resultado").style.display = "none";
}
function restar() {
if (clicks > 0) clicks -= 1;
document.getElementById("clicks").innerHTML = clicks;
}
function restardos() {
if (clicksdos > 0) clicksdos -= 1;
document.getElementById("clicksdos").innerHTML = clicksdos;
if (clicksdos === 0) {
document.getElementById("cont-resultado").style.display = "none";
}
}
</script>
Currently my price output gets calculated based on the chosen quantity of an input field. I have been trying to add a checkbox to this calculation that, if checked, adds $5 to the total price. That being said, I haven't been very successful. In my understanding, there are two calculations going on:
I hit the increase/decrease button and it checks if the checkbox has been selected
I select the checkbox and it calculates the total price
This is the code I have so far:
function IncludePrice()
{
var IncludePrice=0;
var include = theForm.elements["include"];
if(include.checked==true)
{
IncludePrice=5;
}
return IncludePrice;
}
$(".incr-btn_mobile").on("click", function(e) {
var $button = $(this);
var oldValue = $button.parent().find('.quantity').val();
$button.parent().find('.incr-btn_mobile[data-action="decrease"]').removeClass('inactive');
if ($button.data('action') == "increase") {
var newVal = parseFloat(oldValue) + 1;
} else {
// Don't allow decrementing below 1
if (oldValue > 1) {
var newVal = parseFloat(oldValue) - 1;
} else {
newVal = 1;
$button.addClass('inactive');
}
}
$button.parent().find('.quantity').val(newVal);
var cakePrice = newVal;
var includep = IncludePrice();
var divobj = document.getElementById($button.attr('data-target'));
divobj.style.display = 'block';
divobj.innerHTML = "= $" + (cakePrice) * 7.99 + (includep);
e.preventDefault();
});
.bg {
width: 100%;
}
.column {
float: left;
width: 50%;
padding: 10px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
.count-input_mobile {
position: relative;
max-width: 1000%;
max-width: 400px;
margin-top: 10px;
text-align: center;
}
.count-input_mobile input {
width: 100%;
height: 42px;
border: 1px solid #000
border-radius: 2px;
background: none;
text-align: center;
}
.count-input_mobile input:focus {
outline: none;
}
.count-input_mobile .incr-btn_mobile {
display: block;
position: absolute;
width: 30px;
height: 30px;
font-size: 26px;
font-weight: 300;
text-align: center;
line-height: 30px;
top: 50%;
right: 0;
margin-top: -15px;
text-decoration:none;
}
.count-input_mobile .incr-btn_mobile:first-child {
right: auto;
left: 0;
top: 46%;
}
.count-input_mobile.count-input-sm {
max-width: 125px;
}
.count-input_mobile.count-input-sm input {
height: 36px;
}
.count-input_mobile.count-input-lg {
max-width: 200px;
}
.count-input_mobile.count-input-lg input {
height: 70px;
border-radius: 3px;
}
.button_mobile {
border: 1px solid #000;
border-radius: 2px;
background: none;
padding: 10.5px;
width:100%;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
margin-top:10px;
}
.sum_output {
background: none;
padding: 9.5px;
width:100%;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
margin-top:10px;
}
.accordion_img {
width:200%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<div class="count-input_mobile space-bottom">
<a class="incr-btn_mobile" data-action="decrease" data-target="cleanse_drop_1" href="#">–</a>
<input class="quantity" id="ShowButton_value_1" type="text" name="quantity" value="1"/>
<a class="incr-btn_mobile" data-action="increase" data-target="cleanse_drop_1" href="#">+</a>
</div>
<label for='include' class="inlinelabel">Include Extra? ($5)</label>
<input type="checkbox" id="include" name='include' data-target="cleanse_drop_1" />
<div id="cleanse_drop_1" class="sum_output">= $7.99</div>
UPDATE:
I changed made some changes based on the feedback here, but this seems to break the increase/decrease field. Here is the code as is:
$(".incr-btn_mobile").on("click", function(e) {
var $button = $(this);
var oldValue = $button.parent().find('.quantity').val();
$button.parent().find('.incr-btn_mobile[data-action="decrease"]').removeClass('inactive');
if ($button.data('action') == "increase") {
var newVal = parseFloat(oldValue) + 1;
} else {
// Don't allow decrementing below 1
if (oldValue > 1) {
var newVal = parseFloat(oldValue) - 1;
} else {
newVal = 1;
$button.addClass('inactive');
}
}
$button.parent().find('.quantity').val(newVal);
var cakePrice = newVal;
var includep = theForm.elements.include.checked * 5;
var divobj = document.getElementById($button.attr('data-target'));
divobj.style.display = 'block';
divobj.innerHTML = "= $" + (cakePrice) * 7.99 + (includep);
e.preventDefault();
});
.bg {
width: 100%;
}
.column {
float: left;
width: 50%;
padding: 10px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
.count-input_mobile {
position: relative;
max-width: 1000%;
max-width: 400px;
margin-top: 10px;
text-align: center;
}
.count-input_mobile input {
width: 100%;
height: 42px;
border: 1px solid #000
border-radius: 2px;
background: none;
text-align: center;
}
.count-input_mobile input:focus {
outline: none;
}
.count-input_mobile .incr-btn_mobile {
display: block;
position: absolute;
width: 30px;
height: 30px;
font-size: 26px;
font-weight: 300;
text-align: center;
line-height: 30px;
top: 50%;
right: 0;
margin-top: -15px;
text-decoration:none;
}
.count-input_mobile .incr-btn_mobile:first-child {
right: auto;
left: 0;
top: 46%;
}
.count-input_mobile.count-input-sm {
max-width: 125px;
}
.count-input_mobile.count-input-sm input {
height: 36px;
}
.count-input_mobile.count-input-lg {
max-width: 200px;
}
.count-input_mobile.count-input-lg input {
height: 70px;
border-radius: 3px;
}
.button_mobile {
border: 1px solid #000;
border-radius: 2px;
background: none;
padding: 10.5px;
width:100%;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
margin-top:10px;
}
.sum_output {
background: none;
padding: 9.5px;
width:100%;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
margin-top:10px;
}
.accordion_img {
width:200%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<div class="count-input_mobile space-bottom">
<a class="incr-btn_mobile" data-action="decrease" data-target="cleanse_drop_1" href="#">–</a>
<input class="quantity" id="ShowButton_value_1" type="text" name="quantity" value="1"/>
<a class="incr-btn_mobile" data-action="increase" data-target="cleanse_drop_1" href="#">+</a>
</div>
<label for='include' class="inlinelabel">Include Extra? ($5)</label>
<input type="checkbox" id="include" name='include' data-target="cleanse_drop_1" />
<div id="cleanse_drop_1" class="sum_output">= $7.99</div>
There you go my friend. I only change your js code. There is all the change I made:
Deleted your IncludePrice function since you could do it in only one row. And do never user function name for a variable. It could possibly break your code.
All switched for jQuery use instead of half jQuery and native JS.
Created a function for checkbox onclick to change the prince dynamicly.
I changed the names of your variables to make them more specific.
Added some comments to make the code clearer.
var _EXTRAVAL = 5;
$(".incr-btn_mobile").on("click", function(e) {
// Prevent default action
e.preventDefault();
// Set variable for the method
var button = $(this);
var labelNb = button.parent().find('.quantity');
var labelPrice = $("#" + button.attr('data-target'));
var currentNb = button.parent().find('.quantity').val();
var newNb = 0;
// Remove 'inactive' class
$('.incr-btn_mobile[data-action="decrease"]').removeClass('inactive');
// Increase or decrease
if (button.attr('data-action') == "increase") {
newNb = parseFloat(currentNb) + 1;
} else {
// Don't allow decrementing below 1
if (currentNb > 1) {
newNb = parseFloat(currentNb) - 1;
} else {
newNb = 1;
button.addClass('inactive');
}
}
var isExtra = $("#include").prop('checked') ? _EXTRAVAL : 0;
$(labelNb).val(newNb);
$(labelPrice).css('display', 'block').html("= $" + String((((newNb) * 7.99) + (isExtra)).toFixed(2)));
});
$("#include").on('click', function(){
// Set variable for method
var checkbox = $(this);
var labelPrice = $("#" + $(".incr-btn_mobile").attr('data-target'));
var labelPriceFloat = parseFloat(labelPrice.html().substring(4));
// If checkbox is check, increse price
if (checkbox.prop('checked')) {
labelPrice.html("= $" + String((labelPriceFloat + _EXTRAVAL).toFixed(2)));
} else {
labelPrice.html("= $" + String((labelPriceFloat - _EXTRAVAL).toFixed(2)));
}
});
.bg {
width: 100%;
}
.column {
float: left;
width: 50%;
padding: 10px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
.count-input_mobile {
position: relative;
max-width: 1000%;
max-width: 400px;
margin-top: 10px;
text-align: center;
}
.count-input_mobile input {
width: 100%;
height: 42px;
border: 1px solid #000
border-radius: 2px;
background: none;
text-align: center;
}
.count-input_mobile input:focus {
outline: none;
}
.count-input_mobile .incr-btn_mobile {
display: block;
position: absolute;
width: 30px;
height: 30px;
font-size: 26px;
font-weight: 300;
text-align: center;
line-height: 30px;
top: 50%;
right: 0;
margin-top: -15px;
text-decoration:none;
}
.count-input_mobile .incr-btn_mobile:first-child {
right: auto;
left: 0;
top: 46%;
}
.count-input_mobile.count-input-sm {
max-width: 125px;
}
.count-input_mobile.count-input-sm input {
height: 36px;
}
.count-input_mobile.count-input-lg {
max-width: 200px;
}
.count-input_mobile.count-input-lg input {
height: 70px;
border-radius: 3px;
}
.button_mobile {
border: 1px solid #000;
border-radius: 2px;
background: none;
padding: 10.5px;
width:100%;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
margin-top:10px;
}
.sum_output {
background: none;
padding: 9.5px;
width:100%;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
margin-top:10px;
}
.accordion_img {
width:200%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<div class="count-input_mobile space-bottom">
<a class="incr-btn_mobile" data-action="decrease" data-target="cleanse_drop_1" href="#">–</a>
<input class="quantity" id="ShowButton_value_1" type="text" name="quantity" value="1"/>
<a class="incr-btn_mobile" data-action="increase" data-target="cleanse_drop_1" href="#">+</a>
</div>
<label for='include' class="inlinelabel">Include Extra? ($5)</label>
<input type="checkbox" id="include" name='include' data-target="cleanse_drop_1" />
<div id="cleanse_drop_1" class="sum_output">= $7.99</div>
Here is some pastebin (don't want to put my code in the internet for ever) to build a cool calendar :
var today = new Date(); // The current server date
var displayedMonth = new Date(today.getTime())
var mois = ["Janvier", "FĂ©vrier", "Mars", "Avril", "Mai", "Juin", "Juillet", "Aout", "Septembre", "Octobre", "Novembre", "Decembre"];
var jour = ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"];
function initialSetup(date){
addEventListener();
buildCalendar(date);
}
function buildCalendar(date){
$(".currentMonth").text(mois[date.getMonth()]);
$(".currentYear").text(date.getFullYear());
if($(".itemsCalendar").length == 0){
$(".calendar:first").append('<table class="itemsCalendar"><thead><tr></tr></thead>');
for(var cpt = 1; cpt <= jour.length-1;cpt++)
$(".calendar > table > thead > tr").append('<th>'+jour[cpt].substring(0,3)+'</th>');
$(".calendar > table > thead > tr").append('<th>'+jour[0].substring(0,3)+'</th>');
}
// Set the days in the calendar
return populateCalendar(date);
}
function populateCalendar(date){
var itsToday = null;
var appendLocation = null;
var sendResult = false;
if($(".itemsCalendar > tbody").length == 0){
$(".itemsCalendar").append('<tbody class="dates"></tbody>');
appendLocation = ".dates";
}else{
$(".calendar").append('<tbody class="tempCalendar"></tbody>');
appendLocation = ".tempCalendar";
sendResult = true;
}
if(date.getMonth() == today.getMonth() && date.getYear() == today.getYear() ){ // If is it the same day than today, buid as follow
itsToday = 'class="today"'
// date = today;
date.setDate(today.getDate()); // copy the date of today
}
$(appendLocation).append("<tr><td><span "+itsToday+">"+date.getDate()+"</span></td></tr>");
var currentDay = date.getDay();
for(var cpt = date.getDate()-1; cpt>=1;cpt--){ // For each day before
currentDay > 0 ? currentDay-- : currentDay = 6; // Negate 1 day
currentDay == 0 ? $(appendLocation).prepend("<tr></tr>"):null; // Add a line in needed
$(appendLocation+" > tr:first").prepend("<td><span>"+cpt+"</span></td>");
}
fillCalendar(date, currentDay, true, appendLocation);
currentDay = date.getDay();
for(var cpt = date.getDate()+1; cpt<=dayInMonth(date);cpt++){ // For each day after
currentDay < 6 ? currentDay++ : currentDay = 0;// Increase 1 day
currentDay == 1 ? $(appendLocation).append("<tr></tr>"):null; // Add a line if needed
$(appendLocation+" > tr:last").append("<td><span>"+cpt+"</span></td>");
}
fillCalendar(date, currentDay, false, appendLocation);
if(sendResult){
var ret = $(".tempCalendar").html();
$(".tempCalendar").remove();
return ret;
}
}
function dayInMonth(date){
if(date.getMonth() == 1) if(isBissextile(date.getYear())) return 29; else return 28;
if(date.getMonth()%2 == 0) if(date.getMonth() <= 6) return 31; else return 30; else if(date.getMonth() <= 6) return 30; else return 31;
}
function isBissextile(year){
if(year%4 != 0) return false; else if((year%100 == 0) && (year%400 != 0)) return false; else return true;
}
function fillCalendar(date, day, isBefore, where){
var complete;
if(isBefore){
if(day == 1) return; else complete = false;
date.setMonth(date.getMonth()-1);
var cpt = dayInMonth(date);
do{
day != 0 ? day-- : day = 6; // Negate 1 day
$(where+" > tr:first").prepend("<td><span class='notInTheMonth'>"+cpt+"</span></td>");
cpt--;
day == 1 ? complete = true : null;
}while(!complete);
date.setMonth(date.getMonth()+1);
}else{
if(day == 0) return; else complete = false;
var cpt = 1;
do{
day == 6 ? day = 0 : day++; // Increase 1 day
$(where+" > tr:last").append("<td><span class='notInTheMonth'>"+cpt+"</span></td>");
cpt++;
day == 0 ? complete = true : null;
}while(!complete);
}
}
function addEventListener(){
$(".previousMonth").click(function(e){
e.stopPropagation();
displayedMonth.setMonth(displayedMonth.getMonth()-1);
displayedMonth.setDate(15);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
});
$(".nextMonth").click(function(e){
e.stopPropagation();
displayedMonth.setMonth(displayedMonth.getMonth()+1);
displayedMonth.setDate(15);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
});
$(".previousYear").click(function(e){
e.stopPropagation();
displayedMonth.setFullYear(displayedMonth.getFullYear()-1);
displayedMonth.setDate(15);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
});
$(".nextYear").click(function(e){
e.stopPropagation();
displayedMonth.setFullYear(displayedMonth.getFullYear()+1);
displayedMonth.setDate(15);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
});
}
function addDayEventListener(){
$(".dates").on('click', '.notInTheMonth', function() {
var selected = parseInt($(this).text());
if(selected > 15)
displayedMonth.setMonth(displayedMonth.getMonth()-1);
else
displayedMonth.setMonth(displayedMonth.getMonth()+1);
displayedMonth.setDate(selected);
var updated = buildCalendar(displayedMonth);
updateCalendar(updated);
$(".dates > tr > td > span:not(.notInTheMonth)").filter(function() {
return parseInt($(this).text()) === selected;
}).addClass("today")
});
/*$(".notInTheMonth").each(function(){
$(this).click(function(e){
e.stopPropagation();
});
});*/
}
function updateCalendar(updated){
$('.dates').animate({
opacity: 0,
transform: "scale(2,1)"
},250, function(){
updated = $(updated);
$(this).empty();
$(this).html(updated);
addDayEventListener();
$('.dates').animate({opacity: 100}, 250);
});
//$(".itemsCalendar > tbody").remove();
}
function colorize(colors){
/*background: #ff3232;
background: -moz-linear-gradient(-45deg, #ff3232 0%, #ff2828 21%, #2989d8 21%, #2989d8 48%, #5aa85e 48%, #5aa85e 73%, #ffac4f 73%, #ffac4f 100%);
background: -webkit-linear-gradient(-45deg, #ff3232 0%,#ff2828 20%,#2989d8 20%,#2989d8 40%,#5aa85e 40%,#5aa85e 60%,#ffac4f 60%,#ffac4f 80%, yellow 80%,yellow 100%);
background: linear-gradient(135deg, #ff3232 0%,#ff2828 21%,#2989d8 21%,#2989d8 48%,#5aa85e 48%,#5aa85e 73%,#ffac4f 73%,#ffac4f 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff3232', endColorstr='#ffac4f',GradientType=1 );*/
}
initialSetup(today);
* {
font-family: 'Open Sans', sans-serif;
}
div,
ul,
li {
list-style-type: none;
}
.planner {
width: 66%;
margin: 100px auto;
box-shadow: 0 0 40px rgba(0, 0, 0, 0.5);
border-radius: 5px;
overflow: hidden;
min-width: 280px;
}
.calendar {
padding: 10px;
background-color: #333333;
min-width: 260px;
transition: 250ms;
}
.calendar-header {
color: #a7a7a7;
margin: 0;
padding: 0;
text-align: justify;
line-height: 0px;
font-size: 0px;
}
.calendar-header span,
.calendar-header a {
display: inline-block;
font-size: 36px;
font-weight: 200;
text-align: center;
line-height: 36px;
}
.calendar-header a:hover {
color: #98cd60;
cursor: pointer;
}
.calendar-header::after {
content: '';
display: inline-block;
width: 100%;
}
table {
width: 100%;
padding: 10px;
color: #9d9d9d;
min-width: 240px;
}
tbody{
overflow: hidden;
max-height: 180px;
}
th {
font-weight: normal;
font-size: 14px;
color: #5b5b5b;
}
td {
font-weight: normal;
font-size: 12px;
text-align: center;
}
td > span {
display: inline-block;
text-align: center;
padding: 3px;
margin: 0px;
width: 20px;
height: 20px;
line-height: 20px;
}
td > span:hover {
font-weight: bold;
}
td > span.active {
border: 2px solid #98cd60;
border-radius: 30px;
}
.schedule {
margin: 0;
}
.tabs {
margin: 0;
padding: 0;
text-align: justify;
line-height: 0px;
font-size: 0px;
background-color: #6b6b6b;
}
.tabs .tab {
display: inline-block;
width: 33.3333%;
background-color: #6b6b6b;
text-align: center;
color: #333333;
margin: 0;
padding: 0;
border: 0px none;
line-height: 38px;
font-size: 14px;
transition: background 0.2s;
}
.tabs .tab.active {
background-color: #999999;
color: #ffffff;
font-weight: 600;
}
.tabs .tab.active:hover {
background-color: #999999;
}
.tabs .tab:hover {
background-color: #777777;
}
.tabs .tab a {
color: inherit;
text-decoration: none;
}
.tabs::after {
content: '';
width: 100%;
display: inline-block;
}
.schedule-list {
padding: 20px;
margin-left: 37px;
border-left: 2px solid #cccccc;
display: block;
}
.schedule-item {
display: block;
margin-bottom: 50px;
padding: 0;
clear: both;
min-height: 100px;
overflow: visible;
}
.schedule-item:last-child {
margin-bottom: 10px;
min-height: 30px;
}
.schedule-item .time {
display: block;
float: left;
margin-left: -41px;
width: 36px;
height: 36px;
border: 2px solid #cccccc;
background-color: #ffffff;
color: #cccccc;
border-radius: 40px;
text-align: center;
padding: 0px;
line-height: 25px;
}
.schedule-item .time span {
font-size: 12px;
height: 10px;
margin: auto;
display: block;
}
.schedule-item .description {
display: block;
float: left;
width: 305px;
margin-top: 10px;
margin-left: 10px;
color: #fd9a4a;
font-size: 14px;
overflow: visible;
}
.schedule-item .description .description-content {
margin-top: 5px;
}
.schedule-item .description .description-content p {
font-size: 12px;
margin: 0;
color: #c5c5c5;
}
.schedule-item .description .description-content .contact-list {
margin: 0;
margin-top: 10px;
padding: 0;
}
.schedule-item .description .description-content .contact-list .contact {
overflow: hidden;
display: block;
float: left;
margin: 0;
padding: 0;
border: 2px solid rgba(152, 205, 96, 0.25);
border-radius: 60px;
width: 56px;
height: 56px;
text-decoration: none;
text-align: center;
margin-right: 10px;
transition: all 0.2s;
}
.schedule-item .description .description-content .contact-list .contact img {
width: 60px;
height: 60px;
}
.schedule-item .description .description-content .contact-list .contact:hover {
border: 2px solid #98cd60;
}
.schedule-item .description .description-content .contact-list .contact.add-contact {
color: #98cd60;
font-size: 20px;
line-height: 60px;
}
.schedule-item .description .description-content .contact-list .contact.add-contact a {
color: inherit;
text-decoration: none;
}
.schedule-item .description .description-content .contact-list .contact.add-contact:hover {
background-color: rgba(152, 205, 96, 0.25);
}
.schedule-item.free .time {
border: 2px solid #98cd60;
}
.schedule-item.free .description .description-header {
background-color: #ffffff;
color: #c5c5c5;
display: block;
float: left;
}
.schedule-item.free .description .description-content {
margin-left: 5px;
margin-top: 0;
content: '';
width: 215px;
display: block;
float: right;
background-image: url(https://dl.dropboxusercontent.com/u/2915418/filler.png);
background-repeat: no-repeat;
background-position: right center;
}
footer {
margin-top: 30px;
color: #c5c5c5;
display: block;
text-align: center;
}
footer a {
color: #98cd60;
text-decoration: none;
}
.today{
background-color: #7D7D7D;
color: #98CD60;
border-radius: 30px;
width: 20px;
height: 20px;
}
.notInTheMonth{
background-color: #272727;
border-radius: 30px;
color: #444444;
}
.headerWrapper{
color: #a7a7a7;
border-bottom: 1px solid #484848;
margin: 0;
padding: 0;
text-align: justify;
line-height: 0px;
font-size: 0px;
padding: 10px 0px;
}
.headerWrapper::after {
content: '';
display: inline-block;
width: 100%;
}
.itemsCalendar{
display: block;
max-height: 225px;
}
.itemsCalendar thead, .dates tr, .tempCalendar tr{
display: table;
width: 100%;
table-layout: fixed;
}
.tempCalendar{
display: none;
}
<html>
<head>
<title>Calendrier</title>
<meta charset="utf-8" />
<link href="http://netdna.bootstrapcdn.com/font-awesome/3.1.1/css/font-awesome.min.css" rel="stylesheet">
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700,800' rel='stylesheet' type='text/css'>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
</head>
<body>
<div class="planner">
<div class="calendar">
<div class="calendar-header">
<div class="headerWrapper">
<a class="btn btn-prev previousYear">
<i class="icon-angle-left"></i>
</a>
<span class="currentYear">July</span>
<a class="btn btn-next nextYear">
<i class="icon-angle-right"></i>
</a>
</div>
<div class="headerWrapper">
<a class="btn btn-prev previousMonth">
<i class="icon-angle-left"></i>
</a>
<span class="currentMonth"></span>
<a class="btn btn-next nextMonth">
<i class="icon-angle-right"></i>
</a>
</div>
</div>
</div>
</div>
</body>
</html>
js/calendar.js
index.html
css/style.css
When clicking on notInTheMonth classed elements, there will be problems (too much day in the output, more than one month passed etc...)
To trigger the first time the click event listener, you have to pass one month or one year before. After that, it will enable the click event on the notInTheMonth day (element with background dark grey and text grey, who refer to a non-in-month day.
Frequently, the problem occurs on the second or third time we click in a notInTheMonth element.
I can't correct my trouble, so can you please help me ?