summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBharat Mediratta <bharat@menalto.com>2008-11-08 09:28:11 +0000
committerBharat Mediratta <bharat@menalto.com>2008-11-08 09:28:11 +0000
commit950c58e6d37f68f69815d4d73df5577b9789679a (patch)
treef8f176513d9b364b4b0a7b2a6e87ade8af11baeb
parentac8199a09a810277624c93fd82e49d2250ae0461 (diff)
Add support for in-place editing of data fields.
-rw-r--r--core/controllers/album.php2
-rw-r--r--core/controllers/item.php41
-rw-r--r--core/controllers/photo.php2
-rw-r--r--core/libraries/Theme.php4
-rw-r--r--core/models/item.php4
-rw-r--r--core/views/in_place_edit.html.php38
-rw-r--r--lib/jquery.jeditable.js30
-rw-r--r--themes/default/views/album.html.php6
-rw-r--r--themes/default/views/header.html.php6
-rw-r--r--themes/default/views/page.html.php3
10 files changed, 128 insertions, 8 deletions
diff --git a/core/controllers/album.php b/core/controllers/album.php
index 788ff9e2..d6b457d6 100644
--- a/core/controllers/album.php
+++ b/core/controllers/album.php
@@ -20,7 +20,7 @@
class Album_Controller extends Template_Controller {
public $template = "page.html";
- public function View($id) {
+ public function view($id) {
$item = ORM::factory("item")->where("id", $id)->find();
if (empty($item->id)) {
return Kohana::show_404();
diff --git a/core/controllers/item.php b/core/controllers/item.php
new file mode 100644
index 00000000..bb670f8a
--- /dev/null
+++ b/core/controllers/item.php
@@ -0,0 +1,41 @@
+<?php defined("SYSPATH") or die("No direct script access.");
+/**
+ * Gallery - a web based photo album viewer and editor
+ * Copyright (C) 2000-2008 Bharat Mediratta
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+class Item_Controller extends Controller {
+ public function view($id) {
+ $item = ORM::factory("item")->where("id", $id)->find();
+ if (empty($item->id)) {
+ return Kohana::show_404();
+ }
+
+ if (request::method() == 'get') {
+ if ($item->type == 'album') {
+ url::redirect("album/$id");
+ } else {
+ url::redirect("photo/$id");
+ }
+ } else {
+ $key = $this->input->post("key");
+ $value = $this->input->post("value");
+ $item->$key = $value;
+ $item->save();
+ print $value;
+ }
+ }
+}
diff --git a/core/controllers/photo.php b/core/controllers/photo.php
index 6f746e65..45db4b02 100644
--- a/core/controllers/photo.php
+++ b/core/controllers/photo.php
@@ -20,7 +20,7 @@
class Photo_Controller extends Template_Controller {
public $template = "page.html";
- public function View($id) {
+ public function view($id) {
$item = ORM::factory("item")->where("id", $id)->find();
if (empty($item->id)) {
return Kohana::show_404();
diff --git a/core/libraries/Theme.php b/core/libraries/Theme.php
index 0f195d08..239a4256 100644
--- a/core/libraries/Theme.php
+++ b/core/libraries/Theme.php
@@ -48,6 +48,10 @@ class Theme_Core {
return $this->pagination->render();
}
+ public function in_place_edit() {
+ return new View("in_place_edit.html");
+ }
+
public function blocks() {
/** @todo: make this data driven */
$blocks = array(
diff --git a/core/models/item.php b/core/models/item.php
index a32becc9..b83fe5c3 100644
--- a/core/models/item.php
+++ b/core/models/item.php
@@ -185,6 +185,10 @@ class Item_Model extends ORM_MPTT {
$this->owner = ORM::factory("user", $this->owner_id);
}
return $this->owner;
+ } else if (substr($column, -5) == "_edit") {
+ $real_column = substr($column, 0, strlen($column) - 5);
+ return "<span class=\"gInPlaceEdit gEditField-{$this->id}-{$real_column}\">" .
+ "{$this->$real_column}</span>";
} else {
return parent::__get($column);
}
diff --git a/core/views/in_place_edit.html.php b/core/views/in_place_edit.html.php
new file mode 100644
index 00000000..adcad6c6
--- /dev/null
+++ b/core/views/in_place_edit.html.php
@@ -0,0 +1,38 @@
+<? defined("SYSPATH") or die("No direct script access."); ?>
+<script type="text/javascript">
+$(document).ready(function() {
+ ajax_update = function(className, id) {
+ return function(value, settings) {
+ $.post("<?= url::site("item/__ID__") ?>".replace("__ID__", id),
+ {"key": settings.name, "value": value},
+ function(data, textStatus) {
+ if (textStatus == "success") {
+ $(className).html(data);
+ }
+ },
+ "html");
+ }
+ }
+
+ var seen_before = {};
+ var editable = $(".gInPlaceEdit");
+ for (i = 0; i < editable.length; i++) {
+ var matches = editable[i].className.match(/gEditField-(\d+)-(\S+)/);
+ if (matches && matches.length == 3) {
+ var className = "." + matches[0];
+ if (!seen_before[className]) {
+ $(className).editable(
+ ajax_update(className, matches[1]),
+ {indicator : "<?= _("Saving...") ?>",
+ tooltip : "<?= _("Double-click to edit...") ?>",
+ event : "dblclick",
+ style : "inherit",
+ name : matches[2],
+ select : true}
+ );
+ seen_before[className] = 1;
+ }
+ }
+ }
+});
+</script> \ No newline at end of file
diff --git a/lib/jquery.jeditable.js b/lib/jquery.jeditable.js
new file mode 100644
index 00000000..fdc46ff4
--- /dev/null
+++ b/lib/jquery.jeditable.js
@@ -0,0 +1,30 @@
+
+(function($){$.fn.editable=function(target,options){var settings={target:target,name:'value',id:'id',type:'text',width:'auto',height:'auto',event:'click',onblur:'cancel',loadtype:'GET',loadtext:'Loading...',placeholder:'Click to edit',loaddata:{},submitdata:{}};if(options){$.extend(settings,options);}
+var plugin=$.editable.types[settings.type].plugin||function(){};var submit=$.editable.types[settings.type].submit||function(){};var buttons=$.editable.types[settings.type].buttons||$.editable.types['defaults'].buttons;var content=$.editable.types[settings.type].content||$.editable.types['defaults'].content;var element=$.editable.types[settings.type].element||$.editable.types['defaults'].element;var reset=$.editable.types[settings.type].reset||$.editable.types['defaults'].reset;var callback=settings.callback||function(){};if(!$.isFunction($(this)[settings.event])){$.fn[settings.event]=function(fn){return fn?this.bind(settings.event,fn):this.trigger(settings.event);}}
+$(this).attr('title',settings.tooltip);settings.autowidth='auto'==settings.width;settings.autoheight='auto'==settings.height;return this.each(function(){var self=this;var savedwidth=$(self).width();var savedheight=$(self).height();if(!$.trim($(this).html())){$(this).html(settings.placeholder);}
+$(this)[settings.event](function(e){if(self.editing){return;}
+if(0==$(self).width()){settings.width=savedwidth;settings.height=savedheight;}else{if(settings.width!='none'){settings.width=settings.autowidth?$(self).width():settings.width;}
+if(settings.height!='none'){settings.height=settings.autoheight?$(self).height():settings.height;}}
+if($(this).html().toLowerCase().replace(/;/,'')==settings.placeholder.toLowerCase().replace(/;/,'')){$(this).html('');}
+self.editing=true;self.revert=$(self).html();$(self).html('');var form=$('<form/>');if(settings.cssclass){if('inherit'==settings.cssclass){form.attr('class',$(self).attr('class'));}else{form.attr('class',settings.cssclass);}}
+if(settings.style){if('inherit'==settings.style){form.attr('style',$(self).attr('style'));form.css('display',$(self).css('display'));}else{form.attr('style',settings.style);}}
+var input=element.apply(form,[settings,self]);var input_content;if(settings.loadurl){var t=setTimeout(function(){input.disabled=true;content.apply(form,[settings.loadtext,settings,self]);},100);var loaddata={};loaddata[settings.id]=self.id;if($.isFunction(settings.loaddata)){$.extend(loaddata,settings.loaddata.apply(self,[self.revert,settings]));}else{$.extend(loaddata,settings.loaddata);}
+$.ajax({type:settings.loadtype,url:settings.loadurl,data:loaddata,async:false,success:function(result){window.clearTimeout(t);input_content=result;input.disabled=false;}});}else if(settings.data){input_content=settings.data;if($.isFunction(settings.data)){input_content=settings.data.apply(self,[self.revert,settings]);}}else{input_content=self.revert;}
+content.apply(form,[input_content,settings,self]);input.attr('name',settings.name);buttons.apply(form,[settings,self]);$(self).append(form);plugin.apply(form,[settings,self]);$(':input:visible:enabled:first',form).focus();if(settings.select){input.select();}
+input.keydown(function(e){if(e.keyCode==27){e.preventDefault();reset.apply(form,[settings,self]);}});var t;if('cancel'==settings.onblur){input.blur(function(e){t=setTimeout(function(){reset.apply(form,[settings,self]);},500);});}else if('submit'==settings.onblur){input.blur(function(e){form.submit();});}else if($.isFunction(settings.onblur)){input.blur(function(e){settings.onblur.apply(self,[input.val(),settings]);});}else{input.blur(function(e){});}
+form.submit(function(e){if(t){clearTimeout(t);}
+e.preventDefault();if(false!==submit.apply(form,[settings,self])){if($.isFunction(settings.target)){var str=settings.target.apply(self,[input.val(),settings]);$(self).html(str);self.editing=false;callback.apply(self,[self.innerHTML,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}}else{var submitdata={};submitdata[settings.name]=input.val();submitdata[settings.id]=self.id;if($.isFunction(settings.submitdata)){$.extend(submitdata,settings.submitdata.apply(self,[self.revert,settings]));}else{$.extend(submitdata,settings.submitdata);}
+if('PUT'==settings.method){submitdata['_method']='put';}
+$(self).html(settings.indicator);$.post(settings.target,submitdata,function(str){$(self).html(str);self.editing=false;callback.apply(self,[self.innerHTML,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}});}}
+return false;});});this.reset=function(){$(self).html(self.revert);self.editing=false;if(!$.trim($(self).html())){$(self).html(settings.placeholder);}}});};$.editable={types:{defaults:{element:function(settings,original){var input=$('<input type="hidden">');$(this).append(input);return(input);},content:function(string,settings,original){$(':input:first',this).val(string);},reset:function(settings,original){original.reset();},buttons:function(settings,original){var form=this;if(settings.submit){if(settings.submit.match(/>$/)){var submit=$(settings.submit).click(function(){if(submit.attr("type")!="submit"){form.submit();}});}else{var submit=$('<button type="submit">');submit.html(settings.submit);}
+$(this).append(submit);}
+if(settings.cancel){if(settings.cancel.match(/>$/)){var cancel=$(settings.cancel);}else{var cancel=$('<button type="cancel">');cancel.html(settings.cancel);}
+$(this).append(cancel);$(cancel).click(function(event){if($.isFunction($.editable.types[settings.type].reset)){var reset=$.editable.types[settings.type].reset;}else{var reset=$.editable.types['defaults'].reset;}
+reset.apply(form,[settings,original]);return false;});}}},text:{element:function(settings,original){var input=$('<input>');if(settings.width!='none'){input.width(settings.width);}
+if(settings.height!='none'){input.height(settings.height);}
+input.attr('autocomplete','off');$(this).append(input);return(input);}},textarea:{element:function(settings,original){var textarea=$('<textarea>');if(settings.rows){textarea.attr('rows',settings.rows);}else{textarea.height(settings.height);}
+if(settings.cols){textarea.attr('cols',settings.cols);}else{textarea.width(settings.width);}
+$(this).append(textarea);return(textarea);}},select:{element:function(settings,original){var select=$('<select>');$(this).append(select);return(select);},content:function(string,settings,original){if(String==string.constructor){eval('var json = '+string);for(var key in json){if(!json.hasOwnProperty(key)){continue;}
+if('selected'==key){continue;}
+var option=$('<option>').val(key).append(json[key]);$('select',this).append(option);}}
+$('select',this).children().each(function(){if($(this).val()==json['selected']||$(this).text()==original.revert){$(this).attr('selected','selected');};});}}},addInputType:function(name,input){$.editable.types[name]=input;}};})(jQuery); \ No newline at end of file
diff --git a/themes/default/views/album.html.php b/themes/default/views/album.html.php
index 8ec225cf..d9db24d9 100644
--- a/themes/default/views/album.html.php
+++ b/themes/default/views/album.html.php
@@ -1,7 +1,7 @@
<? defined("SYSPATH") or die("No direct script access."); ?>
<div id="gAlbumGridHeader">
- <h1><?= $item->title ?></h1>
- <span class="understate"><?= $item->description ?></span>
+ <h1><?= $item->title_edit ?></h1>
+ <span class="understate"><?= $item->description_edit ?></span>
<a href="#" id="gSlideshowLink" class="buttonlink">Slideshow</a>
</div>
@@ -18,7 +18,7 @@
width="<?= $child->thumbnail_width ?>"
height="<?= $child->thumbnail_height ?>" />
</a>
- <h2><?= $child->title ?></h2>
+ <h2><?= $child->title_edit ?></h2>
<ul class="gMetadata">
<li>Views: 321</li>
<? if ($child->owner): ?>
diff --git a/themes/default/views/header.html.php b/themes/default/views/header.html.php
index a5a85988..f2a72bef 100644
--- a/themes/default/views/header.html.php
+++ b/themes/default/views/header.html.php
@@ -1,7 +1,7 @@
<? defined("SYSPATH") or die("No direct script access."); ?>
<div id="gHeader">
<img id="gLogo" alt="<?= _("Logo") ?>" src="<?= $theme->url("images/logo.png") ?>" />
- <h1><?= $item->title ?></h1>
+ <h1><?= $item->title_edit ?></h1>
<div id="gLoginMenu">
<a href="#"><?= _("Register") ?></a> |
<a href="#"><?= _("Login") ?></a>
@@ -17,9 +17,9 @@
<ul id="gBreadcrumbs">
<? foreach ($parents as $parent): ?>
- <li><a href="<?= url::site("album/{$parent->id}") ?>"><?= $parent->title ?></a></li>
+ <li><a href="<?= url::site("album/{$parent->id}") ?>"><?= $parent->title_edit ?></a></li>
<? endforeach ?>
- <li class="active"><span><?= $item->title ?></span></li>
+ <li class="active"><?= $item->title_edit ?></li>
</ul>
<form id="gSearchForm">
diff --git a/themes/default/views/page.html.php b/themes/default/views/page.html.php
index 7a6c3917..29edc734 100644
--- a/themes/default/views/page.html.php
+++ b/themes/default/views/page.html.php
@@ -11,6 +11,8 @@
"lib/yui/base-min.css" ?>" media="screen,print,projection" />
<link rel="stylesheet" type="text/css" href="<?=
$theme->url("css/screen.css") ?>" media="screen,print,projection" />
+ <script src="<?= url::base() . "lib/jquery.js" ?>" type="text/javascript"></script>
+ <script src="<?= url::base() . "lib/jquery.jeditable.js" ?>" type="text/javascript"></script>
</head>
<body>
@@ -26,5 +28,6 @@
</div>
<?= $theme->display("footer.html") ?>
</div>
+ <?= $theme->in_place_edit(); ?>
</body>
</html>