diff --git a/css/jquery.ocaddnew.css b/css/jquery.ocaddnew.css
new file mode 100644
index 00000000..388bf880
--- /dev/null
+++ b/css/jquery.ocaddnew.css
@@ -0,0 +1,84 @@
+/**
+ * ownCloud - Add new jQuery plugin
+ *
+ * @author Bernhard Posselt, Thomas Tanghus
+ * @copyright 2012 Bernhard Posselt nukeawhale@gmail.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see .
+ *
+ */
+
+.oc-addnew > li > a.oc-addnew-init:before {
+ content: '+';
+ font-weight: bold;
+ font-size: 180%;
+ padding-right: 5px;
+}
+
+.oc-addnew input[type=text] {
+ width: 120px !important;
+ margin-top: 15px;
+ height: 16px !important;
+}
+
+.oc-addnew select {
+ width: 133px;
+ margin-top: 1px !important;
+ height: 30px;
+ background-color: #eee;
+}
+
+.oc-addnew input,
+.oc-addnew select {
+ margin: 0 0 5px 0;
+ display: inline-block;
+ float: left;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-right: 0;
+}
+
+.oc-addnew button {
+ margin: 5px 0;
+ display: inline-block;
+ float: left;
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+ height: 30px !important;
+}
+
+.oc-addnew .action-button {
+ width: 30px;
+ background-position: center;
+ background-repeat: no-repeat;
+}
+
+.oc-addnew .back-button {
+ border-radius: 0;
+ background-image: url('%webroot%/core/img/actions/delete.svg');
+}
+
+.oc-addnew .new-button {
+ border-radius: 0;
+ background-image: url('%webroot%/core/img/add.svg');
+ border-top-right-radius: 5px;
+ border-bottom-right-radius: 5px;
+}
+
+.oc-addnew .create-button {
+ border-radius: 0;
+ background-image: url('%appswebroot%/contacts/img/checkmark-gray.svg');
+ border-top-right-radius: 5px;
+ border-bottom-right-radius: 5px;
+}
\ No newline at end of file
diff --git a/js/jquery.ocaddnew.js b/js/jquery.ocaddnew.js
new file mode 100644
index 00000000..a154db0b
--- /dev/null
+++ b/js/jquery.ocaddnew.js
@@ -0,0 +1,135 @@
+(function($) {
+ $.widget('oc.addnew', {
+ options: {
+ width: 'auto',
+ height: 'auto',
+ closeOnEscape: true,
+ addText: 'Add'
+ },
+ _create: function() {
+ //console.log('ocaddnew._create', this);
+ var self = this;
+
+ this.originalCss = {
+ display: this.element[0].style.display,
+ width: this.element[0].style.width,
+ height: this.element[0].style.height,
+ };
+
+ this.originalTitle = this.element.attr('title') || this.element.attr('original-title');
+ //console.log('ocaddnew, originalTitle', this.originalTitle);
+ this.options.title = this.options.title || this.originalTitle;
+ //console.log('ocaddnew, title', this.options.title);
+ this.element.hide();
+
+ this.$ul = $('
').insertBefore(this.element);
+ $('').text(this.options.title).appendTo(this.$ul).wrap('');
+ this.element.addClass('oc-addnew-name').appendTo(this.$ul).wrap('');
+ //console.log('li', $li.parent());
+ //$li.appendTo(this.$ul);
+ $('').addClass('primary').text(this.options.addText).insertAfter(this.element).hide();
+ this.element.on('input', function() {
+ // Enable button when input is non-empty
+ $(this).next('button').prop('disabled', $(this).val().trim().length === 0);
+ });
+ this.$ul.on('click keydown',function(event) {
+ if(self._wrongKey(event)) {
+ return;
+ }
+ if($(event.target).is('.oc-addnew-init')) {
+ if(self.$ul.is('.open')) {
+ self.close();
+ } else {
+ self.open();
+ }
+ return false;
+ } else if($(event.target).is('button.primary')) {
+ var result = self.element.val().trim();
+ if(result.length > 0) {
+ self._trigger('ok', null, result);
+ self.element.val('');
+ }
+ return false;
+ }
+ });
+
+ $(document).on('click keydown keyup', function(event) {
+ if(event.target !== self.$ul.get(0) && self.$ul.find($(event.target)).length === 0) {
+ //console.log('outside');
+ self.close();
+ return;
+ }
+ // Escape
+ if(event.keyCode && event.keyCode === 27 && self.options.closeOnEscape) {
+ self.close();
+ return false;
+ }
+ // Enter
+ if(event.keyCode && event.keyCode === 13) {
+ event.stopImmediatePropagation();
+ if(event.type === 'keyup') {
+ event.preventDefault();
+ return false;
+ }
+ if(event.target === self.element.get(0)) {
+ self.element.next('button').trigger('click');
+ }
+ return false;
+ }
+ });
+ this._setOptions(this.options);
+ },
+ _init: function() {
+ //console.log('ocaddnew._init');
+ },
+ _setOption: function(key, value) {
+ //console.log('ocaddnew._setOption', key, value);
+ var self = this;
+ switch(key) {
+ case 'width':
+ this.$ul.css('width', value);
+ break;
+ case 'height':
+ this.$ul.css('height', value);
+ break;
+ }
+ //this._super(key, value);
+ $.Widget.prototype._setOption.apply(this, arguments );
+ },
+ _setOptions: function(options) {
+ //console.log('_setOptions', options);
+ //this._super(options);
+ $.Widget.prototype._setOptions.apply(this, arguments);
+ },
+ _wrongKey: function(event) {
+ return ((event.type === 'keydown' || event.type === 'keypress')
+ && (event.keyCode !== 32 && event.keyCode !== 13));
+ },
+ widget: function() {
+ return this.$ul;
+ },
+ close: function() {
+ //console.log('ocaddnew.close()');
+ this.$ul.removeClass('open');
+ this.$ul.find('li:not(:first-child)').hide();
+ this.$ul.find('li:first-child').show();
+ },
+ open: function() {
+ //console.log('ocaddnew.open()', this.element.parent('li'));
+ this.$ul.addClass('open');
+ this.$ul.find('li:first-child').hide();
+ this.element.show().next('button').show().parent('li').show();
+ if(this.options.addTo) {
+ }
+ },
+ destroy: function() {
+ console.log('destroy');
+ if(this.originalTitle) {
+ this.element.attr('title', this.originalTitle);
+ }
+ this.element.removeClass('oc-addnew-name')
+ .css(this.originalCss).detach().insertBefore(this.$ul);
+ this.$ul.remove();
+ }
+ });
+}(jQuery));