Commit: 23609c81b59a1c6168d94a034e91b6f16d0ef2c5
Author: Nate Abele | Date: 2010-01-21 15:27:37 -0500
diff --git a/config/routes.php b/config/routes.php
index a3d5448..675c332 100644
--- a/config/routes.php
+++ b/config/routes.php
@@ -37,6 +37,6 @@ Router::connect('/test', array('controller' => '\lithium\test\Controller'));
*/
Router::connect('/{:controller}/{:action}/{:id}.{:type}', array('id' => null));
Router::connect('/{:controller}/{:action}/{:id}');
-Router::connect('/{:controller}/{:action}/{:args}');
+Router::connect('/{:controller}/{:action}/{:id}/{:args}');
?>
\ No newline at end of file
diff --git a/controllers/CollectionsController.php b/controllers/CollectionsController.php
index d032945..4df414d 100644
--- a/controllers/CollectionsController.php
+++ b/controllers/CollectionsController.php
@@ -23,6 +23,13 @@ class CollectionsController extends \lithium\action\Controller {
public function index() {
$collections = Connections::get('default')->entities();
+
+ if ($this->request->is('ajax')) {
+ $this->render(array(
+ 'template' => '../elements/collections', 'data' => compact('collections')
+ ));
+ return;
+ }
return compact('collections');
}
@@ -30,6 +37,41 @@ class CollectionsController extends \lithium\action\Controller {
$data = Collection::all(array('source' => $this->request->id));
return compact('data');
}
+
+ public function edit() {
+ $path = $this->request->args;
+ $_id = array_shift($path);
+
+ $item = $document = Collection::first(array(
+ 'source' => $this->request->id,
+ 'conditions' => compact('_id')
+ ));
+
+ foreach (array_slice($path, 0, -1) as $key) {
+ $item =& $item[$key];
+ }
+ $key = end($this->request->args);
+
+ if ($item->{$key} == $this->request->data['old']) {
+ $item->{$key} = $this->request->data['data'];
+ $document->save();
+ $this->render(array('text' => $this->request->data['data']));
+ return;
+ }
+ $this->render(array('text' => $this->request->data['old']));
+ }
+
+ protected function _coerceType($data) {
+ switch ($data) {
+ case 'null':
+ return null;
+ case 'true':
+ return true;
+ case 'false':
+ return false;
+ }
+ return is_numeric($data) ? floatval($data) : $data;
+ }
}
?>
\ No newline at end of file
diff --git a/views/collections/index.html.php b/views/collections/index.html.php
index c00acef..3a967b4 100644
--- a/views/collections/index.html.php
+++ b/views/collections/index.html.php
@@ -2,14 +2,5 @@
</div>
<div id="groups">
- <ul>
- <li class="title">Collections</li>
- <?php foreach ($collections as $collection) { ?>
- <li class="collection">
- <?=$this->html->link($collection, array(
- 'controller' => 'collections', 'action' => 'view', 'id' => $collection
- )); ?>
- </li>
- <?php } ?>
- </ul>
+ <?=$this->view()->render(array('element' => 'collections'), compact('collections')); ?>
</div>
diff --git a/views/collections/view.html.php b/views/collections/view.html.php
index ebe2861..9140d76 100644
--- a/views/collections/view.html.php
+++ b/views/collections/view.html.php
@@ -2,10 +2,11 @@
use \lithium\data\model\Document;
-$list = function($data) use (&$list, $h) {
+$list = function($data, $topLevel = false) use (&$list, $h) {
echo "<ul>";
foreach ($data as $key => $value) {
- echo '<li><div class="key">' . $h($key) . '</div>: ';
+ echo '<li' . ($topLevel ? ' class="document"' : '') . '>';
+ echo '<div class="key' . ($key === '_id' ? ' id' : '') . '">' . $h($key) . '</div>: ';
echo '<div class="value">';
switch (true) {
@@ -19,13 +20,13 @@ $list = function($data) use (&$list, $h) {
echo 'null';
break;
default:
- $list($value);
+ $list($value, false);
break;
}
echo '</div></li>';
}
echo "</ul>";
};
-$list($data);
+$list($data, true);
?>
diff --git a/views/elements/collections.html.php b/views/elements/collections.html.php
new file mode 100644
index 0000000..e1e9a4d
--- /dev/null
+++ b/views/elements/collections.html.php
@@ -0,0 +1,10 @@
+<ul>
+ <li class="title">Collections</li>
+ <?php foreach ($collections as $collection) { ?>
+ <li class="collection">
+ <?=$this->html->link($collection, array(
+ 'controller' => 'collections', 'action' => 'view', 'id' => $collection
+ )); ?>
+ </li>
+ <?php } ?>
+</ul>
diff --git a/views/layouts/default.html.php b/views/layouts/default.html.php
index 7fe984d..f31066a 100644
--- a/views/layouts/default.html.php
+++ b/views/layouts/default.html.php
@@ -5,6 +5,17 @@
* @copyright Copyright 2009, Union of RAD (http://union-of-rad.org)
* @license http://opensource.org/licenses/bsd-license.php The BSD License
*/
+
+use \lithium\http\Router;
+
+$urls = array(
+ 'index' => Router::match(array('controller' => 'collections'), $this->request()),
+ 'edit' => Router::match(
+ array('controller' => 'collections', 'action' => 'edit', 'id' => ':col', 'args' => ':args'),
+ $this->request()
+ ),
+);
+
?>
<!doctype html>
<html>
@@ -13,6 +24,9 @@
<title>MongoDB > <?=$this->title; ?></title>
<?=$this->html->style(array('base', 'detail', 'jquery.treeview')); ?>
<?=$this->html->script(array('jquery', 'app')); ?>
+ <script type="text/javascript">
+ urls = <?php echo json_encode($urls); ?>;
+ </script>
</head>
<body class="app">
<div id="container">
@@ -22,7 +36,14 @@
<div id="layout">
<?=$this->content; ?>
</div>
- <div id="footer"></div>
+ <div id="footer">
+ <div class="button-bar">
+ <button id="AddCollection" title="Add collection"></button>
+ <button id="RefreshCollections" title="Refresh collections"></button>
+ <button id="SelectDatabase" title="Select database"></button>
+ </div>
+ <span class="status"></span>
+ </div>
</div>
</body>
</html>
diff --git a/webroot/css/base.css b/webroot/css/base.css
index b1243fa..e479d9e 100644
--- a/webroot/css/base.css
+++ b/webroot/css/base.css
@@ -13,6 +13,10 @@ a:link, a:visited, a:active {
color: blue;
}
+*:focus {
+ outline: none;
+}
+
pre {
font-size: 80%;
color: #000;
@@ -144,28 +148,57 @@ pre {
position: absolute;
float: left;
width: 100%;
- height: 22px;
+ height: 24px;
bottom: 0;
font-size: 11px;
+ padding-top: 4px;
margin-top: -32px;
- padding-top: 8px;
text-align: center;
background: #C0C0C0 url(../img/footer-gradient.png);
font-family: Lucida Grande, Lucida, sans-serif;
}
-#footer ul {
+#footer .status {
+ display: block;
+ margin-top: 4px;
+}
+
+.button-bar {
+ padding: 1px 0 0 40px;
+ float: left;
+}
+
+.button-bar button {
+ height: 19px;
+ width: 39px;
padding: 0;
- margin: 1px;
+ border: 0;
+ margin: 0 -3px 0 0;
+ border-style: none;
}
-#footer li {
- font-size: 70%;
- color: #000;
- text-align: center;
- padding: 3px;
- display: block;
+#AddCollection {
+ background: url(../img/add.png) no-repeat 0 0;
+ width: 40px;
}
-#footer li.bold {
- font-weight: bold;
+
+#AddCollection.pressed {
+ background-image: url(../img/add-click.png);
}
+
+#RefreshCollections {
+ background: url(../img/refresh.png) no-repeat 0 0;
+}
+
+#RefreshCollections.pressed {
+ background-image: url(../img/refresh-click.png);
+}
+
+#SelectDatabase {
+ background: url(../img/select.png) no-repeat 0 0;
+}
+
+#SelectDatabase.pressed {
+ background-image: url(../img/select-click.png);
+}
+
diff --git a/webroot/css/detail.css b/webroot/css/detail.css
index 7950a86..cd3ffac 100644
--- a/webroot/css/detail.css
+++ b/webroot/css/detail.css
@@ -20,15 +20,20 @@
width: 150px;
color: purple;
overflow: hidden;
- padding-left: 15px;
+ padding: 0 0 3px 25px;
background-repeat: no-repeat;
- background-position: 50% left;
+ background-position: 8px 50%;
cursor: pointer;
}
.tree .value {
display: inline;
clear: right;
+ cursor: pointer;
+}
+
+.tree .value ul {
+ cursor: default;
}
.tree .key.open {
diff --git a/webroot/img/add-click.png b/webroot/img/add-click.png
new file mode 100644
index 0000000..bcf0d76
Binary files /dev/null and b/webroot/img/add-click.png differ
diff --git a/webroot/img/add.png b/webroot/img/add.png
new file mode 100644
index 0000000..2ebc24e
Binary files /dev/null and b/webroot/img/add.png differ
diff --git a/webroot/img/arrow.png b/webroot/img/arrow.png
new file mode 100644
index 0000000..7275b5a
Binary files /dev/null and b/webroot/img/arrow.png differ
diff --git a/webroot/img/refresh-click.png b/webroot/img/refresh-click.png
new file mode 100644
index 0000000..71d9558
Binary files /dev/null and b/webroot/img/refresh-click.png differ
diff --git a/webroot/img/refresh.png b/webroot/img/refresh.png
new file mode 100644
index 0000000..32d7c34
Binary files /dev/null and b/webroot/img/refresh.png differ
diff --git a/webroot/img/select-click.png b/webroot/img/select-click.png
new file mode 100644
index 0000000..24fe166
Binary files /dev/null and b/webroot/img/select-click.png differ
diff --git a/webroot/img/select.png b/webroot/img/select.png
new file mode 100644
index 0000000..009a028
Binary files /dev/null and b/webroot/img/select.png differ
diff --git a/webroot/js/app.js b/webroot/js/app.js
index a587074..7ce4d49 100644
--- a/webroot/js/app.js
+++ b/webroot/js/app.js
@@ -1,30 +1,93 @@
-$(document).ready(function() {
- $collections = $('.collection a');
+App = {
+ start: function() {
+ $collections = $('.collection a');
- $collections.bind('click', function() {
- $('.collection').removeClass('selected');
- $self = $(this);
+ $collections.bind('click', function() {
+ $('.collection').removeClass('selected');
+ $self = $(this);
- $('#main').load(this.href, null, function() {
- $self.parent().addClass('selected');
- $('#main > ul').tree();
+ $('#main').load(this.href, null, function() {
+ $self.parent().addClass('selected');
+ $('#main > ul').tree();
+ });
+ return false;
});
- return false;
+ },
+ status: function() {
+ $collections = $('.collection a');
+ text = " collection" + ($collections.length == 1 ? "" : "s") + " in database";
+ $('#footer .status').text($collections.length + text);
+ },
+ collections: {
+ refresh: function() {
+ $('#groups').load(location.toString(), {}, function() {
+ App.start();
+ App.status();
+ });
+ },
+ add: function() {
+ '<li class="collection"><input type="text" id="ColName" /></li>';
+ $('#groups > ul').append()
+ }
+ }
+};
+
+$(document).ready(function() {
+
+ $('.button-bar button').bind('mousedown', function() {
+ $(this).toggleClass('pressed');
+ }).bind('mouseup', function() {
+ $(this).toggleClass('pressed');
+ });
+
+ $('#RefreshCollections').bind('click', function() {
+ App.collections.refresh();
});
- text = " collection" + ($collections.length == 1 ? "" : "s") + " in database";
- $('#footer').text($collections.length + text);
+ App.start();
+ App.status();
});
jQuery.fn.tree = function(config) {
$keys = jQuery(this).addClass('tree').find(".value ul").hide().parent().prev(".key");
$keys.addClass("closed").bind('click', function() {
- if ($(this).hasClass('closed')) {
- $(this).next('.value').find('> ul').show();
- } else {
- $(this).next('.value').find('> ul').hide();
+ $self = jQuery(this);
+ $self.next('.value').find('> ul')[$self.hasClass('closed') ? 'show' : 'hide']();
+ $self.toggleClass('closed').toggleClass('open');
+ });
+
+ jQuery(this).find('.value:not(:has(ul))').bind('click', function() {
+ if ($(this).find('input').length > 0) {
+ return true;
}
- $(this).toggleClass('closed').toggleClass('open');
+ old = jQuery(this).text();
+ $in = jQuery(this).html('<input type="text" class="edit" value="" />').find('input');
+
+ $in.val(old).focus().bind('blur', function(e) {
+ val = $(this).val();
+ $node = $(this).parent();
+ $(this).parent().text();
+
+ mapper = function() { return encodeURIComponent($(this).text()); };
+ path = $node.parents('ul').parent().prev('.key').map(mapper).toArray();
+ path.push(encodeURIComponent($node.prev('.key').text()));
+ path.shift();
+ path = '/' + path.join('/');
+
+ _id = $node.parents('.document').find('.key.id:first').next('.value').text();
+ url = urls.edit.replace(':col', jQuery("#groups .selected a").text());
+ url = url.replace(':args', encodeURIComponent(_id) + path);
+ data = { data: val, old: old };
+
+ $.post(url, data, function(text) {
+ $node.html(text);
+ });
+ }).bind('keyDown', function(e) {
+ if (e.keyCode == 32) {
+ $(this).blur();
+ }
+ return true;
+ })
});
};