diff --git a/ajax/addproperty.php b/ajax/addproperty.php
index b6b5dc7c..e1a31292 100644
--- a/ajax/addproperty.php
+++ b/ajax/addproperty.php
@@ -27,14 +27,16 @@ require_once('../../../lib/base.php');
OC_JSON::checkLoggedIn();
OC_JSON::checkAppEnabled('contacts');
-$id = $_POST['id'];
-$vcard = OC_Contacts_App::getContactVCard( $id );
+$id = isset($_POST['id'])?$_POST['id']:null;
+$name = isset($_POST['name'])?$_POST['name']:null;
+$value = isset($_POST['value'])?$_POST['value']:null;
+$parameters = isset($_POST['parameters'])?$_POST['parameters']:array();
+
+$vcard = OC_Contacts_App::getContactVCard($id);
-$name = $_POST['name'];
-$value = $_POST['value'];
if(!is_array($value)){
$value = trim($value);
- if(!$value && in_array($name, array('TEL', 'EMAIL', 'ORG', 'BDAY', 'NICKNAME'))) {
+ if(!$value && in_array($name, array('TEL', 'EMAIL', 'ORG', 'BDAY', 'NICKNAME', 'NOTE'))) {
OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Cannot add empty property.'))));
exit();
}
@@ -51,7 +53,6 @@ if(!is_array($value)){
exit();
}
}
-$parameters = isset($_POST['parameters']) ? $_POST['parameters'] : array();
// Prevent setting a duplicate entry
$current = $vcard->select($name);
@@ -82,7 +83,9 @@ switch($name) {
}
case 'N':
case 'ORG':
+ case 'NOTE':
case 'NICKNAME':
+ // TODO: Escape commas and semicolons.
break;
case 'EMAIL':
$value = strtolower($value);
diff --git a/ajax/categories/add.php b/ajax/categories/add.php
new file mode 100644
index 00000000..9b6c2629
--- /dev/null
+++ b/ajax/categories/add.php
@@ -0,0 +1,39 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+require_once('../../../../lib/base.php');
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('contacts');
+
+function bailOut($msg) {
+ OC_JSON::error(array('data' => array('message' => $msg)));
+ OC_Log::write('contacts','ajax/categories/add.php: '.$msg, OC_Log::DEBUG);
+ exit();
+}
+function debug($msg) {
+ OC_Log::write('contacts','ajax/categories/add.php: '.$msg, OC_Log::DEBUG);
+}
+
+$category = isset($_GET['category'])?strip_tags($_GET['category']):null;
+
+if(is_null($category)) {
+ bailOut(OC_Contacts_App::$l10n->t('No category to add?'));
+}
+
+debug(print_r($category, true));
+
+$categories = new OC_VCategories('contacts');
+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/ajax/categories/checksumfor.php b/ajax/categories/checksumfor.php
new file mode 100644
index 00000000..ff535866
--- /dev/null
+++ b/ajax/categories/checksumfor.php
@@ -0,0 +1,28 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+require_once('../../../../lib/base.php');
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('contacts');
+
+$id = isset($_GET['id'])?$_GET['id']:null;
+if(is_null($id)) {
+ OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('No ID provided'))));
+ exit();
+}
+$vcard = OC_Contacts_App::getContactVCard( $id );
+foreach($vcard->children as $property){
+ //OC_Log::write('contacts','ajax/categories/checksumfor.php: '.$property->name, OC_Log::DEBUG);
+ if($property->name == 'CATEGORIES') {
+ $checksum = md5($property->serialize());
+ OC_JSON::success(array('data' => array('checksum'=>$checksum)));
+ exit();
+ }
+}
+OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error setting checksum.'))));
+?>
diff --git a/ajax/categories/delete.php b/ajax/categories/delete.php
new file mode 100644
index 00000000..3ba5aa16
--- /dev/null
+++ b/ajax/categories/delete.php
@@ -0,0 +1,60 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+require_once('../../../../lib/base.php');
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('contacts');
+
+foreach ($_POST as $key=>$element) {
+ debug('_POST: '.$key.'=>'.print_r($element, true));
+}
+
+function bailOut($msg) {
+ OC_JSON::error(array('data' => array('message' => $msg)));
+ OC_Log::write('contacts','ajax/categories/delete.php: '.$msg, OC_Log::DEBUG);
+ exit();
+}
+function debug($msg) {
+ OC_Log::write('contacts','ajax/categories/delete.php: '.$msg, OC_Log::DEBUG);
+}
+
+$categories = isset($_POST['categories'])?$_POST['categories']:null;
+
+if(is_null($categories)) {
+ bailOut(OC_Contacts_App::$l10n->t('No categories selected for deletion.'));
+}
+
+debug(print_r($categories, true));
+
+$addressbooks = OC_Contacts_Addressbook::all(OC_User::getUser());
+if(count($addressbooks) == 0) {
+ bailOut(OC_Contacts_App::$l10n->t('No address books found.'));
+}
+$addressbookids = array();
+foreach($addressbooks as $addressbook) {
+ $addressbookids[] = $addressbook['id'];
+}
+$contacts = OC_Contacts_VCard::all($addressbookids);
+if(count($contacts) == 0) {
+ bailOut(OC_Contacts_App::$l10n->t('No contacts found.'));
+}
+
+$cards = array();
+foreach($contacts as $contact) {
+ $cards[] = array($contact['id'], $contact['carddata']);
+}
+
+debug('Before delete: '.print_r($categories, true));
+
+$catman = new OC_VCategories('contacts');
+$catman->delete($categories, $cards);
+debug('After delete: '.print_r($catman->categories(), true));
+OC_Contacts_VCard::updateDataByID($cards);
+OC_JSON::success(array('data' => array('categories'=>$catman->categories())));
+
+?>
diff --git a/ajax/categories/edit.php b/ajax/categories/edit.php
new file mode 100644
index 00000000..8ecc3540
--- /dev/null
+++ b/ajax/categories/edit.php
@@ -0,0 +1,28 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+require_once('../../../../lib/base.php');
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('contacts');
+function bailOut($msg) {
+ OC_JSON::error(array('data' => array('message' => $msg)));
+ OC_Log::write('contacts','ajax/categories/edit.php: '.$msg, OC_Log::DEBUG);
+ exit();
+}
+function debug($msg) {
+ OC_Log::write('contacts','ajax/categories/edit.php: '.$msg, OC_Log::DEBUG);
+}
+
+$tmpl = new OC_TEMPLATE("contacts", "part.edit_categories_dialog");
+
+$categories = OC_Contacts_App::$categories->categories();
+debug(print_r($categories, true));
+$tmpl->assign('categories',$categories);
+$tmpl->printpage();
+
+?>
diff --git a/ajax/categories/list.php b/ajax/categories/list.php
new file mode 100644
index 00000000..3b41b7bf
--- /dev/null
+++ b/ajax/categories/list.php
@@ -0,0 +1,17 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+require_once('../../../../lib/base.php');
+OC_JSON::checkLoggedIn();
+OC_JSON::checkAppEnabled('contacts');
+
+$categories = OC_Contacts_App::$categories->categories();
+
+OC_JSON::success(array('data' => array('categories'=>$categories)));
+
+?>
diff --git a/ajax/contactdetails.php b/ajax/contactdetails.php
index f35fd595..03895c86 100644
--- a/ajax/contactdetails.php
+++ b/ajax/contactdetails.php
@@ -71,5 +71,5 @@ if(isset($details['PHOTO'])) {
$details['PHOTO'] = false;
}
$details['id'] = $id;
-
+OC_Contacts_App::setLastModifiedHeader($vcard);
OC_JSON::success(array('data' => $details));
diff --git a/ajax/saveproperty.php b/ajax/saveproperty.php
index db209fed..0769791e 100644
--- a/ajax/saveproperty.php
+++ b/ajax/saveproperty.php
@@ -36,7 +36,7 @@ function debug($msg) {
OC_Log::write('contacts','ajax/saveproperty.php: '.$msg, OC_Log::DEBUG);
}
foreach ($_POST as $key=>$element) {
- debug('_POST: '.$key.'=>'.$element);
+ debug('_POST: '.$key.'=>'.print_r($element, true));
}
$id = isset($_POST['id'])?$_POST['id']:null;
@@ -51,12 +51,8 @@ $checksum = isset($_POST['checksum'])?$_POST['checksum']:null;
// }
// }
-if(is_array($value)){
- $value = array_map('strip_tags', $value);
- ksort($value); // NOTE: Important, otherwise the compound value will be set in the order the fields appear in the form!
- $value = OC_VObject::escapeSemicolons($value);
-} else {
- $value = trim(strip_tags($value));
+if(!$name) {
+ bailOut(OC_Contacts_App::$l10n->t('element name is not set.'));
}
if(!$id) {
bailOut(OC_Contacts_App::$l10n->t('id is not set.'));
@@ -64,14 +60,22 @@ if(!$id) {
if(!$checksum) {
bailOut(OC_Contacts_App::$l10n->t('checksum is not set.'));
}
-if(!$name) {
- bailOut(OC_Contacts_App::$l10n->t('element name is not set.'));
+if(is_array($value)){
+ $value = array_map('strip_tags', $value);
+ ksort($value); // NOTE: Important, otherwise the compound value will be set in the order the fields appear in the form!
+ if($name == 'CATEGORIES') {
+ $value = OC_Contacts_VCard::escapeDelimiters($value, ',');
+ } else {
+ $value = OC_Contacts_VCard::escapeDelimiters($value, ';');
+ }
+} else {
+ $value = trim(strip_tags($value));
}
$vcard = OC_Contacts_App::getContactVCard( $id );
$line = OC_Contacts_App::getPropertyLineByChecksum($vcard, $checksum);
if(is_null($line)) {
- bailOut(OC_Contacts_App::$l10n->t('Information about vCard is incorrect. Please reload the page.'.$checksum.' "'.$line.'"'));
+ bailOut(OC_Contacts_App::$l10n->t('Information about vCard is incorrect. Please reload the page: ').$checksum);
}
$element = $vcard->children[$line]->name;
@@ -91,7 +95,9 @@ switch($element) {
}
case 'N':
case 'ORG':
+ case 'NOTE':
case 'NICKNAME':
+ case 'CATEGORIES':
debug('Setting string:'.$name.' '.$value);
$vcard->setString($name, $value);
break;
@@ -123,12 +129,8 @@ $checksum = md5($vcard->children[$line]->serialize());
debug('New checksum: '.$checksum);
if(!OC_Contacts_VCard::edit($id,$vcard)) {
- OC_JSON::error(array('data' => array('message' => OC_Contacts_App::$l10n->t('Error updating contact property.'))));
- OC_Log::write('contacts','ajax/setproperty.php: Error updating contact property: '.$value, OC_Log::ERROR);
+ bailOut(OC_Contacts_App::$l10n->t('Error updating contact property.'));
exit();
}
-//$adr_types = OC_Contacts_App::getTypesOfProperty('ADR');
-//$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
-
OC_JSON::success(array('data' => array( 'line' => $line, 'checksum' => $checksum, 'oldchecksum' => $_POST['checksum'] )));
diff --git a/css/contacts.css b/css/contacts.css
index b24ec438..a6f7d931 100644
--- a/css/contacts.css
+++ b/css/contacts.css
@@ -20,7 +20,8 @@
#firstrun { width: 100%; position: absolute; top: 5em; left: 0; text-align: center; font-weight:bold; font-size:1.5em; color:#777; }
#firstrun #selections { font-size:0.8em; margin: 2em auto auto auto; clear: both; }
-#card input[type="text"].contacts_property,input[type="email"].contacts_property { width: 16em; }
+#card input[type="text"].contacts_property,input[type="email"].contacts_property { width: 14em; }
+.categories { float: left; width: 16em; }
#card input[type="text"],input[type="email"],input[type="tel"],input[type="date"], select { background-color: #f8f8f8; border: 0 !important; -webkit-appearance:none !important; -moz-appearance:none !important; -webkit-box-sizing:none !important; -moz-box-sizing:none !important; box-sizing:none !important; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; float: left; }
#card input[type="text"]:hover, input[type="text"]:focus, input[type="text"]:active,input[type="email"]:hover,input[type="tel"]:hover,input[type="date"]:hover,input[type="date"],input[type="date"]:hover,input[type="date"]:active,input[type="date"]:active,input[type="date"]:active,input[type="email"]:active,input[type="tel"]:active, select:hover, select:focus, select:active { border: 0 !important; -webkit-appearance:textfield; -moz-appearance:textfield; -webkit-box-sizing:content-box; -moz-box-sizing:content-box; box-sizing:content-box; background:#fff; color:#333; border:1px solid #ddd; -moz-box-shadow:0 1px 1px #fff, 0 2px 0 #bbb inset; -webkit-box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset; box-shadow:0 1px 1px #fff, 0 1px 0 #bbb inset; -moz-border-radius:.5em; -webkit-border-radius:.5em; border-radius:.5em; outline:none; float: left; }
input[type="text"]:invalid,input[type="email"]:invalid,input[type="tel"]:invalid,input[type="date"]:invalid { background-color: #ffc0c0 !important; }
@@ -68,7 +69,7 @@ dl.form
/*background-color: yellow;*/
}
-.loading { background: url('../../../core/img/loading.gif') no-repeat center !important;}
+.loading { background: url('../../../core/img/loading.gif') no-repeat center !important; /*cursor: progress; */ cursor: wait; }
/*.add { cursor: pointer; width: 25px; height: 25px; margin: 0px; float: right; position:relative; content: "\+"; font-weight: bold; color: #666; font-size: large; bottom: 0px; right: 0px; clear: both; text-align: center; vertical-align: bottom; display: none; }*/
@@ -185,4 +186,12 @@ input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
.propertylist li > input[type="checkbox"],input[type="radio"] { float: left; clear: left; width: 20px; height: 20px; vertical-align: middle; }
.propertylist li > select { float: left; max-width: 8em; }
.typelist { float: left; max-width: 10em; } /* for multiselect */
-.addresslist { clear: both; }
\ No newline at end of file
+.addresslist { clear: both; }
+
+#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/index.php b/index.php
index 0a21ddd0..48b2b8b4 100644
--- a/index.php
+++ b/index.php
@@ -34,6 +34,7 @@ if(!is_null($id)) {
}
$property_types = OC_Contacts_App::getAddPropertyOptions();
$phone_types = OC_Contacts_App::getTypesOfProperty('TEL');
+$categories = OC_Contacts_App::$categories->categories();
$upload_max_filesize = OC_Helper::computerFileSize(ini_get('upload_max_filesize'));
$post_max_size = OC_Helper::computerFileSize(ini_get('post_max_size'));
@@ -48,6 +49,7 @@ OC_Util::addScript('contacts','contacts');
OC_Util::addScript('contacts','jquery.combobox');
OC_Util::addScript('contacts','jquery.inview');
OC_Util::addScript('contacts','jquery.Jcrop');
+OC_Util::addScript('contacts','jquery.multi-autocomplete');
OC_Util::addStyle('','jquery.multiselect');
//OC_Util::addStyle('contacts','styles');
OC_Util::addStyle('contacts','jquery.combobox');
@@ -58,7 +60,9 @@ $tmpl = new OC_Template( "contacts", "index", "user" );
$tmpl->assign('uploadMaxFilesize', $maxUploadFilesize);
$tmpl->assign('uploadMaxHumanFilesize', OC_Helper::humanFileSize($maxUploadFilesize));
$tmpl->assign('property_types',$property_types);
+$tmpl->assign('categories',OC_Contacts_App::getCategories());
$tmpl->assign('phone_types',$phone_types);
+$tmpl->assign('categories',$categories);
$tmpl->assign('addressbooks', $addressbooks);
$tmpl->assign('contacts', $contacts);
$tmpl->assign('details', $details );
diff --git a/js/contacts.js b/js/contacts.js
index 4ede2ff4..ccedf1d3 100644
--- a/js/contacts.js
+++ b/js/contacts.js
@@ -10,17 +10,115 @@ String.prototype.strip_tags = function(){
return stripped;
};
+Categories={
+ edit:function(){
+ console.log('Categories.edit');
+ $('body').append('
');
+ $('#category_dialog').load(OC.filePath('contacts', 'ajax', 'categories/edit.php'), function(response, status, xhr){
+ try {
+ var response = jQuery.parseJSON(response);
+ console.log('status: ' + status + ', response: ' + response + ', response.status:' + response.status);
+ if(response.status == 'error'){
+ OC.dialogs.alert(response.data.message, 'Error');
+ } else {
+ OC.dialogs.alert(response, 'Error');
+ }
+ } catch(e) {
+ $('#edit_categories_dialog').dialog({
+ modal: true,
+ height: 350, minHeight:200, width: 250, minWidth: 200,
+ buttons: {
+ 'Delete':function() {
+ Categories.delete();
+ },
+ 'Rescan':function() {
+ Categories.rescan();
+ }
+ },
+ close : function(event, ui) {
+ //alert('close');
+ $(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() {
+ Categories.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) {
+ Categories.add($('#category_addinput').val());
+ $('#category_addinput').val('');
+ }
+ });
+ }
+ });
+ }
+ });
+ },
+ delete:function(){
+ var categories = $('#categorylist').find('input[type="checkbox"]').serialize();
+ console.log('Categories.delete: ' + categories);
+ $.post(OC.filePath('contacts', 'ajax', 'categories/delete.php'),categories,function(jsondata){
+ if(jsondata.status == 'success'){
+ Categories._update(jsondata.data.categories);
+ } else {
+ OC.dialogs.alert(jsondata.data.message, 'Error');
+ }
+ });
+ },
+ add:function(category){
+ console.log('Categories.add ' + category);
+ $.getJSON(OC.filePath('contacts', 'ajax', 'categories/add.php'),{'category':category},function(jsondata){
+ if(jsondata.status == 'success'){
+ Categories._update(jsondata.data.categories);
+ } else {
+ OC.dialogs.alert(jsondata.data.message, 'Error');
+ }
+ });
+ return false;
+ },
+ rescan:function(){
+ console.log('Categories.rescan');
+ $.getJSON(OC.filePath('contacts', 'ajax', 'categories/rescan.php'),{},function(jsondata){
+ if(jsondata.status == 'success'){
+ Categories._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(Categories.changed != undefined) {
+ Categories.changed(categories);
+ }
+ }
+}
Contacts={
UI:{
notImplemented:function() {
- Contacts.UI.messageBox(t('contacts', 'Not implemented'), t('contacts', 'Sorry, this functionality has not been implemented yet'));
+ OC.dialogs.alert(t('contacts', 'Sorry, this functionality has not been implemented yet'), t('contacts', 'Not implemented'));
},
searchOSM:function(obj) {
var adr = Contacts.UI.propertyContainerFor(obj).find('.adr').val();
console.log('adr 1: ' + adr);
if(adr == undefined) {
- Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'Couldn\'t get a valid address.'));
+ OC.dialogs.alert(t('contacts', 'Couldn\'t get a valid address.'), t('contacts', 'Error'));
return;
}
// FIXME: I suck at regexp. /Tanghus
@@ -53,7 +151,7 @@ Contacts={
mailTo:function(obj) {
var adr = Contacts.UI.propertyContainerFor($(obj)).find('input[type="email"]').val().trim();
if(adr == '') {
- Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'Please enter an email address.'));
+ OC.dialogs.alert(t('contacts', 'Please enter an email address.'), t('contacts', 'Error'));
return;
}
window.location.href='mailto:' + adr;
@@ -116,34 +214,6 @@ Contacts={
$('#carddav_url').show();
$('#carddav_url_close').show();
},
- messageBox:function(title, msg) {
- if(msg.toLowerCase().indexOf('auth') != -1) {
- // fugly hack, I know
- alert(msg);
- }
- if($('#messagebox').dialog('isOpen') == true){
- // NOTE: Do we ever get here?
- $('#messagebox').dialog('moveToTop');
- }else{
- $('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'messagebox.php'), function(){
- $('#messagebox').dialog(
- {
- autoOpen: true,
- title: title,
- buttons: [{
- text: "Ok",
- click: function() { $(this).dialog("close"); }
- }],
- close: function(event, ui) {
- $(this).dialog('destroy').remove();
- },
- open: function(event, ui) {
- $('#messagebox_msg').html(msg);
- }
- });
- });
- };
- },
loadListHandlers:function() {
//$('.add,.delete').hide();
$('.globe,.mail,.delete,.edit').tipsy();
@@ -182,6 +252,12 @@ Contacts={
$('#bday').datepicker({
dateFormat : 'dd-mm-yy'
});
+ $('#categories_value').find('select').multiselect({
+ noneSelectedText: t('contacts', 'Select categories'),
+ header: false,
+ selectedList: 6,
+ classes: 'categories'
+ });
// Style phone types
$('#phonelist').find('select.contacts_property').multiselect({
noneSelectedText: t('contacts', 'Select type'),
@@ -223,6 +299,7 @@ Contacts={
click: function() { $(this).dialog('close'); }
}
] );
+ //$('#categories').multiple_autocomplete({source: categories});
Contacts.UI.loadListHandlers();
},
Card:{
@@ -252,12 +329,12 @@ Contacts={
if(jsondata.status == 'success'){
Contacts.UI.Card.loadContact(jsondata.data);
} else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
} else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
@@ -269,7 +346,7 @@ Contacts={
$('#rightcontent').data('id','');
$('#rightcontent').html(jsondata.data.page);
} else {
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
@@ -309,7 +386,7 @@ Contacts={
}
else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@@ -318,7 +395,7 @@ Contacts={
// TODO: Add to contacts list.
}
else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@@ -344,13 +421,13 @@ Contacts={
$('#rightcontent').html(jsondata.data.page);
}
else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
}
}
else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@@ -361,7 +438,7 @@ Contacts={
this.data = jsondata;
this.id = this.data.id;
$('#rightcontent').data('id',this.id);
- //console.log('loaded: ' + this.data.FN[0]['value']);
+ console.log('loaded: ' + this.data.FN[0]['value']);
this.populateNameFields();
this.loadCategories();
this.loadPhoto();
@@ -369,9 +446,19 @@ Contacts={
this.loadPhones();
this.loadAddresses();
this.loadSingleProperties();
+ // TODO: load NOTE ;-)
+ if(this.data.NOTE) {
+ $('#note').data('checksum', this.data.NOTE[0]['checksum']);
+ $('#note').find('textarea').val(this.data.NOTE[0]['value']);
+ $('#note').show();
+ } else {
+ $('#note').data('checksum', '');
+ $('#note').find('textarea').val('');
+ $('#note').hide();
+ }
},
loadSingleProperties:function() {
- var props = ['BDAY', 'NICKNAME', 'ORG'];
+ var props = ['BDAY', 'NICKNAME', 'ORG']; //, 'CATEGORIES'];
// Clear all elements
$('#ident .propertycontainer').each(function(){
if(props.indexOf($(this).data('element')) > -1) {
@@ -407,6 +494,12 @@ Contacts={
$('#contact_identity').find('#org_label').show();
$('#contact_identity').find('#org_value').show();
break;
+ /*case 'CATEGORIES':
+ $('#contact_identity').find('#categories').val(value);
+ $('#contact_identity').find('#categories_value').data('checksum', checksum);
+ $('#contact_identity').find('#categories_label').show();
+ $('#contact_identity').find('#categories_value').show();
+ break;*/
}
} else {
$('#contacts_propertymenu a[data-type="'+props[prop]+'"]').parent().show();
@@ -460,36 +553,84 @@ Contacts={
$('#contact_identity').find('*[data-element="FN"]').data('checksum', this.data.FN[0]['checksum']);
$('#contact_identity').show();
},
- loadCategories:function(){
+ hasCategory:function(category) {
if(this.data.CATEGORIES) {
- //
+ for(var c in this.data.CATEGORIES[0]['value']) {
+ var cat = this.data.CATEGORIES[0]['value'][c];
+ //console.log('hasCategory: ' + cat + ' === ' + category + '?');
+ if(typeof cat === 'string' && (cat.toUpperCase() === category.toUpperCase())) {
+ //console.log('Yes');
+ return true;
+ }
+ }
}
+ return false;
+ },
+ categoriesChanged:function(categories) { // Categories added/deleted.
+ console.log('categoriesChanged for ' + Contacts.UI.Card.id + ' : ' + categories);
+ var categorylist = $('#categories_value').find('select');
+ categorylist.find('option').remove();
+ for(var category in categories) {
+ console.log('categoriesChanged: ' + categories[category]);
+ var selected = Contacts.UI.Card.hasCategory(categories[category]) ? ' selected="selected"' : '';
+ var item = '';
+ $(item).appendTo(categorylist);
+ }
+ $('#categories_value').find('select').multiselect('refresh');
+ $.getJSON(OC.filePath('contacts', 'ajax', 'categories/checksumfor.php'),{'id':Contacts.UI.Card.id},function(jsondata){
+ if(jsondata.status == 'success'){
+ console.log('Setting checksum: ' + jsondata.data.checksum);
+ $('#categories_value').data('checksum', jsondata.data.checksum);
+ } else {
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
+ }
+ });
+ },
+ loadCategories:function(){ // On loading contact.
+ var categories = $('#categories_value').find('select');
+ if(this.data.CATEGORIES) {
+ $('#categories_value').data('checksum', this.data.CATEGORIES[0]['checksum']);
+ } else {
+ $('#categories_value').data('checksum', '');
+ }
+ categories.find('option').each(function(){
+ if(Contacts.UI.Card.hasCategory($(this).val())) {
+ $(this).attr('selected', 'selected');
+ } else {
+ $(this).removeAttr('selected');
+ }
+ });
+ categories.multiselect('refresh');
},
editNew:function(){ // add a new contact
this.id = ''; this.fn = ''; this.fullname = ''; this.givname = ''; this.famname = ''; this.addname = ''; this.honpre = ''; this.honsuf = '';
- $.getJSON('ajax/newcontact.php',{},function(jsondata){
+ $.getJSON(OC.filePath('contacts', 'ajax', 'newcontact.php'),{},function(jsondata){
if(jsondata.status == 'success'){
id = '';
$('#rightcontent').data('id','');
$('#rightcontent').html(jsondata.data.page);
Contacts.UI.Card.editName();
- }
- else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ } else {
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
},
savePropertyInternal:function(name, fields, oldchecksum, checksum){
// TODO: Add functionality for new fields.
- //console.log('savePropertyInternal: ' + name + ', checksum: ' + checksum);
- //console.log('savePropertyInternal: ' + this.data[name]);
+ console.log('savePropertyInternal: ' + name + ', fields: ' + fields + 'checksum: ' + checksum);
+ console.log('savePropertyInternal: ' + this.data[name]);
+ var multivalue = ['CATEGORIES'];
var params = {};
- var value = undefined;
+ var value = multivalue.indexOf(name) != -1 ? new Array() : undefined;
jQuery.each(fields, function(i, field){
//.substring(11,'parameters[TYPE][]'.indexOf(']'))
if(field.name.substring(0, 5) === 'value') {
- value = field.value;
+ if(multivalue.indexOf(name) != -1) {
+ value.push(field.value);
+ } else {
+ value = field.value;
+ }
} else if(field.name.substring(0, 10) === 'parameters') {
var p = field.name.substring(11,'parameters[TYPE][]'.indexOf(']'));
if(!(p in params)) {
@@ -509,11 +650,11 @@ Contacts={
saveProperty:function(obj){
// I couldn't get the selector to filter on 'contacts_property' so I filter by hand here :-/
if(!$(obj).hasClass('contacts_property')) {
- //console.log('Filtering out object.' + obj);
+ console.log('Filtering out object.' + obj);
return false;
}
if($(obj).hasClass('nonempty') && $(obj).val().trim() == '') {
- Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'This property has to be non-empty.'));
+ OC.dialogs.alert(t('contacts', 'This property has to be non-empty.'), t('contacts', 'Error'));
return false;
}
container = $(obj).parents('.propertycontainer').first(); // get the parent holding the metadata.
@@ -532,32 +673,38 @@ Contacts={
if(checksum != undefined && checksum != '') { // save
q = q + '&checksum=' + checksum;
console.log('Saving: ' + q);
+ $(obj).attr('disabled', 'disabled');
$.post('ajax/saveproperty.php',q,function(jsondata){
if(jsondata.status == 'success'){
container.data('checksum', jsondata.data.checksum);
Contacts.UI.Card.savePropertyInternal(name, fields, checksum, jsondata.data.checksum);
Contacts.UI.loading(container, false);
+ $(obj).removeAttr('disabled');
return true;
}
else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
Contacts.UI.loading(container, false);
+ $(obj).removeAttr('disabled');
return false;
}
},'json');
} else { // add
console.log('Adding: ' + q);
+ $(obj).attr('disabled', 'disabled');
$.post('ajax/addproperty.php',q,function(jsondata){
if(jsondata.status == 'success'){
container.data('checksum', jsondata.data.checksum);
// TODO: savePropertyInternal doesn't know about new fields
//Contacts.UI.Card.savePropertyInternal(name, fields, checksum, jsondata.data.checksum);
Contacts.UI.loading(container, false);
+ $(obj).removeAttr('disabled');
return true;
}
else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
Contacts.UI.loading(container, false);
+ $(obj).removeAttr('disabled');
return false;
}
},'json');
@@ -568,10 +715,14 @@ Contacts={
console.log('addProperty:' + type);
switch (type) {
case 'PHOTO':
- this.loadPhoto();
+ this.loadPhoto(true);
$('#file_upload_form').show();
$('#contacts_propertymenu a[data-type="'+type+'"]').parent().hide();
break;
+ case 'NOTE':
+ $('#note').show();
+ $('#contacts_propertymenu a[data-type="'+type+'"]').parent().hide();
+ break;
case 'EMAIL':
if($('#emaillist>li').length == 1) {
$('#emails').show();
@@ -596,6 +747,7 @@ Contacts={
case 'NICKNAME':
case 'ORG':
case 'BDAY':
+ case 'CATEGORIES':
$('dl dt[data-element="'+type+'"],dd[data-element="'+type+'"]').show();
$('#contacts_propertymenu a[data-type="'+type+'"]').parent().hide();
break;
@@ -619,13 +771,13 @@ Contacts={
$('#contacts_propertymenu a[data-type="'+proptype+'"]').parent().show();
Contacts.UI.loading(obj, false);
} else {
- Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', '\'deleteProperty\' called without type argument. Please report at bugs.owncloud.org'));
+ OC.dialogs.alert(t('contacts', '\'deleteProperty\' called without type argument. Please report at bugs.owncloud.org'), t('contacts', 'Error'));
Contacts.UI.loading(obj, false);
}
}
else{
Contacts.UI.loading(obj, false);
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
} else { // Property hasn't been saved so there's nothing to delete.
@@ -640,7 +792,7 @@ Contacts={
$('#contacts_propertymenu a[data-type="'+proptype+'"]').parent().show();
Contacts.UI.loading(obj, false);
} else {
- Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', '\'deleteProperty\' called without type argument. Please report at bugs.owncloud.org'));
+ OC.dialogs.alert(t('contacts', '\'deleteProperty\' called without type argument. Please report at bugs.owncloud.org'), t('contacts', 'Error'));
}
}
},
@@ -650,8 +802,9 @@ Contacts={
if($('#edit_name_dialog').dialog('isOpen') == true){
$('#edit_name_dialog').dialog('moveToTop');
}else{ // TODO: If id=='' call addcontact.php (or whatever name) instead and reload view with id.
- $('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'editname.php')+'?id='+this.id, function(){
- $('#edit_name_dialog' ).dialog({
+ $('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'editname.php')+'?id='+this.id, function(jsondata){
+ if(jsondata.status != 'error'){
+ $('#edit_name_dialog' ).dialog({
modal: (isnew && true || false),
closeOnEscape: (isnew == '' && false || true),
title: (isnew && t('contacts', 'Add contact') || t('contacts', 'Edit name')),
@@ -670,7 +823,10 @@ Contacts={
open : function(event, ui) {
// load 'N' property - maybe :-P
}*/
- });
+ });
+ } else {
+ alert(jsondata.data.message);
+ }
});
}
},
@@ -695,7 +851,14 @@ Contacts={
$('#fn_select option').remove();
//$('#fn_select').combobox('value', this.fn);
- var names = [this.fullname, this.givname + ' ' + this.famname, this.famname + ' ' + this.givname, this.famname + ', ' + this.givname];
+ var tmp = [this.fullname, this.givname + ' ' + this.famname, this.famname + ' ' + this.givname, this.famname + ', ' + this.givname];
+ var names = new Array();
+ for(var name in tmp) {
+ console.log('idx: ' + names.indexOf(tmp[name]));
+ if(names.indexOf(tmp[name]) == -1) {
+ names.push(tmp[name]);
+ }
+ }
$.each(names, function(key, value) {
$('#fn_select')
.append($('')
@@ -774,8 +937,9 @@ Contacts={
if($('#edit_address_dialog').dialog('isOpen') == true){
$('#edit_address_dialog').dialog('moveToTop');
}else{
- $('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'editaddress.php')+q, function(){
- $('#edit_address_dialog' ).dialog({
+ $('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'editaddress.php')+q, function(jsondata){
+ if(jsondata.status != 'error'){
+ $('#edit_address_dialog' ).dialog({
/*modal: true,*/
height: 'auto', width: 'auto',
buttons: {
@@ -806,7 +970,10 @@ Contacts={
open : function(event, ui) {
// load 'ADR' property - maybe :-P
}*/
- });
+ });
+ } else {
+ alert(jsondata.data.message);
+ }
});
}
},
@@ -846,7 +1013,7 @@ Contacts={
},
uploadPhoto:function(filelist) {
if(!filelist) {
- Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts','No files selected for upload.'));
+ OC.dialogs.alert(t('contacts','No files selected for upload.'), t('contacts', 'Error'));
return;
}
//var file = filelist.item(0);
@@ -855,7 +1022,7 @@ Contacts={
var form = $('#file_upload_form');
var totalSize=0;
if(file.size > $('#max_upload').val()){
- Contacts.UI.messageBox(t('Upload too large'), t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'));
+ OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts', 'Error'));
return;
} else {
target.load(function(){
@@ -864,21 +1031,21 @@ Contacts={
Contacts.UI.Card.editPhoto(response.data.id, response.data.tmp);
//alert('File: ' + file.tmp + ' ' + file.name + ' ' + file.mime);
}else{
- Contacts.UI.messageBox(t('contacts', 'Error'), response.data.message);
+ OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
}
});
form.submit();
}
},
- loadPhoto:function(){
- if(this.data.PHOTO) {
+ loadPhoto:function(force){
+ if(this.data.PHOTO||force==true) {
$.getJSON('ajax/loadphoto.php',{'id':this.id},function(jsondata){
if(jsondata.status == 'success'){
//alert(jsondata.data.page);
$('#contacts_details_photo_wrapper').html(jsondata.data.page);
}
else{
- Contacts.UI.messageBox(jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
$('#file_upload_form').show();
@@ -897,7 +1064,7 @@ Contacts={
$('#edit_photo_dialog_img').html(jsondata.data.page);
}
else{
- Contacts.UI.messageBox(jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
if($('#edit_photo_dialog').dialog('isOpen') == true){
@@ -916,7 +1083,7 @@ Contacts={
// load cropped photo.
$('#contacts_details_photo_wrapper').html(response.data.page);
}else{
- Contacts.UI.messageBox(t('contacts','Error'), response.data.message);
+ OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
}
});
$('#contacts [data-id="'+this.id+'"]').find('a').css('background','url(thumbnail.php?id='+this.id+'&refresh=1'+Math.random()+') no-repeat');
@@ -1009,13 +1176,17 @@ Contacts={
if($('#chooseaddressbook_dialog').dialog('isOpen') == true){
$('#chooseaddressbook_dialog').dialog('moveToTop');
}else{
- $('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'chooseaddressbook.php'), function(){
- $('#chooseaddressbook_dialog').dialog({
- width : 600,
- close : function(event, ui) {
- $(this).dialog('destroy').remove();
- }
- });
+ $('#dialog_holder').load(OC.filePath('contacts', 'ajax', 'chooseaddressbook.php'), function(jsondata){
+ if(jsondata.status != 'error'){
+ $('#chooseaddressbook_dialog').dialog({
+ width : 600,
+ close : function(event, ui) {
+ $(this).dialog('destroy').remove();
+ }
+ });
+ } else {
+ alert(jsondata.data.message);
+ }
});
}
},
@@ -1052,7 +1223,7 @@ Contacts={
Contacts.UI.Contacts.update();
Contacts.UI.Addressbooks.overview();
} else {
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert('Error: ' + data.message);
}
});
@@ -1067,7 +1238,7 @@ Contacts={
var description = $("#description_"+bookid).val();
if(displayname.length == 0) {
- Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'Displayname cannot be empty.'));
+ OC.dialogs.alert(t('contacts', 'Displayname cannot be empty.'), t('contacts', 'Error'));
return false;
}
var url;
@@ -1082,7 +1253,7 @@ Contacts={
$(button).closest('tr').prev().html(jsondata.page).show().next().remove();
Contacts.UI.Contacts.update();
} else {
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
}
});
},
@@ -1102,7 +1273,7 @@ Contacts={
Contacts.UI.Card.update();
}
else{
- Contacts.UI.messageBox(t('contacts', 'Error'),jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@@ -1124,6 +1295,7 @@ Contacts={
$(document).ready(function(){
Contacts.UI.loadHandlers();
+ Categories.changed = Contacts.UI.Card.categoriesChanged;
/**
* Show the Addressbook chooser
@@ -1151,7 +1323,7 @@ $(document).ready(function(){
Contacts.UI.Card.loadContact(jsondata.data);
}
else{
- Contacts.UI.messageBox(t('contacts', 'Error'), jsondata.data.message);
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
//alert(jsondata.data.message);
}
});
@@ -1192,7 +1364,8 @@ $(document).ready(function(){
// NOTE: For some reason the selector doesn't work when I select by '.contacts_property' too...
// I do the filtering in the event handler instead.
- $('input[type="text"],input[type="checkbox"],input[type="email"],input[type="tel"],input[type="date"], select').live('change', function(){
+ //$('input[type="text"],input[type="checkbox"],input[type="email"],input[type="tel"],input[type="date"], select').live('change', function(){
+ $('.contacts_property').live('change', function(){
Contacts.UI.Card.saveProperty(this);
});
@@ -1249,17 +1422,17 @@ $(document).ready(function(){
var file = files[0];
console.log('size: '+file.size);
if(file.size > $('#max_upload').val()){
- Contacts.UI.messageBox(t('contacts','Upload too large'), t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'));
+ OC.dialogs.alert(t('contacts','The file you are trying to upload exceed the maximum size for file uploads on this server.'), t('contacts','Upload too large'));
return;
}
if (file.type.indexOf("image") != 0) {
- Contacts.UI.messageBox(t('contacts','Wrong file type'), t('contacts','Only image files can be used as profile picture.'));
+ OC.dialogs.alert(t('contacts','Only image files can be used as profile picture.'), t('contacts','Wrong file type'));
return;
}
var xhr = new XMLHttpRequest();
if (!xhr.upload) {
- Contacts.UI.messageBox(t('contacts', 'Error'), t('contacts', 'Your browser doesn\'t support AJAX upload. Please click on the profile picture to select a photo to upload.'))
+ OC.dialogs.alert(t('contacts', 'Your browser doesn\'t support AJAX upload. Please click on the profile picture to select a photo to upload.'), t('contacts', 'Error'))
}
fileUpload = xhr.upload,
xhr.onreadystatechange = function() {
@@ -1269,11 +1442,11 @@ $(document).ready(function(){
if(xhr.status == 200) {
Contacts.UI.Card.editPhoto(response.data.id, response.data.tmp);
} else {
- Contacts.UI.messageBox(t('contacts', 'Error'), xhr.status + ': ' + xhr.responseText);
+ OC.dialogs.alert(xhr.status + ': ' + xhr.responseText, t('contacts', 'Error'));
}
} else {
//alert(xhr.responseText);
- Contacts.UI.messageBox(t('contacts', 'Error'), response.data.message);
+ OC.dialogs.alert(response.data.message, t('contacts', 'Error'));
}
// stop loading indicator
//$('#contacts_details_photo_progress').hide();
@@ -1301,8 +1474,19 @@ $(document).ready(function(){
xhr.send(file);
}
+ $('body').live('click',function(e){
+ if(!$(e.target).is('#contacts_propertymenu_button')) {
+ $('#contacts_propertymenu').hide();
+ }
+ });
$('#contacts_propertymenu_button').live('click',function(){
- $('#contacts_propertymenu').is(':hidden') && $('#contacts_propertymenu').slideDown() || $('#contacts_propertymenu').slideUp();
+ var menu = $('#contacts_propertymenu');
+ if(menu.is(':hidden')) {
+ menu.show();
+ menu.find('ul').focus();
+ } else {
+ menu.hide();
+ }
});
$('#contacts_propertymenu a').live('click',function(){
Contacts.UI.Card.addProperty(this);
diff --git a/js/jquery.multi-autocomplete.js b/js/jquery.multi-autocomplete.js
new file mode 100644
index 00000000..4be8d901
--- /dev/null
+++ b/js/jquery.multi-autocomplete.js
@@ -0,0 +1,47 @@
+/**
+ * Inspired by http://jqueryui.com/demos/autocomplete/#multiple
+ */
+
+(function( $ ) {
+ $.widget('ui.multiple_autocomplete', {
+ _create: function() {
+ function split( val ) {
+ return val.split( /,\s*/ );
+ }
+ function extractLast( term ) {
+ return split( term ).pop();
+ }
+ //console.log('_create: ' + this.options['id']);
+ var self = this;
+ this.element.bind( "keydown", function( event ) {
+ if ( event.keyCode === $.ui.keyCode.TAB &&
+ $( this ).data( "autocomplete" ).menu.active ) {
+ event.preventDefault();
+ }
+ })
+ .autocomplete({
+ minLength: 0,
+ source: function( request, response ) {
+ // delegate back to autocomplete, but extract the last term
+ response( $.ui.autocomplete.filter(
+ self.options.source, extractLast( request.term ) ) );
+ },
+ focus: function() {
+ // prevent value inserted on focus
+ return false;
+ },
+ select: function( event, ui ) {
+ var terms = split( this.value );
+ // remove the current input
+ terms.pop();
+ // add the selected item
+ terms.push( ui.item.value );
+ // add placeholder to get the comma-and-space at the end
+ terms.push( "" );
+ this.value = terms.join( ", " );
+ return false;
+ }
+ });
+ },
+ });
+})( jQuery );
diff --git a/lib/app.php b/lib/app.php
index e8c3087c..cc33c733 100644
--- a/lib/app.php
+++ b/lib/app.php
@@ -10,8 +10,10 @@
* This class manages our app actions
*/
OC_Contacts_App::$l10n = new OC_L10N('contacts');
+OC_Contacts_App::$categories = new OC_VCategories('contacts');
class OC_Contacts_App {
public static $l10n;
+ public static $categories;
/**
* Render templates/part.details to json output
@@ -153,6 +155,10 @@ class OC_Contacts_App {
}
}
+ public static function getCategories() {
+ return self::$categories->categories();
+ }
+
public static function setLastModifiedHeader($contact) {
$rev = $contact->getAsString('REV');
if ($rev) {
diff --git a/lib/vcard.php b/lib/vcard.php
index eade8859..a7e1817d 100644
--- a/lib/vcard.php
+++ b/lib/vcard.php
@@ -4,6 +4,7 @@
*
* @author Jakob Sack
* @copyright 2011 Jakob Sack mail@jakobsack.de
+ * @copyright 2012 Thomas Tanghus
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -233,6 +234,8 @@ class OC_Contacts_VCard{
return null;
};
+ OC_Contacts_App::$categories->loadFromVObject($card);
+
self::updateValuesFromAdd($card);
$fn = $card->getAsString('FN');
@@ -267,6 +270,29 @@ class OC_Contacts_VCard{
return self::add($id, $data, $uri);
}
+ /**
+ * @brief Mass updates an array of cards
+ * @param array $objects An array of [id, carddata].
+ */
+ public static function updateDataByID($objects){
+ $stmt = OC_DB::prepare( 'UPDATE *PREFIX*contacts_cards SET carddata = ?, lastmodified = ? WHERE id = ?' );
+ $now = new DateTime;
+ foreach($objects as $object) {
+ $vcard = OC_VObject::parse($object[1]);
+ if(!is_null($vcard)){
+ $vcard->setString('REV', $now->format(DateTime::W3C));
+ $data = $vcard->serialize();
+ try {
+ $result = $stmt->execute(array($data,time(),$object[0]));
+ //OC_Log::write('contacts','OC_Contacts_VCard::updateDataByID, id: '.$object[0].': '.$object[1],OC_Log::DEBUG);
+ } catch(Exception $e) {
+ OC_Log::write('contacts','OC_Contacts_VCard::updateDataByID:, exception: '.$e->getMessage(),OC_Log::DEBUG);
+ OC_Log::write('contacts','OC_Contacts_VCard::updateDataByID, id: '.$object[0],OC_Log::DEBUG);
+ }
+ }
+ }
+ }
+
/**
* @brief edits a card
* @param integer $id id of card
@@ -280,6 +306,8 @@ class OC_Contacts_VCard{
return false;
}
+ OC_Contacts_App::$categories->loadFromVObject($card);
+
$fn = $card->getAsString('FN');
if (empty($fn)) {
$fn = null;
@@ -338,6 +366,43 @@ class OC_Contacts_VCard{
return true;
}
+ /**
+ * @brief Escapes delimiters from an array and returns a string.
+ * @param array $value
+ * @param char $delimiter
+ * @return string
+ */
+ public static function escapeDelimiters($value, $delimiter=';') {
+ foreach($value as &$i ) {
+ $i = implode("\\$delimiter", explode($delimiter, $i));
+ }
+ return implode($delimiter, $value);
+ }
+
+
+ /**
+ * @brief Creates an array out of a multivalue property
+ * @param string $value
+ * @param char $delimiter
+ * @return array
+ */
+ public static function unescapeDelimiters($value, $delimiter=';') {
+ $array = explode($delimiter,$value);
+ for($i=0;$ivalue;
//$value = htmlspecialchars($value);
if($property->name == 'ADR' || $property->name == 'N'){
- $value = OC_VObject::unescapeSemicolons($value);
+ $value = self::unescapeDelimiters($value);
+ } elseif($property->name == 'CATEGORIES') {
+ $value = self::unescapeDelimiters($value, ',');
}
$temp = array(
'name' => $property->name,
diff --git a/templates/index.php b/templates/index.php
index e81597f2..efd797e2 100644
--- a/templates/index.php
+++ b/templates/index.php
@@ -1,5 +1,6 @@
@@ -45,7 +47,7 @@ $id = isset($_['id']) ? $_['id'] : '';
+
@@ -53,8 +55,21 @@ $id = isset($_['id']) ? $_['id'] : '';
+
+
+
+
+
+
+