0

I am creating an editable calendar, very similar to the one in Gmail. It is a grid of div boxes, and each div box can be clicked and a Modal will pop up where the user can edit/add data to that specific entry.

I am having one slight issue with my Modal within my For Loop. I understand the IDs used for the Divs must be unique, but my variable $i will echo accurately within div id="myBtn' . $i . '" but not accurate within div id="myModal' . $i . '" and the same applies to retrieving data from my database. Accurate within the "myBtn" div but not the "myModal" div.

Additionally, I can't close out of the Modal once I open it when I have the code set to div id="myModal' . $i . '" but when it is just div id="myModal" it functions fine, but the data is wrong.

I read the other posts similar to my issue, but couldn't seem to find a working solution. What am I doing wrong?

<?php

for($i = 0; $i <= 365; $i++){
$d=strtotime($i . " Day");

$day = date("l (m/d)", $d);

$end_month = date("l (m/01)", $d);

$str = strcmp($day, $end_month);

$query_date = date("m/d/Y l", $d);


$sql = "SELECT * FROM XXXXXXXX WHERE date = '$query_date' AND user_id = 1 ORDER BY start_time ASC";

$result = mysqli_query($connection, $sql);

    while($row = mysqli_fetch_array($result)){  

    $entry_id = $row['entry_id'];

    $schedule_date = date("l (m/d)", strtotime($row['date']));

    $location_name .= "<strong>" . $row['location_name'] . "</strong><br/>(" . $row['start_time'] . " - " . $row['end_time'] . ")<br/><br/>";

    }

$test = strcmp($day, $schedule_date);

    if($str == 0){
    echo '<div id="myBtn' . $i . '" class="menu2" style="width: 100%;">' . date("F", $d) . '</div>';        
    }   

        echo '
    <!-- The Modal -->
    <form action="" name="add-location" method="POST">
    <div id="myModal' . $i . '" class="modal">

     <!-- Modal content -->
    <div class="modal-content">
      <span class="close">×</span>

      <p style="color: black;">' . $i . '</p>

     <input type="text" name="" class="booking_input" style="width: 100%;" placeholder="' . $i . '"/>
     <input type="submit" name="submit" class="button" style="vertical-align: middle; line-height: 15px;" />

    </div>

    </div>
    </form>';

echo '<div id="myBtn' . $i . '" class="menu2" style="text-align: center;"><span style="font-size: 16px; color: #c11414;"><strong><u>' . $day . $i . '</u></strong></span></br/><br/>'; 
    if($test == 0){ 
    echo $location_name . "<br/>";  
    }

echo "</div>";

?>

<script>
// Get the modal
var modal = document.getElementById('myModal<?php echo $i; ?>');

// Get the button that opens the modal
var btn = document.getElementById("myBtn<?php echo $i; ?>");

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks the button, open the modal
btn.onclick = function() {
    modal.style.display = "block";
}

// When the user clicks on <span> (x), close the modal
span.onclick = function() {
    modal.style.display = "none";
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
    if (event.target == modal) {
        modal.style.display = "none";
    }
}
</script>

<?php

unset($location_name);
unset($address);
unset($start_time);
unset($end_time);

}

?>

Not very relevant, but here is the style tag to go with the above code:

<style>
* {
    box-sizing: border-box;
}
.header {
    border: .5px solid #2f363e;
    padding: 15px;
}
.menu2 {
    width: 14.28%;
    float: left;
    padding: 15px;
    border: .5px solid #2f363e;
    height: 150px;
    color: #2f363e;
}
.main {
    width: 75%;
    float: left;
    padding: 15px;
    border: .5px solid #2f363e;
}
</style>


<style>
/* The Modal (background) */
.modal {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    z-index: 1; /* Sit on top */
    padding-top: 100px; /* Location of the box */
    left: 0;
    top: 0;
    width: 100%; /* Full width */
    height: 100%; /* Full height */
    overflow: auto; /* Enable scroll if needed */
    background-color: rgb(0,0,0); /* Fallback color */
    background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}

/* Modal Content */
.modal-content {
    background-color: #fefefe;
    margin: auto;
    padding: 20px;
    border: 1px solid #888;
    width: 80%;
}

/* The Close Button */
.close {
    color: #aaaaaa;
    float: right;
    font-size: 28px;
    font-weight: bold;
    z-index: 1;
}

.close:hover,
.close:focus {
    color: #000;
    text-decoration: none;
    cursor: pointer;
    z-index: 1;
}
</style>

2 Answers 2

1

Why don't simply add the function calls direct to the buttons and use a general function to show/hide modal dialog? like this:

<?php

for($i = 0; $i <= 365; $i++){
$d=strtotime($i . " Day");

$day = date("l (m/d)", $d);

$end_month = date("l (m/01)", $d);

$str = strcmp($day, $end_month);

$query_date = date("m/d/Y l", $d);


$sql = "SELECT * FROM XXXXXXXX WHERE date = '$query_date' AND user_id = 1 ORDER BY start_time ASC";

$result = mysqli_query($connection, $sql);

    while($row = mysqli_fetch_array($result)){  

    $entry_id = $row['entry_id'];

    $schedule_date = date("l (m/d)", strtotime($row['date']));

    $location_name .= "<strong>" . $row['location_name'] . "</strong><br/>(" . $row['start_time'] . " - " . $row['end_time'] . ")<br/><br/>";

    }

$test = strcmp($day, $schedule_date);

    if($str == 0){
    echo '<div id="myBtn' . $i . '" class="menu2" style="width: 100%;">' . date("F", $d) . '</div>';        
    }   

        echo '
    <!-- The Modal -->
    <form action="" name="add-location" method="POST">
    <div id="myModal' . $i . '" class="modal">

     <!-- Modal content -->
    <div class="modal-content">
      <span class="close" onclick="closeModal('.$i.')">×</span>

      <p style="color: black;">' . $i . '</p>

     <input type="text" name="" class="booking_input" style="width: 100%;" placeholder="' . $i . '"/>
     <input type="submit" name="submit" class="button" style="vertical-align: middle; line-height: 15px;" />

    </div>

    </div>
    </form>';

echo '<div id="myBtn' . $i . '" class="menu2" onclick="showModal('.$i.')" style="text-align: center;"><span style="font-size: 16px; color: #c11414;"><strong><u>' . $day . $i . '</u></strong></span></br/><br/>'; 
    if($test == 0){ 
    echo $location_name . "<br/>";  
    }

echo "</div>";

?>

<?php

unset($location_name);
unset($address);
unset($start_time);
unset($end_time);

}

?>
<script>
function closeModal(id){
    // Get the modal
    var modal = document.getElementById('myModal'+id);
    modal.style.display = "none";
}

function showModal(id){
    // Get the modal
    var modal = document.getElementById('myModal'+id);
    modal.style.display = "block";
}
</script>
Sign up to request clarification or add additional context in comments.

1 Comment

This did the trick perfectly, thank you so much! My Javascript knowledge is rather poor... @Glufu
0

This is breaking because each iteration of the loop overwrites the javascript variables from the previous iteration.

To show you what I mean, look at this version of your loops distilled down to the simplest for that shows the bug

for ($i = 0; $i <= 2; $i++) {
    ?>
    <script>
        var modal = document.getElementById('myModal<?php echo $i; ?>');
    </script>
    <?php
}

The output of this will look like

<script>
    var modal = document.getElementById('myModal0');
</script>
<script>
    var modal = document.getElementById('myModal1');
</script>
<script>
    var modal = document.getElementById('myModal2');
</script>

Or perhaps re-written to be even more illustrative

<script>
    var modal = document.getElementById('myModal0');
    var modal = document.getElementById('myModal1');
    var modal = document.getElementById('myModal2');
</script>

Nothing in your implementation attempts to prevent this clobbering of the javascript variables. Glufu posted a solution that works, but it's based on HTML-DOM event handlers which is a pretty outdated way of doing things. You really should be using a library like jQuery to do this in a much better way

2 Comments

Thank you for your explanation Peter. Incrementing the Id to myModal0, myModal1, etc... is what I was trying to do. Just so I fully understand, could you briefly explain why this is an issue?
You mean why variables over-writing each other is a problem?

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.