From 03eb5197b62664ee89060e2d644531c9e7fe8250 Mon Sep 17 00:00:00 2001 From: Thomas Tanghus Date: Mon, 12 Mar 2012 14:07:48 +0100 Subject: [PATCH] Added category editor for apps using OC_VObjects. --- core/ajax/vcategories/add.php | 43 ++++++++ core/ajax/vcategories/delete.php | 38 +++++++ core/ajax/vcategories/edit.php | 35 +++++++ core/css/oc-vcategories.css | 7 ++ core/js/oc-vcategories.js | 115 ++++++++++++++++++++++ core/js/oc-vcategories.txt | 28 ++++++ core/templates/edit_categories_dialog.php | 16 +++ 7 files changed, 282 insertions(+) create mode 100644 core/ajax/vcategories/add.php create mode 100644 core/ajax/vcategories/delete.php create mode 100644 core/ajax/vcategories/edit.php create mode 100644 core/css/oc-vcategories.css create mode 100644 core/js/oc-vcategories.js create mode 100644 core/js/oc-vcategories.txt create mode 100644 core/templates/edit_categories_dialog.php diff --git a/core/ajax/vcategories/add.php b/core/ajax/vcategories/add.php new file mode 100644 index 0000000000..a58489228d --- /dev/null +++ b/core/ajax/vcategories/add.php @@ -0,0 +1,43 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +function bailOut($msg) { + OC_JSON::error(array('data' => array('message' => $msg))); + OC_Log::write('core','ajax/vcategories/add.php: '.$msg, OC_Log::DEBUG); + exit(); +} +function debug($msg) { + OC_Log::write('core','ajax/vcategories/add.php: '.$msg, OC_Log::DEBUG); +} + +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +$category = isset($_GET['category'])?strip_tags($_GET['category']):null; +$app = isset($_GET['app'])?$_GET['app']:null; + +if(is_null($app)) { + bailOut(OC_Contacts_App::$l10n->t('Application name not provided.')); +} + +OC_JSON::checkAppEnabled($app); + +if(is_null($category)) { + bailOut(OC_Contacts_App::$l10n->t('No category to add?')); +} + +debug(print_r($category, true)); + +$categories = new OC_VCategories($app); +if($categories->hasCategory($category)) { + bailOut(OC_Contacts_App::$l10n->t('This category already exists: '.$category)); +} else { + $categories->add($category, true); +} + +OC_JSON::success(array('data' => array('categories'=>$categories->categories()))); + +?> diff --git a/core/ajax/vcategories/delete.php b/core/ajax/vcategories/delete.php new file mode 100644 index 0000000000..602ee1d74a --- /dev/null +++ b/core/ajax/vcategories/delete.php @@ -0,0 +1,38 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +function bailOut($msg) { + OC_JSON::error(array('data' => array('message' => $msg))); + OC_Log::write('core','ajax/vcategories/delete.php: '.$msg, OC_Log::DEBUG); + exit(); +} +function debug($msg) { + OC_Log::write('core','ajax/vcategories/delete.php: '.$msg, OC_Log::DEBUG); +} + +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +$app = isset($_GET['app'])?$_GET['app']:null; +$categories = isset($_POST['categories'])?$_POST['categories']:null; +if(is_null($app)) { + bailOut(OC_Contacts_App::$l10n->t('Application name not provided.')); +} + +OC_JSON::checkAppEnabled($app); + +debug('The application "'.$app.'" uses the default file. OC_VObjects will not be updated.'); + +if(is_null($categories)) { + bailOut('No categories selected for deletion.'); +} + +$vcategories = new OC_VCategories($app); +$vcategories->delete($categories); +OC_JSON::success(array('data' => array('categories'=>$vcategories->categories()))); + +?> diff --git a/core/ajax/vcategories/edit.php b/core/ajax/vcategories/edit.php new file mode 100644 index 0000000000..252b3d3454 --- /dev/null +++ b/core/ajax/vcategories/edit.php @@ -0,0 +1,35 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +function bailOut($msg) { + OC_JSON::error(array('data' => array('message' => $msg))); + OC_Log::write('core','ajax/vcategories/edit.php: '.$msg, OC_Log::DEBUG); + exit(); +} +function debug($msg) { + OC_Log::write('core','ajax/vcategories/edit.php: '.$msg, OC_Log::DEBUG); +} + +require_once('../../../lib/base.php'); +OC_JSON::checkLoggedIn(); +$app = isset($_GET['app'])?$_GET['app']:null; + +if(is_null($app)) { + bailOut('Application name not provided.'); +} + +OC_JSON::checkAppEnabled($app); +$tmpl = new OC_TEMPLATE("core", "edit_categories_dialog"); + +$vcategories = new OC_VCategories($app); +$categories = $vcategories->categories(); +debug(print_r($categories, true)); +$tmpl->assign('categories',$categories); +$tmpl->printpage(); + +?> diff --git a/core/css/oc-vcategories.css b/core/css/oc-vcategories.css new file mode 100644 index 0000000000..68ff832bb0 --- /dev/null +++ b/core/css/oc-vcategories.css @@ -0,0 +1,7 @@ +#categoryform .scrollarea { position: absolute; left: 10px; top: 10px; right: 10px; bottom: 50px; overflow: auto; border:1px solid #ddd; background: #f8f8f8; } +#categoryform .bottombuttons { position: absolute; bottom: 10px;} +#categoryform .bottombuttons * { float: left;} +/*#categorylist { border:1px solid #ddd;}*/ +#categorylist li { background:#f8f8f8; padding:.3em .8em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; -webkit-transition:background-color 500ms; -moz-transition:background-color 500ms; -o-transition:background-color 500ms; transition:background-color 500ms; } +#categorylist li:hover, li:active { background:#eee; } +#category_addinput { width: 10em; } diff --git a/core/js/oc-vcategories.js b/core/js/oc-vcategories.js new file mode 100644 index 0000000000..a6dcccf88e --- /dev/null +++ b/core/js/oc-vcategories.js @@ -0,0 +1,115 @@ +OCCategories={ + edit:function(){ + console.log('OCCategories.edit'); + if(OCCategories.app == undefined) { + OC.dialogs.alert('OCCategories.app is not set!'); + return; + } + $('body').append('
'); + $('#category_dialog').load(OC.filePath('core', 'ajax', 'vcategories/edit.php')+'?app='+OCCategories.app, function(response){ + try { + var jsondata = jQuery.parseJSON(response); + if(response.status == 'error'){ + OC.dialogs.alert(response.data.message, 'Error'); + return; + } + } catch(e) { + $('#edit_categories_dialog').dialog({ + modal: true, + height: 350, minHeight:200, width: 250, minWidth: 200, + buttons: { + 'Delete':function() { + OCCategories.delete(); + }, + 'Rescan':function() { + OCCategories.rescan(); + } + }, + close : function(event, ui) { + $(this).dialog('destroy').remove(); + $('#category_dialog').remove(); + }, + open : function(event, ui) { + $('#category_addinput').live('input',function(){ + if($(this).val().length > 0) { + $('#category_addbutton').removeAttr('disabled'); + } + }); + $('#categoryform').submit(function() { + OCCategories.add($('#category_addinput').val()); + $('#category_addinput').val(''); + $('#category_addbutton').attr('disabled', 'disabled'); + return false; + }); + $('#category_addbutton').live('click',function(e){ + e.preventDefault(); + if($('#category_addinput').val().length > 0) { + OCCategories.add($('#category_addinput').val()); + $('#category_addinput').val(''); + } + }); + } + }); + } + }); + }, + delete:function(){ + var categories = $('#categorylist').find('input[type="checkbox"]').serialize(); + categories += '&app=' + OCCategories.app; + console.log('OCCategories.delete: ' + categories); + $.post(OC.filePath(OCCategories.app, 'ajax', 'categories/delete.php'),categories,function(jsondata, status, xhr){ + if (status == 'error' && xhr.status == 404) { + $.post(OC.filePath('core', 'ajax', 'vcategories/delete.php'),categories,function(jsondata, status, xhr){ + if(jsondata.status == 'success'){ + OCCategories._update(jsondata.data.categories); + } else { + OC.dialogs.alert(jsondata.data.message, 'Error'); + } + }); + return; + } + if(jsondata.status == 'success'){ + OCCategories._update(jsondata.data.categories); + } else { + OC.dialogs.alert(jsondata.data.message, 'Error'); + } + }); + }, + add:function(category){ + console.log('OCCategories.add ' + category); + $.getJSON(OC.filePath('core', 'ajax', 'vcategories/add.php'),{'category':category, 'app':OCCategories.app},function(jsondata){ + if(jsondata.status == 'success'){ + OCCategories._update(jsondata.data.categories); + } else { + OC.dialogs.alert(jsondata.data.message, 'Error'); + } + }); + return false; + }, + rescan:function(){ + console.log('Categories.rescan'); + $.getJSON(OC.filePath(OCCategories.app, 'ajax', 'categories/rescan.php'),{},function(jsondata, status, xhr){ + if (status == 'error' && xhr.status == 404) { + OC.dialogs.alert('The required file ' + OC.filePath(Categories.app, 'ajax', 'categories/rescan.php') + ' is not installed!', 'Error'); + return; + } + if(jsondata.status == 'success'){ + OCCategories._update(jsondata.data.categories); + } else { + OC.dialogs.alert(jsondata.data.message, 'Error'); + } + }); + }, + _update:function(categories){ + var categorylist = $('#categorylist'); + categorylist.find('li').remove(); + for(var category in categories) { + var item = '
  • ' + categories[category] + '
  • '; + $(item).appendTo(categorylist); + } + if(OCCategories.changed != undefined) { + OCCategories.changed(categories); + } + } +} + diff --git a/core/js/oc-vcategories.txt b/core/js/oc-vcategories.txt new file mode 100644 index 0000000000..76d4245f5e --- /dev/null +++ b/core/js/oc-vcategories.txt @@ -0,0 +1,28 @@ +Using OCCategories + +This 'class' is meant for any apps that uses OC_VObjects with the CATEGORIES field e.g. +Contacts and Calendar. It provides an editor UI for adding/deleting and rescanning categories +and basic ajax functions for adding and deleting. +To use the mass updating of OC_VObjects that /lib/vcategories.php provides, the app must implement +its own ajax functions in /apps/$(APP)/ajax/categories/rescan.php and /apps/$(APP)/ajax/categories/delete.php +See examples in /apps/contacts/ajax/categories and the inline docs in /lib/vcategories.php. + +In your app make sure you load the script and stylesheet: + +OC_Util::addScript('','oc-vcategories'); +OC_Util::addStyle('','oc-vcategories'); + +Set the app specific values in your javascript file. This is what I've used for the Contacts app: + + OCCategories.app = 'contacts'; + OCCategories.changed = Contacts.UI.Card.categoriesChanged; + +If OCCategories.changed point is set that function will be called each time the categories have been changed +in the editor (add/delete/rescan) to allow the app to update the UI accordingly. The only argument to the function +is an array of the updated categories e.g.: + +OCCategories.changed = function(categories) { + for(var category in categories) { + console.log(categories[category]); + } +} \ No newline at end of file diff --git a/core/templates/edit_categories_dialog.php b/core/templates/edit_categories_dialog.php new file mode 100644 index 0000000000..8997fa586b --- /dev/null +++ b/core/templates/edit_categories_dialog.php @@ -0,0 +1,16 @@ + +
    + +
    +
    +
      + +
    • + +
    +
    +
    +
    +