Bottom Menu Builder Part 2

Bottom Menu Builder Part 2

0 26120
Bottom Menu Builder Part 2 (HTML5)

Bottom Menu Builder Part 2 (HTML5)

Today – our final part of our ‘Bottom Menu Builder’ which we started yesterday. We are going to implement our final features: Preview and Export (optional). So, webmaster will be able to arrange links by drag and drop, and then he can click ‘Preview’ button in order to Preview (and export results). I moved all the links into a separate php file (and now, we can have direct access to these links from PHP). In your case it can be database as example (in case of big project). So, lets start..

As the first, I would suggest you to download the source files and keep the demo opened in a tab for better understanding.

Live Demo
download result

So, lets start


Step 1. HTML

Today we do not have a static html files, I moved the contents of our index.html into a new index.php file.

Step 2. CSS

In addition to our main.css file, I added a new css file (to stylize our preview page):

css/bmenu.css

/* menu builder styles */
.actions {
    border: 1px solid #CCCCCC;
    font-size: 24px;
    margin: 20px auto 5px;
    overflow: hidden;
    padding: 10px;
    width: 900px;
    /* CSS3 Box sizing property */
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
}
.columns {
    margin: 0 auto;
    overflow: hidden;
    width: 900px;
}
.column {
    border: 1px dotted #ccc;
    float: left;
    min-height: 100px;
    padding: 10px;
    position: relative;
    width: 33.3%;
    /* CSS3 Box sizing property */
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
}
.column a {
    cursor: pointer;
    display: block;
    font-size: 16px;
    height: 30px;
    margin-bottom: 5px;
    position: relative;
    text-align: center;
}

Step 3. JS

Please add next code to our main.js file (at the bottom, right after the call of updateHandlerDrop):

js/main.js

// preview button
var previewBtn = document.querySelectorAll('#preview');
addEvent(previewBtn, 'click', function (event) {
    if (event.preventDefault) event.preventDefault();
    var params = '';
    var oColumns = document.querySelectorAll('div.column');
    for (var i = 0; i < oColumns.length; i++) {
        var iCol = i+1;
        var sColElems = '';
        for (var k = 0; k < oColumns[i].childNodes.length; k++) {
            if (oColumns[i].childNodes[k].nodeType == document.ELEMENT_NODE && oColumns[i].childNodes[k].tagName == 'A') {
                sColElems += oColumns[i].childNodes[k].id + '_';
            }
        }
        params += iCol + '=' + sColElems + '&';
    }
    // open results
    var http = new XMLHttpRequest();
    http.open('POST', 'preview.php', true);
    http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    http.setRequestHeader('Content-length', params.length);
    http.setRequestHeader('Connection', 'close');
    http.onreadystatechange = function() {
        if (http.readyState == 4 && http.status == 200) {
            document.open();
            document.write(http.responseText);
            return;
        }
    }
    http.send(params);
    return false;
});

This is Preview button code. As you can see – it prepares all necessary params in order to send to our new ‘preview.php’. Basically, this is some kind of serialization of our active links (in columns).

Step 4. PHP

Now, its time to review our server side scripting. As I told before, I moved all the links into separate php file (links.php), here it is:

links.php

<?
$aLinks = array(
    1 => array('Link 1', '#link1'),
    2 => array('Link 2', '#link2'),
    3 => array('Link 3', '#link3'),
    4 => array('Link 4', '#link4'),
    5 => array('Link 5', '#link5'),
    6 => array('Link 6', '#link6'),
    7 => array('Link 7', '#link7'),
    8 => array('Link 8', '#link8'),
    9 => array('Link 9', '#link9'),
    10 => array('Link 10', '#link10'),
    11 => array('Link 11', '#link11'),
    12 => array('Link 12', '#link12')
);

Now I should generate code for our index page (with builder) with using this array:

index.php

<?php
require_once('links.php'); // include set of all possible links
// prepare draggable elements
$sLinks = '';
foreach ($aLinks as $i => $aPair) {
    list($sText, $sUrl) = $aPair;
    $sLinks .= '<a id="'.$i.'" draggable="true">'.$sText.'</a>';
}
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Bottom Menu Builder (HTML5) - Step 2 (of 2) | Script Tutorials</title>
        <link href="css/main.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <header tabindex="0">
            <h2>Bottom Menu Builder (HTML5) - Step 2 (of 2)</h2>
            <a href="https://www.script-tutorials.com/bottom-menu-builder-html5-2/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
        </header>
        <div class="actions">
            Actions:
            <button id="preview">Preview</button>
            <button id="add_col">Add Column</button>
        </div>
        <div class="actions">Columns (with active elements)</div>
        <div class="columns">
            <div class="column" id="drop_1" droppable="true"><img src="images/delete.png" onclick="removeColumn(this)" /></div>
            <div class="column" id="drop_2" droppable="true"><img src="images/delete.png" onclick="removeColumn(this)" /></div>
            <div class="column" id="drop_3" droppable="true"><img src="images/delete.png" onclick="removeColumn(this)" /></div>
        </div>
        <div style="clear:both"></div>
        <div class="actions">All (inactive) elements. You can drag these elements into columns.</div>
        <div class="inactive" droppable="true">
            <?= $sLinks ?>
        </div>
        <script src="js/main.js"></script>
    </body>
</html>

And finally, our preview page:

preview.php

<?php
require_once('links.php'); // include set of all possible links
$sColumns = '';
$iColCnt = count($_POST); // Columns count
$dWidth = round(100 / $iColCnt, 1); // Column width
foreach ($_POST as $sCol => $sColEls) { // walk through all POST params
    $iColId = (int)$sCol; // Column ID
    $sColumns .= '<div class="column" style="width:'.$dWidth.'%">';
    $aEls = explode('_', $sColEls); // obtain elements in column
    if (is_array($aEls) && count($aEls)) {
        foreach ($aEls as $iPos => $sEl) { // walk through all elements
            $iEl = (int)$sEl;
            if ($iEl) {
                list($sText, $sUrl) = $aLinks[$iEl];
                $sColumns .= '<a href="'.$sUrl.'">'.$sText.'</a>';
            }
        }
    }
    $sColumns .= '</div>';
}
// Here you can save current value of $sColumns into some cache file
//file_put_contents('cache/bottom_menu.html', $sColumns);
?>
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Bottom Menu Builder (HTML5) - Step 2 (of 2) | Script Tutorials</title>
        <link href="css/bmenu.css" rel="stylesheet" type="text/css" />
    </head>
    <body>
        <header tabindex="0">
            <h2>Bottom Menu Builder (HTML5) - Step 2 (of 2)</h2>
            <a href="https://www.script-tutorials.com/bottom-menu-builder-html5-2/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
        </header>
        <div class="actions">Result bottom menu (preview)
            <a href="index.php" style="float:right">Start again</a>
        </div>
        <div class="columns">
            <?= $sColumns /*and finally - draw our result menu*/ ?>
        </div>
    </body>
</html>

Small code at the top – preparing of result bottom menu (with columns). As you can see, you even can uncomment ‘file_put_contents’ in order to generate cache file of result menu.


Live Demo
download result

Conclusion

That’s all, I hope that we have made really user friendly script – html5 drag and drop menu builder. Hope that our tutorial has helped you. Feel free to share our tutorials with your friends. Good luck!

SIMILAR ARTICLES

Understanding Closures

0 21865

NO COMMENTS

Leave a Reply