1

enter image description here

So I'm trying to make a little scheduling / calendar app for practice. It's all generated in JS and appended to the DOM.

The dark gray button with the date on it toggles the 'content' divs underneath, each of which contain the 'add' button, and task buttons afterwards. What I want to do is add other buttons in the same line as the task buttons, e.g. the remove button. So for instance, the task (subroutine) button takes 90% width, where the remove button takes 10%. However, when I do that, it seems to create this 1 or 2px margin at the bottom. And I can't figure out why.

EDIT: Whole thing added below I apologize for the horrid JS, I'm not too familiar with good practises for this type of thing.

BONUS QUESTION: Is it alright to re-render the whole DOM page from 0 in practise for a small app like this, i.e. when a certain element gets removed?

let routineData = {
    "dates" : [{
        "day" : 25,
        "month": 07,
        "year": 2019,
        "completion" : 2,
        "outof" : 3,
        "tags" : "",
        "subroutines" : [{
            "title" : "Example 1",
            "type" : "recurring",
            "state" : 1
        },
        {   "title": "Example two",
            "type": "warning",
            "state" : 0
        }]
    }]
};


function renderDOM(){

    let timespan = 5;
    let container = document.getElementById('schedule_container');
    let now = new Date(Date.now());
    let marker = now;
    
    marker.setDate(marker.getDate()-timespan);

    for(let i=0; i<timespan*2; i++){

        /* 1. Generate collapsible-day button */
            let dayElement = document.createElement('button');
            dayElement.setAttribute('class', 'collapsible');
            dayElement.setAttribute('data-day',marker.getDate());
            dayElement.setAttribute('data-month',marker.getMonth());
            dayElement.setAttribute('data-year',marker.getFullYear());
            dayElement.innerHTML = marker.getDate() + '/' + marker.getMonth() + "/" + marker.getFullYear();

            // 2. Generate container for collapsible content
            let content = document.createElement('div');
            content.setAttribute('class', 'content');
            //content.innerHTML = 'test';

            // 3. Collapsible-day button handler
            dayElement.addEventListener('click', function(){
                this.classList.toggle("active");
                let content = this.nextElementSibling;
                if(content.style.maxHeight){
                    content.style.maxHeight = null;
                } else {
                    content.style.maxHeight = content.scrollHeight + "px";
                }
            });
        
        /* 4. Add-subroutine button */
            let addbutton = document.createElement('button');
            addbutton.setAttribute('class','addRoutineButton');
            addbutton.setAttribute('data-day',marker.getDate());
            addbutton.setAttribute('data-month',marker.getMonth());
            addbutton.setAttribute('data-year',marker.getFullYear());
            addbutton.innerHTML = "+";

            // 5. Add-subroutine click handler 
            addbutton.addEventListener('click', function(){
                let date = addbutton.getAttribute('data-day');
                let month = addbutton.getAttribute('data-month');
                let year = addbutton.getAttribute('data-year');
                console.log("You're trying to add a new routine to date " + date + '/' + month + "/" + year);
            });

        /*6. Append finished product to DOM and repeat */
            content.appendChild(addbutton);
            container.appendChild(dayElement);
            container.appendChild(content);

            marker.setDate(marker.getDate() + 1);
    }

    // appending and aligning
    for(let i=0; i<routineData.dates.length; i++){
        //for each day
        let day = routineData.dates[i].day;
        let month = routineData.dates[i].month;
        let year = routineData.dates[i].year;

        let dayElem = document.querySelector('button[data-day="'+ day + '"]').nextSibling;

        for(let k=0; k<routineData.dates[i].subroutines.length;k++){
            //for each routine
            let currentRoutine = routineData.dates[i].subroutines[k];
            let routine = document.createElement('button');
            let stateElem = document.createElement('span');

            stateElem.style.float = "right";
            stateElem.innerHTML = currentRoutine.state ? "&#10003;" : "&#10539;";
            routine.setAttribute('class', 'subroutine ' + routineData.dates[i].subroutines[k].type)
            routine.innerHTML = routineData.dates[i].subroutines[k].title;
            routine.style.textDecoration = currentRoutine.state ? "line-through" : "none";

            let routineDelete = document.createElement('button');
            routineDelete.setAttribute('class', 'routineDelete');
            routineDelete.innerHTML = 'REMOVE';

            // Handle delete-routine button

                routineDelete.addEventListener('click', function(){
                    //1. remove JSON data
                        let query = routineData.dates.find(function(e){
                            return (e.day == day && e.month == month && e.year == year);
                        });

                        if(query){
                            console.log("You are trying to delete " + day + "/" + month + "/" + year + " routine no: " + k);
                            //routineData.dates[i].subroutines.splice(k,1);
                        } else {
                            console.log("error deleting");
                        }

                    //2. remove corresponding subroutine elements

                });

            dayElem.appendChild(routine);
            dayElem.appendChild(routineDelete);
            routine.appendChild(stateElem);
        }
    }
}

renderDOM();
.collapsible {
    background-color: #777;
    color: white;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    border: none;
    text-align: left;
    outline: none;
    font-size: 15px;
  }
  .addRoutineButton {
      padding: 5px;
      color: white;
      background-color: crimson;
      width: 75%;
      border: none;
      outline: none;
      font-size: 20px;
  }
  .addRoutineButton:hover {
      background-color:darkred;
      cursor: pointer;
  }
  
  .active, .collapsible:hover {
    background-color: #555;
  }
  
  .collapsible:after {
    content: '\002B';
    color: white;
    font-weight: bold;
    float: right;
    margin-left: 5px;
  }
  
  .active:after {
    content: "\2212";
  }
  
  .content {
    padding-left: 14px;
    padding-right: 14px;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease-out;
    background-color: #f1f1f1;
  }
  .subroutine {
    color: white;
    padding-top: 14px;
    padding-bottom: 14px;
    text-transform: uppercase;
    cursor: pointer;
    width: 90%;
    outline: none;
    border: none;
  }
  .recurring {
      background-color: seagreen;
  }
  .recurring:hover {
    background-color: darkgreen;
  }
  .warning {
      background-color: orangered;
  }
  .warning:hover {
    background-color: darkred;
  }
  .routineDelete {
    background-color: red;
    color: white;
    padding-top: 14px;
    padding-bottom: 14px;
    cursor: pointer;
    width: 10%;
    outline: none;
    border: none;
    text-transform: uppercase;
  }
  .routineDelete:hover {
    background-color: darkred;
  }
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>TSK MGR</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
      <div id="schedule_container">
          
      </div>

    <script type="text/javascript" src="scheduler.js"></script>
  
  </body>
</html>
Coma
  • 179
  • 10

0 Answers0