1

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>";
        }
1
  • 1
    Please mention Full HTML code because that HTML code doesn't full fill your requirements. Commented Nov 27, 2019 at 12:25

4 Answers 4

2

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>

Sign up to request clarification or add additional context in comments.

12 Comments

This works ish.... I mean it kinda does it but in the wrong way. So when I click January, it prints the data from February. The similar to this when I click February it prints the data from January. @CertainPerformance
Well after testing it with the other months. I have realised it only prints January and February data, no matter what month I click, and it's like it takes turns to have a go.
Not sure what'd be causing that. It sounds like the problem might have to do with thisIndex, but thisIndex should be a number between 0 and 11, so rallyPrint[thisIndex] should select the appropriate rallyPrint element, assuming that they're in order too. Or are your rallyPrint elements not in order?
Yes they are in order, I believe it is printing them the wrong way. As I have added data for the months January, February, March, April, when I click April it will print January and when I click January it will print Aprils data etc.
I can't reproduce the problem. Run the live snippet in the answer, it seems to work as expected
|
1

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.

Comments

0

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>

Comments

0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.