summaryrefslogtreecommitdiffstats
path: root/core/js
diff options
context:
space:
mode:
authorThomas Tanghus <thomas@tanghus.net>2013-10-11 04:17:59 -0700
committerThomas Tanghus <thomas@tanghus.net>2013-10-11 04:17:59 -0700
commit31714f8871eb21b9c6097e0c4edcbe97fb8a35a3 (patch)
tree82bb1b1c2d26fab819b69444d28f2f0882669dca /core/js
parent4336d42ab095c304d0a46bb30c2d0203e606597e (diff)
parent9c230f8c85cf80efb10093e66e1197c200c185c1 (diff)
downloadnextcloud-server-31714f8871eb21b9c6097e0c4edcbe97fb8a35a3.tar.gz
nextcloud-server-31714f8871eb21b9c6097e0c4edcbe97fb8a35a3.zip
Merge pull request #5133 from owncloud/js_vcategories_to_tags
Js vcategories to tags
Diffstat (limited to 'core/js')
-rw-r--r--core/js/oc-vcategories.js216
-rw-r--r--core/js/oc-vcategories.txt33
-rw-r--r--core/js/tags.js353
3 files changed, 353 insertions, 249 deletions
diff --git a/core/js/oc-vcategories.js b/core/js/oc-vcategories.js
deleted file mode 100644
index c297a24680d..00000000000
--- a/core/js/oc-vcategories.js
+++ /dev/null
@@ -1,216 +0,0 @@
-var OCCategories= {
- category_favorites:'_$!<Favorite>!$_',
- edit:function(type, cb) {
- if(!type && !this.type) {
- throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
- }
- type = type ? type : this.type;
- $('body').append('<div id="category_dialog"></div>');
- $('#category_dialog').load(
- OC.filePath('core', 'ajax', 'vcategories/edit.php') + '?type=' + type, function(response) {
- try {
- var jsondata = jQuery.parseJSON(response);
- if(response.status == 'error') {
- OC.dialogs.alert(response.data.message, t('core', 'Error'));
- return;
- }
- } catch(e) {
- var setEnabled = function(d, enable) {
- if(enable) {
- d.css('cursor', 'default').find('input,button:not(#category_addbutton)')
- .prop('disabled', false).css('cursor', 'default');
- } else {
- d.css('cursor', 'wait').find('input,button:not(#category_addbutton)')
- .prop('disabled', true).css('cursor', 'wait');
- }
- };
- var dlg = $('#edit_categories_dialog').dialog({
- modal: true,
- height: 350, minHeight:200, width: 250, minWidth: 200,
- buttons: {
- 'Close': function() {
- $(this).dialog('close');
- },
- 'Delete':function() {
- var categories = $('#categorylist').find('input:checkbox').serialize();
- setEnabled(dlg, false);
- OCCategories.doDelete(categories, function() {
- setEnabled(dlg, true);
- });
- },
- 'Rescan':function() {
- setEnabled(dlg, false);
- OCCategories.rescan(function() {
- setEnabled(dlg, true);
- });
- }
- },
- close : function(event, ui) {
- $(this).dialog('destroy').remove();
- $('#category_dialog').remove();
- },
- open : function(event, ui) {
- $('#category_addinput').on('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').on('click',function(e) {
- e.preventDefault();
- if($('#category_addinput').val().length > 0) {
- OCCategories.add($('#category_addinput').val());
- $('#category_addinput').val('');
- }
- });
- }
- });
- }
- });
- },
- _processDeleteResult:function(jsondata) {
- if(jsondata.status == 'success') {
- OCCategories._update(jsondata.data.categories);
- } else {
- OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
- }
- },
- favorites:function(type, cb) {
- if(!type && !this.type) {
- throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
- }
- type = type ? type : this.type;
- $.getJSON(OC.filePath('core', 'ajax', 'categories/favorites.php'), {type: type},function(jsondata) {
- if(typeof cb == 'function') {
- cb(jsondata);
- } else {
- if(jsondata.status === 'success') {
- OCCategories._update(jsondata.data.categories);
- } else {
- OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
- }
- }
- });
- },
- addToFavorites:function(id, type, cb) {
- if(!type && !this.type) {
- throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
- }
- type = type ? type : this.type;
- $.post(OC.filePath('core', 'ajax', 'vcategories/addToFavorites.php'), {id:id, type:type}, function(jsondata) {
- if(typeof cb == 'function') {
- cb(jsondata);
- } else {
- if(jsondata.status !== 'success') {
- OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
- }
- }
- });
- },
- removeFromFavorites:function(id, type, cb) {
- if(!type && !this.type) {
- throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
- }
- type = type ? type : this.type;
- $.post(OC.filePath('core', 'ajax', 'vcategories/removeFromFavorites.php'), {id:id, type:type}, function(jsondata) {
- if(typeof cb == 'function') {
- cb(jsondata);
- } else {
- if(jsondata.status !== 'success') {
- OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
- }
- }
- });
- },
- doDelete:function(categories, type, cb) {
- if(!type && !this.type) {
- throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
- }
- type = type ? type : this.type;
- if(categories == '' || categories == undefined) {
- OC.dialogs.alert(t('core', 'No categories selected for deletion.'), t('core', 'Error'));
- return false;
- }
- var self = this;
- var q = categories + '&type=' + type;
- if(this.app) {
- q += '&app=' + this.app;
- $.post(OC.filePath(this.app, 'ajax', 'categories/delete.php'), q, function(jsondata) {
- if(typeof cb == 'function') {
- cb(jsondata);
- } else {
- self._processDeleteResult(jsondata);
- }
- });
- } else {
- $.post(OC.filePath('core', 'ajax', 'vcategories/delete.php'), q, function(jsondata) {
- if(typeof cb == 'function') {
- cb(jsondata);
- } else {
- self._processDeleteResult(jsondata);
- }
- });
- }
- },
- add:function(category, type, cb) {
- if(!type && !this.type) {
- throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
- }
- type = type ? type : this.type;
- $.post(OC.filePath('core', 'ajax', 'vcategories/add.php'),{'category':category, 'type':type},function(jsondata) {
- if(typeof cb == 'function') {
- cb(jsondata);
- } else {
- if(jsondata.status === 'success') {
- OCCategories._update(jsondata.data.categories);
- } else {
- OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
- }
- }
- });
- },
- rescan:function(app, cb) {
- if(!app && !this.app) {
- throw { name: 'MissingParameter', message: t('core', 'The app name is not specified.') };
- }
- app = app ? app : this.app;
- $.getJSON(OC.filePath(app, 'ajax', 'categories/rescan.php'),function(jsondata, status, xhr) {
- if(typeof cb == 'function') {
- cb(jsondata);
- } else {
- if(jsondata.status === 'success') {
- OCCategories._update(jsondata.data.categories);
- } else {
- OC.dialogs.alert(jsondata.data.message, t('core', 'Error'));
- }
- }
- }).error(function(xhr){
- if (xhr.status == 404) {
- var errormessage = t('core', 'The required file {file} is not installed!',
- {file: OC.filePath(app, 'ajax', 'categories/rescan.php')}, t('core', 'Error'));
- if(typeof cb == 'function') {
- cb({status:'error', data:{message:errormessage}});
- } else {
- OC.dialogs.alert(errormessage, t('core', 'Error'));
- }
- }
- });
- },
- _update:function(categories) {
- var categorylist = $('#categorylist');
- categorylist.find('li').remove();
- for(var category in categories) {
- var item = '<li><input type="checkbox" name="categories" value="' + categories[category] + '" />' + categories[category] + '</li>';
- $(item).appendTo(categorylist);
- }
- if(typeof OCCategories.changed === 'function') {
- OCCategories.changed(categories);
- }
- }
-}
-
diff --git a/core/js/oc-vcategories.txt b/core/js/oc-vcategories.txt
deleted file mode 100644
index 31216f80bd3..00000000000
--- a/core/js/oc-vcategories.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-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 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]);
- }
-}
-
-To show the categories editor call:
-
- OCCategories.edit()
-
diff --git a/core/js/tags.js b/core/js/tags.js
new file mode 100644
index 00000000000..16dd3d4bf97
--- /dev/null
+++ b/core/js/tags.js
@@ -0,0 +1,353 @@
+OC.Tags= {
+ edit:function(type, cb) {
+ if(!type && !this.type) {
+ throw { name: 'MissingParameter', message: t('core', 'The object type is not specified.') };
+ }
+ type = type ? type : this.type;
+ var self = this;
+ $.when(this._getTemplate()).then(function($tmpl) {
+ if(self.$dialog) {
+ self.$dialog.ocdialog('close');
+ }
+ self.$dialog = $tmpl.octemplate({
+ addText: t('core', 'Enter new')
+ });
+ $('body').append(self.$dialog);
+
+ self.$dialog.ready(function() {
+ self.$taglist = self.$dialog.find('.taglist');
+ self.$taginput = self.$dialog.find('.addinput');
+ self.$taglist.on('change', 'input:checkbox', function(event) {
+ self._handleChanges(self.$taglist, self.$taginput);
+ });
+ self.$taginput.on('input', function(event) {
+ self._handleChanges(self.$taglist, self.$taginput);
+ });
+ self.deleteButton = {
+ text: t('core', 'Delete'),
+ click: function() {self._deleteTags(self, type, self._selectedIds())},
+ };
+ self.addButton = {
+ text: t('core', 'Add'),
+ click: function() {self._addTag(self, type, self.$taginput.val())},
+ };
+
+ self._fillTagList(type, self.$taglist);
+ });
+
+ self.$dialog.ocdialog({
+ title: t('core', 'Edit tags'),
+ closeOnEscape: true,
+ width: 250,
+ height: 'auto',
+ modal: true,
+ //buttons: buttonlist,
+ close: function(event, ui) {
+ try {
+ $(this).ocdialog('destroy').remove();
+ } catch(e) {console.warn(e);}
+ self.$dialog = null;
+ }
+ });
+ })
+ .fail(function(status, error) {
+ // If the method is called while navigating away
+ // from the page, it is probably not needed ;)
+ if(status !== 0) {
+ alert(t('core', 'Error loading dialog template: {error}', {error: error}));
+ }
+ });
+ },
+ /**
+ * @param string type
+ * @return jQuery.Promise which resolves with an array of ids
+ */
+ getIdsForTag:function(type, tag) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_ids_for_tag', {type: type});
+ $.getJSON(url, {tag: tag}, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response.ids);
+ } else {
+ defer.reject(response);
+ }
+ });
+ return defer.promise();
+ },
+ /**
+ * @param string type
+ * @return jQuery.Promise which resolves with an array of ids
+ */
+ getFavorites:function(type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_favorites', {type: type});
+ $.getJSON(url, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response.ids);
+ } else {
+ defer.reject(response);
+ }
+ });
+ return defer.promise();
+ },
+ /**
+ * @param string type
+ * @return jQuery.Promise which resolves with an array of id/name objects
+ */
+ getTags:function(type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_tags', {type: type});
+ $.getJSON(url, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response.tags);
+ } else {
+ defer.reject(response);
+ }
+ });
+ return defer.promise();
+ },
+ /**
+ * @param int id
+ * @param string type
+ * @return jQuery.Promise
+ */
+ tagAs:function(id, tag, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_tag', {type: type, id: id});
+ $.post(url, {tag: tag}, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response);
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param int id
+ * @param string type
+ * @return jQuery.Promise
+ */
+ unTag:function(id, tag, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_untag', {type: type, id: id});
+ $.post(url, {tag: tag}, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response);
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param int id
+ * @param string type
+ * @return jQuery.Promise
+ */
+ addToFavorites:function(id, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_favorite', {type: type, id: id});
+ $.post(url, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response);
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param int id
+ * @param string type
+ * @return jQuery.Promise
+ */
+ removeFromFavorites:function(id, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_unfavorite', {type: type, id: id});
+ $.post(url, function(response) {
+ if(response.status === 'success') {
+ defer.resolve();
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param string tag
+ * @param string type
+ * @return jQuery.Promise which resolves with an object with the name and the new id
+ */
+ addTag:function(tag, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_add', {type: type});
+ $.post(url,{tag:tag}, function(response) {
+ if(typeof cb == 'function') {
+ cb(response);
+ }
+ if(response.status === 'success') {
+ defer.resolve({id:response.id, name: tag});
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ /**
+ * @param array tags
+ * @param string type
+ * @return jQuery.Promise
+ */
+ deleteTags:function(tags, type) {
+ if(!type && !this.type) {
+ throw new Error('The object type is not specified.');
+ }
+ type = type ? type : this.type;
+ var defer = $.Deferred(),
+ self = this,
+ url = OC.Router.generate('core_tags_delete', {type: type});
+ if(!tags || !tags.length) {
+ throw new Error(t('core', 'No tags selected for deletion.'));
+ }
+ var self = this;
+ $.post(url, {tags:tags}, function(response) {
+ if(response.status === 'success') {
+ defer.resolve(response.tags);
+ } else {
+ defer.reject(response);
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ return defer.promise();
+ },
+ _update:function(tags, type) {
+ if(!this.$dialog) {
+ return;
+ }
+ var $taglist = this.$dialog.find('.taglist'),
+ self = this;
+ $taglist.empty();
+ $.each(tags, function(idx, tag) {
+ var $item = self.$listTmpl.octemplate({id: tag.id, name: tag.name});
+ $item.appendTo($taglist);
+ });
+ $(this).trigger('change', {type: type, tags: tags});
+ if(typeof this.changed === 'function') {
+ this.changed(tags);
+ }
+ },
+ _getTemplate: function() {
+ var defer = $.Deferred();
+ if(!this.$template) {
+ var self = this;
+ $.get(OC.filePath('core', 'templates', 'tags.html'), function(tmpl) {
+ self.$template = $(tmpl);
+ self.$listTmpl = self.$template.find('.taglist li:first-child').detach();
+ defer.resolve(self.$template);
+ })
+ .fail(function(jqXHR, textStatus, errorThrown) {
+ defer.reject(jqXHR.status, errorThrown);
+ });
+ } else {
+ defer.resolve(this.$template);
+ }
+ return defer.promise();
+ },
+ _fillTagList: function(type) {
+ var self = this;
+ $.when(this.getTags(type))
+ .then(function(tags) {
+ self._update(tags, type);
+ })
+ .fail(function(response) {
+ console.warn(response);
+ });
+ },
+ _selectedIds: function() {
+ return $.map(this.$taglist.find('input:checked'), function(b) {return $(b).val();});
+ },
+ _handleChanges: function($list, $input) {
+ var ids = this._selectedIds();
+ var buttons = [];
+ if($input.val().length) {
+ buttons.push(this.addButton);
+ }
+ if(ids.length) {
+ buttons.push(this.deleteButton);
+ }
+ this.$dialog.ocdialog('option', 'buttons', buttons);
+ },
+ _deleteTags: function(self, type, ids) {
+ $.when(self.deleteTags(ids, type))
+ .then(function() {
+ self._fillTagList(type);
+ self.$dialog.ocdialog('option', 'buttons', []);
+ })
+ .fail(function(response) {
+ console.warn(response);
+ });
+ },
+ _addTag: function(self, type, tag) {
+ $.when(self.addTag(tag, type))
+ .then(function(tag) {
+ self._fillTagList(type);
+ self.$taginput.val('').trigger('input');
+ })
+ .fail(function(response) {
+ console.warn(response);
+ });
+ }
+}
+