JSFiddle - React, Tailwind, and code Playground

by opherv

HTML

<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>
<script id="tmpl_menuItem" type="text/x-jquery-tmpl">
    <li class="menuItem ${cssclass}">
        <a href="${url}" target="${target}" title="${title}" class="title">${title}</a>
		<div class="btnRow">
            <a href="#" class="btn_item icon-pencil"></a>
            <a href="#" class="btn_item icon-link"></a>        
            <a href="#" class="btn_item icon-eye"></a>  
            <a href="#" class="btn_item icon-close"></a>
        </div>        
    </li>
</script>


<script id="tmpl_menuOptions" type="text/x-jquery-tmpl">
    <div class="menuOptions">        
            <a href="#" class="btn_item icon-plus" title="add item"></a>
            <a href="#" class="btn_item icon-disk" title="save"></a>
    </div>
</script>

<div class="menuItems"></div>

CSS

ul{
  padding-bottom: 20px;
}

ul ul{
    min-height: 10px;
    background-color: white;
}

ul ul ul{
    display: none;
}

li ul{
    margin-top: 4px;
}

li, li li {  
  border-top: 1px solid black;
  padding: 0px 0px;
}

li:first-child, li li:first-child{
  border-top: 0px solid black;
}

li {    
    background-color: black;
    padding-top: 4px;    
    cursor: move;
}

li a{
    color: white;    
    text-decoration: none;    
}


li li {
    background-color: white;
    padding: 6px;
    margin-left: 10px;
}

li li a{    
    color: black;
    text-decoration: none;
}

a.title{
    padding-left: 8px;
}



.btn_item {    
	display: inline-block;
	width: 12px;
	height: 12px;
	background-image:...

JavaScript

function renderOptions(){
    return $("#tmpl_menuOptions").tmpl()
}


function renderList(listData){
  var menuElement = $("<ul></ul>");
  
  for (nodeIndex in listData.menu_items){
    var node=listData.menu_items[nodeIndex];
    var nodeElement = renderNode(node);
    menuElement.append(nodeElement);
  }
  
  return menuElement;
}

function renderNode(node){
    var nodeElement=$("#tmpl_menuItem").tmpl({
        url: node.item_data.url,
        target: node.item_data.target,
        cssclass: node.item_data.class,
        title: node.item_data.title
    });  
    
    
    var submenuElement=$("<ul></ul>");
    for (childIndex in node.children){
      var subNode=node.children[childIndex];
      submenuElement.append(renderNode(subNode));
    }
       
    nodeElement.append(submenuElement);
  
  
  return nodeElement;
}

function init(elementClass){
  var menuContainer=$("."+elementClass);
  var navElement=renderList(top_nav);  
  menuContainer.append(navElement);

	//tie actions    
   menuContainer.find("ul, ul ul").sortable({ connectWith: "."+elementClass+" ul",
                                         dropOnEmpty: true,
                                         placeholder: "menuItem_placeholder"
                                  }).disableSelection();
        
    menuContainer.find(".icon-close").click(function(){
        var item=$($(this).parents("li")[0]);
        var itemName=item.find("a.title").attr("title");
        var doDelete=confirm("are you sure you want to delete '"+itemName+"'?");
        if (doDelete){
        	item.remove();
        }
    });
    
    menuContainer.find(".icon-link").click(function(){
        var item=$($(this).parents("li")[0]);
        var itemURL=item.find("a.title").attr("href");
        var itemTarget=item.find("a.title").attr("target");
        
        var newUrl=prompt("enter URL:",itemURL);
        item.find("a.title").attr("href",newUrl);
        
		var newTarget=prompt("enter target:",itemTarget);
       ...