HTML5 Zone is brought to you in partnership with:

I was born in 1981 in one little city. Since I was 10y/o I programmed in different languages. My first languages were basic, then C++/MFC, after .Net (C#, VB.Net, J#, ASP.Net), XSL+XML processing). In the last 5 years I worked with web languages (HTML, CSS, PHP, SQL, XML, XSL, JavaScript). After university I worked in several different companies, eventually becoming a blogger. This is my hobby too. Andrey is a DZone MVB and is not an employee of DZone and has posted 106 posts at DZone. You can read more from them at their website. View Full User Profile

Bottom Menu Builder Part 2

05.29.2012
| 2435 views |
  • submit to reddit
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, let's 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 the 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="http://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="http://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 resulting bottom menu (with columns). As you can see, you even can uncomment ‘file_put_contents’ in order to generate the cache file of the result menu.

Live Demo

download result

Conclusion

That’s all, I hope that we have made a 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!

Published at DZone with permission of Andrey Prikaznov, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)