Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Trash Can - CanJS 3.1">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<script type="text/stache" id="folder-template">
<span ($click)="toggleOpen()" 
      class="{{#if isOpen}}isOpen{{/if}}">{{folder.name}}</span>
{{#if isOpen}}
  {{#if entitiesPromise.isPending}}
    <div class="loading">Loading</div>
  {{else}}
    <ul>
    {{#each entitiesPromise.value}}
      <li class="{{type}} {{#if hasChildren}}hasChildren{{/if}}">
        {{#eq type 'file'}}
          📝 <span>{{name}}</span>
        {{else}}
          📁<a-folder {folder}="this"/>
        {{/eq}}
      </li>
    {{/each}}
    </ul>
  {{/if}}
{{/if}}
</script>
<script type="text/stache" id="app-template">
  <a-folder {folder}="rootFolder" {is-open}="true"/>
</script>
<script src="//unpkg.com/can/dist/global/can.all.js"></script>
</body>
</html>
 
body {
  padding: 10px;
}
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono:400,700');
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
  font-family: "Roboto Mono", "Lucida Console", Monaco, monospace;
  font-size: 14px;
  color: #000;
}
ul {
  list-style: none;
}
li {
  padding-left: 20px;
  position: relative;
  line-height: 2em;
}
li:before{
  position: absolute;
  left: 5px;
  top: -2px;
  content: '';
  display: block;
  height: 1em;
  border-bottom: 1px solid #bbb;
  width: 10px;
}
li:after {
  position: absolute;
  left: 5px;
  bottom: 0;
  content: '';
  display: block;
  border-left: 1px solid #bbb;
  height: 100%;
}
.loading {
  color: black;
  padding-left: 20px;
  padding-top: 10px;
  padding-bottom: 10px;
}
.loading:after {
  content: "...";
}
.hasChildren > a-folder > span {
  transition: all .1s ease-in-out;
  cursor: pointer;
  border-bottom: 1px dotted #000;
}
.hasChildren > a-folder > span:hover {
  opacity: .5;
}
 
var entityId = 1;
var makeEntities = function(parentId, depth){
  if(depth > 5) {
    return [];
  }
  var num = can.fixture.rand(10);
  var entities = [];
  
  for(var i = 0 ;  i< num; i++) {
    var id = entityId++;
    var isFolder = Math.random() > 0.3;
    var children = [];
    if(isFolder) {
      children = makeEntities(id, depth+1);
    }
    var entity = {
      id: id,
      name: (isFolder ? "Folder" : "File")+" "+id,
      parentId: ""+parentId,
      type: (isFolder ? "folder" : "file"),
      hasChildren: children.length ? true : false
    };
    entities.push(entity);
    [].push.apply(entities, children)
  }
  return entities;
};
var entities = makeEntities(0, 0)
var entitiesStore = can.fixture.store(entities);
can.fixture("/entities", entitiesStore);
can.fixture.delay = 1000;
var Entity = can.DefineMap.extend({
  id: "string",
  name: "string",
  parentId: "string",
  hasChildren: "boolean",
  type: {value: "string"}
});
Entity.List = can.DefineList.extend({
  "#": Entity
})
Entity.connection = can.connect.baseMap({
  url: "/entities",
  Map: Entity,
  List: Entity.List
});
var FolderVM = can.DefineMap.extend({
  folder: Entity,
  isOpen: "boolean",
  entitiesPromise: {
    value: function(){
      return Entity.getList({parentId: this.folder.id});
    }
  },
  toggleOpen: function(){
    if(this.folder.hasChildren) {
      this.isOpen = !this.isOpen;
    }
  }
});
can.Component.extend({
  tag: "a-folder",
  ViewModel: FolderVM,
  view: can.stache.from("folder-template")
});
var rootFolder = new Entity({
  id: "0",
  name: "ROOT/", 
  hasChildren: true,
  type: "folder"
});
document.body.appendChild( can.stache.from("app-template")({rootFolder: rootFolder}) );
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
justinbmeyerpro
0viewers