Reputation: 65
So I am trying to manipulate the CSS using Javascipt, so that when the user clicks on the box, it displays the data I have for that specific month. I have managed to achieve it, however there just feel likes there is too much code, and that there can be a more efficient way to achieve what I am trying to do.
<div class="calander-container">
<div class="months">
<p class="months-text">January</p>
</div>
<div class="months">
<p class="months-text">February</p>
</div>
<div class="months">
<p class="months-text">March</p>
</div>
<div class="months">
<p class="months-text">April</p>
</div>
<div class="months">
<p class="months-text">May</p>
</div>
<div class="months">
<p class="months-text">June</p>
</div>
<div class="months">
<p class="months-text">July</p>
</div>
<div class="months">
<p class="months-text">August</p>
</div>
<div class="months">
<p class="months-text">September</p>
</div>
<div class="months">
<p class="months-text">October</p>
</div>
<div class="months">
<p class="months-text">November</p>
</div>
<div class="months">
<p class="months-text">December</p>
</div>
</div>
Above is the HTML used for the user to click the box for the script to then run.
document.querySelector('.calander-container').addEventListener('click', (e) => {
const months = e.target.closest('.months');
if (!months) {
return;
}
const thisIndex = [...months.parentElement.children].indexOf(months);
const rallyPrint = document.querySelectorAll('.rallyPrint');
rallyPrint.forEach((div) => {
div.style.display = 'none';
});
rallyPrint[thisIndex].style.display = 'block';
});
Above is the Javascript that I am using which works. However doing this function twelve times for each month just doesn't seem efficient. I feel as if there is any easier way to accomplish this. Below is the PHP I am using if that is any help.
if($row['month'] === 'January'){
echo "<div class='rallyPrint'>";
echo "<h2>" . $row['rallyVenue'] . " in " . $row['month'] . " " . $row['year'] . "</h2>";
echo "<h4>Event: ". $row['rallyEvent'] . " </h4>";
echo "<h3>Your Marshall(s): " . $row['rallyMarsh'] . "</h3>";
echo "<h4>When? ". $row['rallyDate'] . " </h4>";
echo "<p>" . $row['rallyDesc'] . "</p>";
echo "<p>How much? ". $row['rallyCost'] . " </p>";
echo "<p>How long? ". $row['rallyNights'] . " Nights</p>";
echo "<p>Pitch Limit? ". $row['pitchLimit'] . "</p>";
echo "<p>Phone Number: 0". $row['phoneNo'] . " </p>";
echo "<p>Email: <a href='mailto:". $row['email'] . "'> ". $row['email'] ."</a></p>";
echo "<p>Please make sure you to contact ". $row['rallyMarsh'] . " for more information.</p>";
if(isset($_SESSION['loggedin'])){
echo "<a href='' id='". $row['rallyId'] . "' class='trash'>Delete</a>";
}
echo "</div><br>";
}
Upvotes: 1
Views: 110
Reputation: 35
This in reference with @CertainPerformance answer.
<html>
<head>
<style>
ul {list-style-type: none;}
body {font-family: Verdana, sans-serif;}
/* Month header */
.month {
padding: 70px 25px;
width: 100%;
background: #1abc9c;
text-align: center;
}
/* Month list */
.month ul {
margin: 0;
padding: 0;
}
.month ul li {
color: white;
font-size: 20px;
text-transform: uppercase;
letter-spacing: 3px;
}
/* Previous button inside month header */
.month .prev {
float: left;
padding-top: 10px;
}
/* Next button */
.month .next {
float: right;
padding-top: 10px;
}
/* Weekdays (Mon-Sun) */
.weekdays {
margin: 0;
padding: 10px 0;
background-color:#ddd;
}
.weekdays li {
display: inline-block;
width: 13.6%;
color: #666;
text-align: center;
}
/* Days (1-31) */
.days {
padding: 10px 0;
background: #eee;
margin: 0;
}
.days li {
list-style-type: none;
display: inline-block;
width: 13.6%;
text-align: center;
margin-bottom: 5px;
font-size:12px;
color: #777;
}
/* Highlight the "current" day */
.days li .active {
padding: 5px;
background: #1abc9c;
color: white !important
}
</style>
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$( document ).ready(function() {
document.querySelector('.calander-container').addEventListener('click', (e) => {
const months = e.target.closest('.months');
if (!months) {
return;
}
const thisIndex = [...months.parentElement.children].indexOf(months);
const rallyPrint = document.querySelectorAll('.rallyPrint');
rallyPrint.forEach((div) => {
div.style.display = 'none';
});
rallyPrint[thisIndex].style.display = 'block';
});
});
</script>
</head>
<body>
<div class="calander-container">
<?php
$month=array(
"1"=>"Jan",
"2"=>"Feb",
"3"=>"Mar",
"4"=>"April",
"5"=>"May",
"6"=>"June",
"7"=>"July",
"8"=>"Aug",
"9"=>"Sep",
"10"=>"Oct",
"11"=>"Nov",
"12"=>"Dec"
);
foreach($month as $k=>$v){
//echo "<br>Key :: ".$k." Val :: ".$v;
echo '<div class="months">
<p class="months-text">'.$v.'</p>
</div>';
}
?>
<?php
foreach($month as $k=>$v){
echo "<div class='rallyPrint'>$k</div>";
}
?>
</div>
</body>
Upvotes: 0
Reputation: 370639
Use classes instead of IDs, eg instead of
echo "<div id='rallyPrintJan'>";
use
echo "<div class='rallyPrint'>";
And then, when the container of the calendar is clicked, iterate over every .rallyPrint
class (using event delegation instead of inline handlers - inline handlers are quite poor practice, and should be avoided whenever possible). Check to see if the clicked element has a months
ancestor, and if it does, identify the index of the months
in its parent container. From that index, you can figure out which rallyPrint
element needs to be shown:
document.querySelector('.calander-container').addEventListener('click', (e) => {
const months = e.target.closest('.months');
if (!months) {
return;
}
const thisIndex = [...months.parentElement.children].indexOf(months);
const rallyPrint = document.querySelectorAll('.rallyPrint');
rallyPrint.forEach((div) => {
div.style.display = 'none';
});
rallyPrint[thisIndex].style.display = 'block';
});
Live demo:
document.querySelector('.calander-container').addEventListener('click', (e) => {
const months = e.target.closest('.months');
if (!months) {
return;
}
const thisIndex = [...months.parentElement.children].indexOf(months);
const rallyPrint = document.querySelectorAll('.rallyPrint');
rallyPrint.forEach((div) => {
div.style.display = 'none';
});
rallyPrint[thisIndex].style.display = 'block';
});
<div class="calander-container">
<div class="months">
<p class="months-text">January</p>
</div>
<div class="months">
<p class="months-text">February</p>
</div>
<div class="months">
<p class="months-text">March</p>
</div>
<div class="months">
<p class="months-text">April</p>
</div>
<div class="months">
<p class="months-text">May</p>
</div>
<div class="months">
<p class="months-text">June</p>
</div>
<div class="months">
<p class="months-text">July</p>
</div>
<div class="months">
<p class="months-text">August</p>
</div>
<div class="months">
<p class="months-text">September</p>
</div>
<div class="months">
<p class="months-text">October</p>
</div>
<div class="months">
<p class="months-text">November</p>
</div>
<div class="months">
<p class="months-text">December</p>
</div>
</div>
<div class='rallyPrint'>1</div>
<div class='rallyPrint'>2</div>
<div class='rallyPrint'>3</div>
<div class='rallyPrint'>4</div>
<div class='rallyPrint'>5</div>
<div class='rallyPrint'>6</div>
<div class='rallyPrint'>7</div>
<div class='rallyPrint'>8</div>
<div class='rallyPrint'>9</div>
<div class='rallyPrint'>10</div>
<div class='rallyPrint'>11</div>
<div class='rallyPrint'>12</div>
Upvotes: 2
Reputation: 395
you can try like using JQuery as follow
$("div[id^='rallyPrint']").hide();
$("div[id='rallyPrintJan']").show();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="rallyPrintJan">Jan</div>
<div id="rallyPrintFeb">Feb</div>
<div id="rallyPrintMar">Mar</div>
<div id="rallyPrintApr">Apr</div>
<div id="rallyPrintMay">May</div>
<div id="rallyPrintJun">Jun</div>
<div id="rallyPrintJul">Jul</div>
<div id="rallyPrintAug">Aug</div>
<div id="rallyPrintSep">Sep</div>
<div id="rallyPrintOct">Oct</div>
<div id="rallyPrintNov">Nov</div>
<div id="rallyPrintDec">Dec</div>
Upvotes: 0
Reputation: 2799
Create an array of all the months, then loop through each month and compare the function parameter with each months name. If they're the same, show the element. Otherwise, hide the element.
function showMonth(monthName) {
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
months.forEach(month => {
const el = document.getElementById("rallyPrint" + month);
if (monthName === month) {
el.style.display = "block"; // Show current month
} else {
el.style.display = "none"; // Not the current month, hide
}
});
}
showMonth("Jan") // Only shows January
<div id="rallyPrintJan">Jan</div>
<div id="rallyPrintFeb">Feb</div>
<div id="rallyPrintMar">Mar</div>
<div id="rallyPrintApr">Apr</div>
<div id="rallyPrintMay">May</div>
<div id="rallyPrintJun">Jun</div>
<div id="rallyPrintJul">Jul</div>
<div id="rallyPrintAug">Aug</div>
<div id="rallyPrintSep">Sep</div>
<div id="rallyPrintOct">Oct</div>
<div id="rallyPrintNov">Nov</div>
<div id="rallyPrintDec">Dec</div>
Now you could pass the showMonth("Jan")
function to the onclick
attribute in your PHP.
Upvotes: 1