context menu

by bighostkim

HTML

<div id="menu" style="z-index:100">
    <ul>
        <li id="add">Add</li>
        <li id="rename">Rename</li>
        <li id="delete">Delete</li>
    </ul>
</div>

<ul id="dragObject" style="display:none">
</ul>

<ul id="tree">
    <li><i>+</i><b>Root</b>
        <ul>
            <li><i>+</i><b>Foo</b>
            <ul>
                <li><i>+</i><b>Bar</b>
                    <ul>
                        <li><i>+</i><b>FooBar</b>
                            <ul>
                                <li><b>1</b></li>
                                <li><b>2</b></li>
                                <li><b>3</b></li>
                                <li><b>4</b></li>
                                <li><b>5</b></li>
                            </ul>
                        </li>
                    </ul>
                 </li>
              </ul>
          </li>
       </ul>
    </li>
</ul>

CSS

#menu {
  position: absolute;
  display:none;
  border:1px solid black;
  background-color: #ccc;
}
li {
  border: 1px solid black;
}
li.selected { background-color:#ccc; }
li ul {
  margin-left: 10px;
}
li ul b {
   background-color: #eee;
}

JavaScript

function contextMenu() {
  var cmLiEl = $(this).closest("li");
  $("#menu").css({ top: $(this).offset().top + 10, left: $(this).offset().left + 10 });
  $("#menu #add").unbind('click').click( function() {contextMenuAdd(cmLiEl) });
  $("#menu #rename").unbind('click').click( function() {contextMenuRename(cmLiEl) });
  $("#menu #delete").unbind('click').click( function() {contextMenuDelete(cmLiEl) });
  $("#menu").show();
  return false;
}

function contextMenuAdd(cmLiEl) {
  if ( cmLiEl.find("ul").length == 0) {  // if no child tree
    cmLiEl.append("<ul></ul>");
    cmLiEl.find("> b").before("<i>+</i>");
    cmLiEl.find("> i").click( foldUnfold );
  }
  cmLiEl.find("> ul").append("<li><b>New Element</b></li>");
  $("#menu").hide();
}

function contextMenuRename(cmLiEl) {
  var newName = prompt("Enter a new name", "");
  cmLiEl.find("b").text(newName);
  $("#menu").hide();
}

function contextMenuDelete(cmLiEl) {
  if ( cmLiEl.parent().find(".selected").length )
    cmLiEl.parent().find(".selected").remove();
  else if ( cmLiEl.parent().find("li").length == 1 ) { // if last element
    cmLiEl.parent().parent().find("i").remove();  // remove foldUnfold from parent
    cmLiEl.parent().remove(); // remove <ul>
  } else {
    cmLiEl.remove();
  }
  $("#menu").hide();
}
                                            
                                            function foldUnfold() {
    $(this).parent().find("> ul").toggle();
}

$( function() {
  $("#tree li i").click( foldUnfold );
  $("#tree li b").live('contextmenu', contextMenu );

  var mouseDown=false, dragging=false;
  $("#tree li").live('click', function(e) {
    $(this).toggleClass('selected');
    e.stopPropagation();
  });
  $("#tree li").mousedown( function(e) {
    if (e.which == 1) { //only left click counts
      mouseDown=true;
      dragObject = $("#dragObject").empty().append($("#tree .selected").clone());
    }
    e.stopPropagation();
    e.preventDefault()
  });
  $("#tree li").mousemove( function(e)...