skip to Main Content

I’m trying to create a sliding menu for my web application that contains several buttons which should slide in from the right when a menu icon is clicked. I’ve attempted to use CSS for the sliding effect and JavaScript to handle the toggle functionality, but I’m encountering issues with the elements not behaving as expected.

Here’s a simplified version of the code I’m working with:

body, html {
    height: 100%;
    margin: 0;
    font-family: Arial, sans-serif;
    background-color: #333;
    color: white;
}

header {
    background-color: #222;
    padding: 10px 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

nav h1 {
    margin: 0;
}

nav ul {
    list-style: none;
    padding: 0;
    display: flex;
    gap: 10px;
}

nav ul li button {
    background-color: #555;
    border: none;
    padding: 10px 20px;
    color: white;
    cursor: pointer;
}

nav ul li button:hover {
    background-color: #666;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Taskboard</title>
    <link rel="stylesheet" href="/static/styling/home.css">
</head>
<body>
    <header>
        <nav>
            <h1>My New Taskboard</h1>
            <ul>
                <li>
                    <button id="update-button">Update</button>
                </li>
                <li><button id="edit-button">Edit</button></li>
                <li><button id="open-button">Open</button></li>
                <li><button id="new-button">New</button></li>
                <li><button id="settings-button">Settings</button></li>
            </ul>
        </nav>
    </header>
    <main>
        <section class="taskboard-grid" id="taskboard-grid">
            <!-- Task cards will be dynamically added here -->
        </section>

        <!-- Hidden form for creating a new taskboard -->
        <div id="new-taskboard-form" style="display: none;">
            <input type="text" id="new-taskboard-name" placeholder="Enter Taskboard Name">
            <input type="file" id="new-taskboard-file" accept=".xlsx">
            <button id="submit-new-taskboard">Create Taskboard</button>
        </div>
    </main>
    <script>

        document.getElementById('settings-button').addEventListener('click', function() {
            // To open in the same tab:
            window.location.href = 'settings';

        });
        // Global variable to keep track of the currently selected taskboard
        let currentTaskboard = null;

        document.getElementById('update-button').addEventListener('click', function() {
            if (!currentTaskboard) {
                alert('Please select a taskboard first.');
                return;
            }
        
            var fileInput = document.createElement('input');
            fileInput.type = 'file';
            fileInput.accept = '.xlsx';
        
            fileInput.addEventListener('change', function(event) {
                var file = event.target.files[0];
                var formData = new FormData();
                formData.append('file', file);
                formData.append('name', currentTaskboard); // Use the current taskboard
        
                fetch('/upload/', {
                    method: 'POST',
                    body: formData
                })
                .then(response => response.json())
                .then(data => {
                    // If the upload is successful, fetch and display the updated data
                    fetchTaskboardData(currentTaskboard);
                })
                .catch(error => {
                    console.error('Error:', error);
                });
            });
        
            fileInput.click();
        });

        document.getElementById('open-button').addEventListener('click', function() {
            fetch('/list/')
            .then(response => response.json())
            .then(taskboards => {
                showTaskboardSelector(Object.values(taskboards));
            })
            .catch(error => {
                console.error('Error fetching taskboards:', error);
            });
        });

        function showTaskboardSelector(taskboards) {
            var selector = document.createElement('select');
            selector.id = 'taskboard-selector';
            taskboards.forEach(taskboard => {
                var option = document.createElement('option');
                option.value = taskboard;
                option.textContent = taskboard;
                selector.appendChild(option);
            });

            document.body.appendChild(selector);

            selector.addEventListener('change', function() {
                currentTaskboard = this.value; // Update the current taskboard
                fetchTaskboardData(currentTaskboard);
            });
        }

        function fetchTaskboardData(taskboardName) {
            fetch(`/get/?name=${encodeURIComponent(taskboardName)}`)
            .then(response => response.json())
            .then(data => {
                var taskboardGrid = document.getElementById('taskboard-grid');
                taskboardGrid.innerHTML = ''; // Clear existing content

                // Check if data is an array and handle accordingly
                if (Array.isArray(data)) {
                    data.forEach(createCard);
                } else if (typeof data === 'object') {
                    // If data is an object, iterate over its values
                    Object.values(data).forEach(createCard);
                }
            })
            .catch(error => {
                console.error('Error fetching taskboard data:', error);
            });
        }

        function createCard(row) {
            var card = document.createElement('div');
            card.className = 'task-card';
            Object.keys(row).forEach(key => {
                if (row[key] !== null && row[key] !== undefined) {  // Check for non-null and non-undefined values
                    var p = document.createElement('p');
                    p.textContent = `${key}: ${row[key]}`;
                    card.appendChild(p);
                }
            });
            document.getElementById('taskboard-grid').appendChild(card);
        }
        

     //   function createCard(row) {
        //    var card = document.createElement('div');
            //card.className = 'task-card';
          //  Object.keys(row).forEach(key => {
                //var p = document.createElement('p');
              //  p.textContent = `${key}: ${row[key]}`;
            //    card.appendChild(p);
          //  });
        //    document.getElementById('taskboard-grid').appendChild(card);
       // }



        // Event listener for the 'Edit' button
        document.getElementById('edit-button').addEventListener('click', function() {
            if (!currentTaskboard) {
                alert('Please select a taskboard first.');
                return;
            }
            
            // Change the window location to your edit page and pass the taskboard name as a query parameter
            window.location.href = `/edit?name=${encodeURIComponent(currentTaskboard)}`;
        });
        


        
        // New functionality for the 'New' button
        document.getElementById('new-button').addEventListener('click', function() {
            document.getElementById('new-taskboard-form').style.display = 'block';
        });

        document.getElementById('submit-new-taskboard').addEventListener('click', function() {
            var taskboardName = document.getElementById('new-taskboard-name').value;
            var fileInput = document.getElementById('new-taskboard-file');
            var file = fileInput.files[0];

            if (!taskboardName || !file) {
                alert('Please enter a taskboard name and select a file.');
                return;
            }

            var formData = new FormData();
            formData.append('name', taskboardName);
            formData.append('file', file);

            fetch('/create', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                console.log('Taskboard created:', data);
                // Hide the form and clear inputs after successful creation
                document.getElementById('new-taskboard-form').style.display = 'none';
                document.getElementById('new-taskboard-name').value = '';
                fileInput.value = '';
            })
            .catch(error => {
                console.error('Error:', error);
            });
        });

        document.addEventListener('DOMContentLoaded', function() {
            const urlParams = new URLSearchParams(window.location.search);
            const taskboardName = urlParams.get('name');
            if (taskboardName) {
                // Code to open the specified taskboard
                // For example, if you have a function to load a taskboard by name, call it here
                openTaskboard(taskboardName);
            }
        });
    
        function openTaskboard(taskboardName) {
            // Implement the logic to open and display the taskboard by its name
            // This might involve setting the 'currentTaskboard' variable and calling a function to fetch and display its data
            currentTaskboard = taskboardName;
            fetchTaskboardData(taskboardName);
        }
    </script>
</body>
</html>

The expected behavior is that when the menu icon is clicked, the menu should slide in from the right with a smooth transition, and clicking the icon again should hide the menu with a similar sliding effect.

Actually, right now it is static as you can see at the picture below.

Here is how it looks now, it is static:

Here is how ot looks now

Here is how it should look like, this is when the buttons are expanded, please pay attention only to the header with the buttons:

enter image description here

This is when the buttons are not expanded:

enter image description here

Could someone help me understand what I’m doing wrong and how to achieve the sliding menu effect properly?

2

Answers


  1. You seem to have no onClick method on the buttons.
    And to get the sliding effect, you will need @keyframes in the CSS.

    Edit

    Read this: https://www.joshwcomeau.com/animation/keyframe-animations/

    Login or Signup to reply.
  2. You can use translate() function this way. I will also start by removing the buttons. You will also need to add onclick listener to slide back the non-clicked elements

    const hamburger = document.querySelector('.hamburger')
    const menu = document.querySelector('.menu')
    hamburger.addEventListener('click',()=>{
        menu.classList.add('showNavMenu')
    })
    body, html {
        height: 100%;
        margin: 0;
        font-family: Arial, sans-serif;
        background-color: #333;
        color: white;
    }
    
    header {
        background-color: #222;
        padding: 10px 20px;
        display: flex;
        justify-content: space-between;
        align-items: center;
    }
    
    nav h1 {
        margin: 0;
    }
    
    nav .hamburger{
        cursor: pointer;
    }
    nav ul {
        list-style: none;
        padding: 0;
        display: flex;
        gap: 10px;
        transform: translate(-200%);
        transition: transform 350ms ease-in-out;
    }
    
    ul li{
        display: inline-block;
        width: 100%;
        height: 100%;
        padding: 5px;
        background-color: #555;
        color: white;
    }
    
    ul li:hover{
        background-color: #333;
    }
    
    .showNavMenu{
        transform: translate(0%);
    }
        <header>
            <nav>
              <h1>My New Taskboard <span class="hamburger">&#9776;</span></h1>
              <ul class="menu">
                <li>Update </li>
                <li>Edit</li>
                <li>Open</li>
                <li>New</li>
                <li>Settings</li>
              </ul>
            </nav>
          </header>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search