Skip to content

I Cannot drop generated elements

I am working on a website that can generate templates with drag and drop. I have made an element generator. But the problem is that I can only drag and drop the elements that are already in the “container” as an example ” already button” but the generated items are not droppable. I’m new to JavaScript so don’t know much about it. Please solve this problem. So I may continue to work on my website Here is my code

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    body {
        margin: 0;
    }
    
    .container {
        background-color: #333;
        padding: 1rem;
        margin-top: 1rem;
    }
    
    .draggable {
        padding: 1rem;
        background-color: white;
        border: 1px solid black;
        cursor: move;
    }
    
    .draggable.dragging {
        opacity: .5;
    }
    /* Background Styles Only */
    
    @import url('https://fonts.googleapis.com/css?family=Raleway');
    * {
        font-family: Raleway;
    }
    
    .side-links {
        position: absolute;
        top: 15px;
        right: 15px;
    }
    
    .side-link {
        display: flex;
        align-items: center;
        justify-content: center;
        text-decoration: none;
        margin-bottom: 10px;
        color: white;
        width: 180px;
        padding: 10px 0;
        border-radius: 10px;
    }
    
    .side-link-youtube {
        background-color: red;
    }
    
    .side-link-twitter {
        background-color: #1DA1F2;
    }
    
    .side-link-github {
        background-color: #6e5494;
    }
    
    .side-link-text {
        margin-left: 10px;
        font-size: 18px;
    }
    
    .side-link-icon {
        color: white;
        font-size: 30px;
    }
</style>

<body>
    <textarea id="ambtnhtml" name="generatedCode1" class="generatedCode1"> <button type="button" class="draggable"  id=""  draggable ="true"> Button</button></textarea>

    <!-- area -->
    <button type="button" id="generatehtml">generate button </button>
    <div class="container pipp" style="margin: auto;">

        <button type="button" class="draggable AM-btnhj" id="" draggable="true">Already Button</button>


    </div>
    <div class="container">

    </div>
</body>
<!-- drag and drop able script -->
<script>
    const draggables = document.querySelectorAll('.draggable')
    const containers = document.querySelectorAll('.container')

    draggables.forEach(draggable => {
        draggable.addEventListener('dragstart', () => {
            draggable.classList.add('dragging')
        })

        draggable.addEventListener('dragend', () => {
            draggable.classList.remove('dragging')
        })
    })

    containers.forEach(container => {
        container.addEventListener('dragover', e => {
            e.preventDefault()
            const afterElement = getDragAfterElement(container, e.clientY)
            const draggable = document.querySelector('.dragging')
            if (afterElement == null) {
                container.appendChild(draggable)
            } else {
                container.insertBefore(draggable, afterElement)
            }
        })
    })

    function getDragAfterElement(container, y) {
        const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]

        return draggableElements.reduce((closest, child) => {
            const box = child.getBoundingClientRect()
            const offset = y - box.top - box.height / 2
            if (offset < 0 && offset > closest.offset) {
                return {
                    offset: offset,
                    element: child
                }
            } else {
                return closest
            }
        }, {
            offset: Number.NEGATIVE_INFINITY
        }).element
    }
</script>
<!-- add new button -->
<script src="http://code.jquery.com/jquery-1.8.1.min.js"></script>
<script>
    $(document).ready(function() {
        $("#generatehtml").click(function() {
            $(".pipp").append($("#ambtnhtml").val());
            $("ambtnhtml").val("");
        });

    });
</script>

</html>

Please Help

Answer

You missed adding event handlers to the new elements. I modified your example by adding event handlers to a separate function initDraggable so that later it would be easier to use it when generating new elements.

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<style>
    body {
        margin: 0;
    }
    
    .container {
        background-color: #333;
        padding: 1rem;
        margin-top: 1rem;
    }
    
    .draggable {
        padding: 1rem;
        background-color: white;
        border: 1px solid black;
        cursor: move;
    }
    
    .draggable.dragging {
        opacity: .5;
    }
    /* Background Styles Only */
    
    @import url('https://fonts.googleapis.com/css?family=Raleway');
    * {
        font-family: Raleway;
    }
    
    .side-links {
        position: absolute;
        top: 15px;
        right: 15px;
    }
    
    .side-link {
        display: flex;
        align-items: center;
        justify-content: center;
        text-decoration: none;
        margin-bottom: 10px;
        color: white;
        width: 180px;
        padding: 10px 0;
        border-radius: 10px;
    }
    
    .side-link-youtube {
        background-color: red;
    }
    
    .side-link-twitter {
        background-color: #1DA1F2;
    }
    
    .side-link-github {
        background-color: #6e5494;
    }
    
    .side-link-text {
        margin-left: 10px;
        font-size: 18px;
    }
    
    .side-link-icon {
        color: white;
        font-size: 30px;
    }
</style>

<body>
    <textarea id="ambtnhtml" name="generatedCode1" class="generatedCode1"> <button type="button" class="draggable"  id=""  draggable ="true"> Button</button></textarea>

    <!-- area -->
    <button type="button" id="generatehtml">generate button </button>
    <div class="container pipp" style="margin: auto;">

        <button type="button" class="draggable AM-btnhj" id="" draggable="true">Already Button</button>


    </div>
    <div class="container">

    </div>
</body>
<!-- drag and drop able script -->
<script>
    const draggables = document.querySelectorAll('.draggable')
    const containers = document.querySelectorAll('.container')
    
    function initDraggable (draggable) {
        draggable.addEventListener('dragstart', () => {
            draggable.classList.add('dragging')
        })

        draggable.addEventListener('dragend', () => {
            draggable.classList.remove('dragging')
        })
    }

    draggables.forEach(initDraggable)

    containers.forEach(container => {
        container.addEventListener('dragover', e => {
            e.preventDefault()
            const afterElement = getDragAfterElement(container, e.clientY)
            const draggable = document.querySelector('.dragging')
            if (afterElement == null) {
                container.appendChild(draggable)
            } else {
                container.insertBefore(draggable, afterElement)
            }
        })
    })

    function getDragAfterElement(container, y) {
        const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]

        return draggableElements.reduce((closest, child) => {
            const box = child.getBoundingClientRect()
            const offset = y - box.top - box.height / 2
            if (offset < 0 && offset > closest.offset) {
                return {
                    offset: offset,
                    element: child
                }
            } else {
                return closest
            }
        }, {
            offset: Number.NEGATIVE_INFINITY
        }).element
    }
</script>
<!-- add new button -->
<script src="http://code.jquery.com/jquery-1.8.1.min.js"></script>
<script>
    $(document).ready(function() {
        $("#generatehtml").click(function() {
            const newDraggable = $($("#ambtnhtml").val())
            initDraggable(newDraggable.get(0))
            $(".pipp").append(newDraggable);
            $("ambtnhtml").val("");
        });

    });
</script>

</html>