/* CardDavMATE - the open source CardDAV Web Client Copyright (C) 2011-2015 Jan Mate Andrej Lezo Matej Mihalik This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ // reorder countries according to localization (returns array becaouse object are unsorted according to ECMA) function sortCountries(obj) { var arr=[]; for(var prop in obj) if(obj.hasOwnProperty(prop)) arr.push({'key': prop, 'value': obj[prop], 'translated_value': localization[globalInterfaceLanguage]['txtAddressCountry'+prop.toUpperCase()]}); return arr.sort(function(a, b){return a.translated_value.customCompare(b.translated_value, globalSortAlphabet, 1, false)}); } function loadAdditionalCardDAVCollections() { if(globalSettingsSaving!='') return false; globalSettingsSaving='addressbook'; var inSettings = $.extend({},globalSettings); var rex = new RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@(.*)'); var key='loadedaddressbookcollections'; inSettings.loadedaddressbookcollections = {value : new Array(), locked: globalSettings[key].locked}; $('#ResourceCardDAVList').find('.unloadCheck').each(function(cin,cel) { if($(cel).prop('checked')) { var uidParts=$(cel).attr('data-id').match(rex); inSettings.loadedaddressbookcollections.value.splice(inSettings.loadedaddressbookcollections.value.length , 0, uidParts[1]+uidParts[3]); } }); if($(inSettings[key]).not(globalSettings[key].value).length > 0 || $(globalSettings[key].value).not(inSettings[key]).length > 0) { $('#AddressbookOverlay').removeClass('loader_hidden'); $('#ResourceCardDAVList').find('input[type="checkbox"]').prop('disabled',true); var setC=0; for(var i=0;i'); headerClickElm.change(function(){ loadResourceChBoxClick(this, '#ResourceCardDAVList', resHeader, resItem, '.resourceCardDAV_item'); }); $(this).addClass('load_mode').append(headerClickElm); }); // carddav_item display resList.find('.resourceCardDAV').each(function(){ if(typeof $(this).attr('data-id') != 'undefined') { var newInputElm = $(''); newInputElm.change(function(){ loadCollectionChBoxClick(this, '#ResourceCardDAVList', resHeader, resItem, '.resourceCardDAV_item'); }); $(this).siblings('.contact_group').addBack().addClass('load_mode'); $(this).append(newInputElm); if($(this).parent().css('display')=='none') $(this).addClass('unloaded'); else newInputElm.prop('checked',true); newInputElm.trigger('change'); } }); $('#showUnloadedAddressbooks').css('display','none'); $('.resourcesCardDAV_h').text(localization[globalInterfaceLanguage].txtEnabledAddressbooks); var origH = resList.find('.resourceCardDAV_header.unloaded').eq(0).css('height'); var origC = resList.find('.resourceCardDAV.unloaded').parent().eq(0).css('height'); resList.find('.resourceCardDAV_header.unloaded').css({'height':0,'display':''}).animate({height:origH},300); resList.find('.resourceCardDAV.unloaded').parent().css({'height':0,'display':''}).animate({height:origC},300); resList.animate({'top':49},300); } function cancelUnloadedCardDAVCollections() { $('#ResourceCardDAVList').children('.resourceCardDAV_item').children('.resourceCardDAV ').each(function(){ var uidParts=$(this).attr('data-id').match(RegExp('^(https?://)([^@/]+(?:@[^@/]+)?)@(.*)')); var checkHref=uidParts[1]+uidParts[3]; var isLoaded=false; if(typeof globalCrossServerSettingsURL!='undefined'&&globalCrossServerSettingsURL!=null&globalCrossServerSettingsURL) { var uidParts=$(this).attr('data-id').match(RegExp('/([^/]+/[^/]+/)$')); var tmpParts = uidParts[1].match('^(.*/)([^/]+)/$'); var checkHref=decodeURIComponent(tmpParts[1])+tmpParts[2]+'/'; var found=false; for(var l=0;l0) $('#ResourceCardDAVList').find('.resourceCardDAV[data-id="'+inputResource+globalSettings.addressbookselected.value.substring(globalSettings.addressbookselected.value.lastIndexOf('/')+1,globalSettings.addressbookselected.value.length)+'"]:visible').addClass('resourceCardDAV_selected'); } } else if (typeof globalSettings.addressbookselected.value=='object' && inputResource.match(globalSettings.addressbookselected.value)!=null) { if($('#ResourceCardDAVList').find('.resourceCardDAV_selected:visible').length == 0) $('#ResourceCardDAVList').find('.resourceCardDAV[data-id="'+inputResource+'"]:visible').addClass('resourceCardDAV_selected'); } } } if($('#ResourceCardDAVList').find('.resourceCardDAV_selected:visible').length==0) for(var i=0; i0) $('#ResourceCardDAVList').find('[data-id="'+inputResource+globalAddressbookSelected.substring(globalAddressbookSelected.lastIndexOf('/')+1,globalAddressbookSelected.length)+'"]:visible').addClass('resourceCardDAV_selected'); } } else if (typeof globalAddressbookSelected=='object' && inputResource.match(globalAddressbookSelected)!=null) { if($('#ResourceCardDAVList').find('.resourceCardDAV_selected:visible').length == 0) $('#ResourceCardDAVList').find('[data-id="'+inputResource+'"]:visible').addClass('resourceCardDAV_selected'); } else if($('#ResourceCardDAVList').find('.resourceCardDAV_selected:visible').length == 0) { globalSettings.addressbookselected.value=par[par.length-3]+'/'+par[par.length-2]+'/'; $('#ResourceCardDAVList').find('[data-id="'+inputResource+'"]:visible').addClass('resourceCardDAV_selected'); } } } if($('#ResourceCardDAVList').find('.resourceCardDAV_selected:visible').length == 0 && $('#ResourceCardDAVList').find('.resourceCardDAV[data-id]:visible').length > 0) { var ui_d = $('#ResourceCardDAVList').find('.resourceCardDAV[data-id]:visible').eq(0).attr('data-id'); var part_u = ui_d.split('/'); globalSettings.addressbookselected.value=part_u[part_u.length-3]+'/'+part_u[part_u.length-2]+'/'; $('#ResourceCardDAVList').find('.resourceCardDAV[data-id]:visible').eq(0).addClass('resourceCardDAV_selected'); } var selColl=globalResourceCardDAVList.getCollectionByUID($('#ResourceCardDAVList').find('.resourceCardDAV[data-id].resourceCardDAV_selected').attr('data-id')); if(selColl!=null) { selColl.filterUID=selColl.uid; if(selColl.permissions.read_only==true) globalRefAddContact.addClass('element_no_display'); else globalRefAddContact.removeClass('element_no_display'); globalRefAddContact.attr('data-url', selColl.uid.replace(RegExp('[^/]+$'),'')); globalRefAddContact.attr('data-filter-url',selColl.filterUID); // Set the current addressbook filter uid globalRefAddContact.attr('data-account-uid',selColl.accountUID); globalRefAddContact.attr('data-color',selColl.color); // Make the selected collection active if(!globalCardDAVInitLoad) { if(typeof(globalContactsABChange)=='function') globalContactsABChange(selColl.uid); $('#ResourceCardDAVList').find('.resourceCardDAV_item').find('.resourceCardDAV_selected').removeClass('resourceCardDAV_selected'); $('#ResourceCardDAVList').find('[data-id='+jqueryEscapeSelector(selColl.uid)+']').addClass('resourceCardDAV_selected'); if(selColl.filterUID[selColl.filterUID.length-1]!='/') $('#ResourceCardDAVList').find('[data-id='+jqueryEscapeSelector(selColl.filterUID)+']').addClass('resourceCardDAV_selected'); } } } function CardDAVUpdateMainLoader(inputCollection) { if(!globalCardDAVInitLoad) { if(globalSettingsSaving=='addressbook') { globalLoadedCollectionsCount++; $('#AddressbookOverlay').children('.loaderInfo').text(localization[globalInterfaceLanguage].loadingAddressbooks.replace('%act%', globalLoadedCollectionsCount).replace('%total%', globalLoadedCollectionsNumber)); if(globalSettingsSaving!='' && globalLoadedCollectionsCount==globalLoadedCollectionsNumber) setTimeout(function(){hideUnloadedCardDAVCollectionsCallBack();if(isAvaible('Settings'))hideSettingsOverlay();},300); } selectActiveAddressbook(); for(var adr in globalAddressbookList.vcard_groups) { if(globalAddressbookList.vcard_groups[adr].length>0) { extendDestSelect(); if(typeof $('#vCardEditor').attr('data-vcard-uid')=='undefined') $('#vCardEditor').find('[data-attr-name="_DEST_"]').find('optiotn[data-type$="'+$('#ResourceCardDAVList').find('.resourceCardDAV_selected').find(':input[data-id]').attr('data-id')+'"]').prop('selected',true) } } return false; } if(inputCollection.makeLoaded) { globalAddressbookNumberCount++; $('#MainLoaderInner').html(localization[globalInterfaceLanguage].loadingAddressbooks.replace('%act%', (globalAddressbookNumberCount)).replace('%total%', globalAddressbookNumber)); } inputCollection.isLoaded=true; $('#ResourceCardDAVList [data-id="'+inputCollection.uid+'"]').removeClass('r_operate'); var unloadedCount=0; for(var i=0; i0) $('#ResourceCardDAVList input[data-id$="'+checkHref2+'"]').trigger('click'); } else { var uidPart=globalSettings.activeaddressbookcollections.value[i].match(RegExp('^(https?://)(.*)', 'i'))[1]; var uidPart2=globalSettings.activeaddressbookcollections.value[i].match(RegExp('^(https?://)(.*)', 'i'))[2]; var uidPart3=getAccount(inputCollection.accountUID).userAuth.userName; var uid = uidPart+uidPart3+'@'+uidPart2; if($('#ResourceCardDAVList .resourceCardDAV input[data-id="'+uid+'"]:visible').length>0) $('#ResourceCardDAVList .resourceCardDAV input[data-id="'+uid+'"]').trigger('click'); } } if(globalSettings.activeaddressbookcollections.value.length>0 && $('#ResourceCardDAVList .resourceCardDAV input:checked').length==0) globalDefaultAddressbookCollectionActiveAll=true; } if(globalDefaultAddressbookCollectionActiveAll) for(var i=0;i0) $('#ResourceCardDAVList input[data-id="'+globalResourceCardDAVList.collections[i].uid+'"]').trigger('click'); selectActiveAddressbook(); globalRefAddContact.prop('disabled', false); loadNextApplication(true); } } function applyAddrSettings(abContactRef, remValues) { var addrVals = new Array(); if(typeof remValues!= 'undefined') { abContactRef.find('[data-type="\\%address"]').find('[data-type="country_type"]').each(function(){ addrVals[$(this).parents('[data-type="%address"]').attr('data-id')] = $(this).val(); }); } var country_option=abContactRef.find('[data-type="\\%address"]').find('[data-type="country_type"]').find('option').last().clone(); abContactRef.find('[data-type="\\%address"]').find('[data-type="country_type"]').html(''); // we need a copy of the object because of the next "delete" operation var addressTypesTmp=jQuery.extend({}, addressTypes); // delete custom ordered element before the sort (then we will add them back) if(globalSettings.addresscountryfavorites.value.length>0) for(var i=globalSettings.addresscountryfavorites.value.length-1;i>=0;i--) delete addressTypesTmp[globalSettings.addresscountryfavorites.value[i]]; var addressTypesArr=sortCountries(addressTypesTmp); // re-add custom ordered elements from the original addressTypes (where all elements are still present) if(globalSettings.addresscountryfavorites.value.length>0) for(var i=globalSettings.addresscountryfavorites.value.length-1;i>=0;i--) addressTypesArr.unshift({'key': globalSettings.addresscountryfavorites.value[i], 'value': addressTypes[globalSettings.addresscountryfavorites.value[i]], 'translated_value': localization[globalInterfaceLanguage]['txtAddressCountry'+globalSettings.addresscountryfavorites.value[i].toUpperCase()]}); for(var i=0;i').append($(newSVG).clone()).html()); } /*************************** END OF BAD HACKS SECTION ***************************/ for(var i=0; i').append($(newSVG).clone()).html()); } /*************************** END OF BAD HACKS SECTION ***************************/ tmp.prop('readonly', readonly); found_non_empty=1; } else $(element).addClass(cssElementNoDisplay); } else // 'show' { empty = empty || $(element).hasClass(cssElementNoDisplay); $(element).removeClass(cssElementNoDisplay); $(element).find('[data-type="\\%add"]').find('input[type="image"]').removeClass(cssElementNoDisplay); $(element).find('[data-type="\\%del"]').find('input[type="image"]').removeClass(cssElementNoDisplay); $(element).find('select').prop('disabled', disabled); $(element).find('textarea').prop('disabled', disabled); /*************************** BAD HACKS SECTION ***************************/ if($.browser.msie || $.browser.mozilla) { var newSVG=$((disabled ? SVG_select_dis : SVG_select)).attr('data-type', 'select_icon').css({'pointer-events': 'none', 'z-index': '1', 'display': 'inline', 'margin-left': (disabled ? '-22px' : '-19px'), 'vertical-align': 'top', 'background-color': '#ffffff'}); // background-color = stupid IE9 bug //XXXX check this - was $('#ABContact') $(element).find('svg[data-type="select_icon"]').replaceWith($('
').append($(newSVG).clone()).html()); } /*************************** END OF BAD HACKS SECTION ***************************/ tmp.prop('readonly', readonly); } } ); if(processingType==='show' && !empty) { if(typeList[i].sel==='[data-type="\\%address"]') { tmp.each(function() { var street = $(this).find('[data-addr-field="street"]'); if(street.val()) { street.trigger('keyup.street'); } }); } if(typeof globalContactAutoExpand=='undefined' || globalContactAutoExpand!=false) tmp.last().find('[data-type="\\%add"]').find('.op').trigger('click'); } // set the visibility of the buttons if(processingType=='hide') { if(inputIsReadonly!=true) { if(typeof globalGroupContactsByCompanies!='undefined' && globalGroupContactsByCompanies==true && inputIsCompany) tmp_ref.find('[data-type="add_contact"]').removeClass(cssElementNoDisplay); else tmp_ref.find('[data-type="add_contact"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="edit"]').removeClass(cssElementNoDisplay); } else { tmp_ref.find('[data-type="add_contact"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="edit"]').addClass(cssElementNoDisplay); } tmp_ref.find('[data-type="save"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="cancel"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="delete_from_group"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="delete"]').addClass(cssElementNoDisplay); } else if(processingType=='add') { tmp_ref.find('[data-type="add_contact"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="edit"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="save"]').removeClass(cssElementNoDisplay); tmp_ref.find('[data-type="cancel"]').removeClass(cssElementNoDisplay); tmp_ref.find('[data-type="delete_from_group"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="delete"]').addClass(cssElementNoDisplay); } else { tmp_ref.find('[data-type="add_contact"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="edit"]').addClass(cssElementNoDisplay); tmp_ref.find('[data-type="save"]').removeClass(cssElementNoDisplay); tmp_ref.find('[data-type="cancel"]').removeClass(cssElementNoDisplay); // show "Delete from Group" only if there is an active contact group // XXX we need to use another identificator // if(globalResourceCardDAVList.getLoadedAddressbook().filterUID[globalResourceCardDAVList.getLoadedAddressbook().filterUID.length-1]!='/') // tmp.find('[data-type="delete_from_group"]').removeClass(cssElementNoDisplay); tmp_ref.find('[data-type="delete"]').removeClass(cssElementNoDisplay); } if(!found_non_empty) { if(processingType=='hide') tmp.prev().addClass(cssElementNoDisplay); else tmp.prev().removeClass(cssElementNoDisplay); } } // set editor "process" hook if(typeof(globalContactsExtEditorProcess)=='function') globalContactsExtEditorProcess(tmp_ref, 'post', processingType, inputIsCompany); } function loadImage(image) { var canvas = $('#photo'); var canvasElement = canvas.get(0); var imageWidth = image.width; var imageHeight = image.height; var canvasWidth = canvas.width()*globalContactPhotoScaleFactor; var canvasHeight = canvas.height()*globalContactPhotoScaleFactor; var clipStartX = 0; var clipStartY = 0; var clipWidth = imageWidth; var clipHeight = imageHeight; canvasElement.width = canvasWidth; canvasElement.height = canvasHeight; if(imageWidth-canvasWidth < imageHeight-canvasHeight) { var clipLength = Math.ceil((imageHeight-imageWidth/canvasWidth*canvasHeight)/2); clipStartY = clipLength; clipHeight = imageHeight-clipLength*2; } else { var clipLength = Math.ceil((imageWidth-imageHeight/canvasHeight*canvasWidth)/2); clipStartX = clipLength; clipWidth = imageWidth-clipLength*2; } canvasElement.getContext('2d').drawImage(image, clipStartX, clipStartY, clipWidth, clipHeight, 0, 0, canvasWidth, canvasHeight); canvas.removeClass('photo_blank'); } function CardDAVeditor_cleanup(inputLoadEmpty, inputIsCompany) { CardDAVcleanupRegexEnvironment(); // Cleanup the editor and store reference to the editor object globalRefVcardEditor=globalTranslVcardTemplate.clone(); // cleanup old data form address fields globalAddressElementOldData={}; if(typeof(globalContactsExtEditorProcess)=='function') globalContactsExtEditorProcess(globalRefVcardEditor, 'pre', null, inputIsCompany); /*************************** BAD HACKS SECTION ***************************/ /* IE or FF */ if($.browser.msie || $.browser.mozilla) { // ADD empty SVG to interface (we will replace it later) $('').css('display', 'none').insertAfter(globalRefVcardEditor.find('select[data-type$="_type"]')); if($.browser.msie && parseInt($.browser.version, 10)==10) /* IE 10 (because there are no more conditional comments) */ globalRefVcardEditor.find('[data-type="\\%note"]').find('textarea[data-type="value"]').text('').attr('placeholder',$('[data-type="\\%note"]').find('textarea[data-type="value"]').attr('placeholder')); } /*************************** END OF BAD HACKS SECTION ***************************/ // bind events (see also add_elements()) // hide the "-" button (we maybe change this in future) globalRefVcardEditor.find('[data-type="\\%del"]').css('visibility', 'hidden'); var tmp_arr=['[data-type="\\%phone"]', '[data-type="\\%email"]', '[data-type="\\%url"]', '[data-type="\\%date"]', '[data-type="\\%person"]', '[data-type="\\%im"]', '[data-type="\\%profile"]', '[data-type="\\%address"]']; for(var i=0; i=0; i--) { for(var j=0; j .ablist_header'); if(globalLastScrollPos<=globalRefABList.scrollTop()) // scrolling DOWN { var next_h=$(element).nextAll('.ablist_header:visible').first(); // next visible header if(next_h!=null && next_h.offset().top>globalABListTop) // only if it is below to #ABList do action { var cloned=$(element).clone(); // do not create the floating header with the same text twice if(floating_elem.filter(':contains("'+jqueryEscapeSelector(cloned.text())+'")').length==0) { // parameters for the fixed element cloned.css({'top': globalABListTop, 'left': globalABListLeft, 'width': headerWidth, 'position': 'fixed', 'z-index': 1}); // remove the previous floating header floating_elem.remove(); // set the opacity back to standard value (item is invisible scrolled above the ABlist top) globalRefABListTable.children('.ablist_header').each(function(index,element){ if($(element).css('opacity')=='0'){$(element).css('opacity',0.85);} }); // set the element opacity to 0 and "replace" it with floating element above it $(element).css('opacity',0); cloned.appendTo('#SystemCardDavMATE'); } // move the previous floating header UP if(next_h.offset().top=globalABListTop) { var prev_h=$(element).prevAll('.ablist_header').first(); if(prev_h!=null) // if there is a previous header in #ABList do action { var cloned=$(prev_h).clone(); // do not create the floating header with the same text twice if(floating_elem.filter(':contains("'+jqueryEscapeSelector(cloned.text())+'")').length==0) { // parameters for the fixed element // cloned.css('top',globalABListTop-headerHeight); cloned.css({'top': Math.min(globalABListTop,$(element).offset().top-headerHeight), 'left': globalABListLeft, 'width': headerWidth, 'position': 'fixed', 'z-index': 1}); // remove the previous floating header floating_elem.remove(); // set the opacity back to standard value (item is invisible scrolled above the ABlist top) globalRefABListTable.children('.ablist_header').each(function(index,element){ if($(element).css('opacity')=='0'){$(element).css('opacity',0.85);} }); // set the previous element opacity to 0 and "replace" it with floating element above it $(prev_h).css('opacity',0); cloned.appendTo('#SystemCardDavMATE'); } } // move the next floating header DOWN if(floating_elem.length!=0 && floating_elem.offset().top we need to move it if(addressTypes[selectedCountry][i]['fid']!=tmp.closest('[data-addr-fid]').attr('data-addr-fid')) $(addressElement).find('[data-addr-fid="'+jqueryEscapeSelector(addressTypes[selectedCountry][i]['fid'])+'"]').append(tmp); } // set address country "update" hook if(typeof(globalContactsExtAddrElemAfterUpdate)=='function') globalContactsExtAddrElemAfterUpdate(addressElement, addressTypes[selectedCountry][i]); } // hide the unused fields by changing the CSS addressElement.find('[data-type="container"]').each( function(index,element) { var found=0; $(element).find('[data-addr-field]').each( function(index,element) { if($(element).attr('data-addr-field')!='') { found=1; return false; } } ); if(found) $(element).removeClass('element_no_display_af'); else $(element).addClass('element_no_display_af'); } ); // CUSTOM PLACEHOLDER (reinitialization due to possible placeholder value change) addressElement.find('input[data-type="value"][placeholder],textarea[data-type="value"][placeholder]').placeholder(); } function add_element(inputElementID, inputParentSelector, newElementSelector, inputAddClassSelector, inputDelClassSelector, newElementID) // note: newElementSelector is always used with .last() { // we assume that the new element is inputElementID.parent() to minimize then number of selectors! var newElement=inputElementID.parent().clone().wrap('
'); // wrap('
') is used because we use .find() which not searches the "self" // disable the "add" button on the current element (do not move above) inputElementID.filter(inputAddClassSelector).css('visibility', 'hidden'); // CUSTOM PLACEHOLDER // remove the "placeholder" data (custom placeholder label for IE) newElement.find('label').remove(); newElement.find('[data-type="date_value"],[data-type="value"]').removeAttr('id', '').removeClass('placeholder-input'); // unselect each selected element newElement.find('option').prop('selected', false); // remove the form values newElement.find('[data-type$="value"], [data-type$="date_value"]').val(''); // hide custom types newElement.find('[data-type="custom_span"]').css('display', 'none'); // get the current data-id value var prevID=newElement.attr("data-id"); // add the new data-id value newElement.attr("data-id", newElementID); // add element "before insert" hook if(typeof(globalContactsExtAddElemBeforeInsert)=='function') globalContactsExtAddElemBeforeInsert(newElement); // add the new element (with enabled "add" button) + store the reference to the current element var tmpRef=inputElementID.parent().after(newElement); // enable the "del" button on this and the previous element tmpRef.next().addBack().find(inputDelClassSelector).css('visibility', ''); // now we need a reference to the new element var tmpRef=tmpRef.next(); // CUSTOM PLACEHOLDER // enable custom placeholder support (it is enabled only if needed) tmpRef.find('input[data-type="value"][placeholder], input[data-type="date_value"][placeholder],textarea[data-type="value"][placeholder]').placeholder(); // enable autosize for textarea elements tmpRef.find('textarea[data-type="value"]').autosize({defaultStyles: {height: '64', overflow: '', 'overflow-y': '', 'word-wrap': '', resize: 'none'}, callback: function(){checkContactFormScrollBar();}}); //bind datepicker if(tmpRef.find('input[data-type="date_value"]').hasClass('hasDatepicker')) tmpRef.find('input[data-type="date_value"]').removeClass('hasDatepicker'); if(tmpRef.find('input[data-type="date_value"]').parent().find('img').css('display')!='none') tmpRef.find('input[data-type="date_value"]').parent().find('img').css('display','none') tmpRef.find('input[data-type="date_value"]').focus(function(){initDatePicker($(this));}); // bind events var tmp_arr=['[data-type="\\%phone"]', '[data-type="\\%email"]', '[data-type="\\%url"]', '[data-type="\\%date"]', '[data-type="\\%person"]', '[data-type="\\%im"]', '[data-type="\\%profile"]', '[data-type="\\%address"]']; if(tmp_arr.indexOf(inputParentSelector)!=-1) { tmpRef.find('[data-type="\\%add"] input').data('customSelector', inputParentSelector).click(function(){add_element($(this).parent(), $(this).data('customSelector'), $(this).data('customSelector'), '[data-type="\\%add"]','[data-type="\\%del"]', globalABEditorCounter[$(this).data('customSelector')]++);checkContactFormScrollBar();}); tmpRef.find('[data-type="\\%del"] input').data('customSelector', inputParentSelector).click(function(){del_element($(this).parent(), $(this).data('customSelector'), '[data-type="\\%add"]','[data-type="\\%del"]');checkContactFormScrollBar();}); if(typeof globalContactAutoExpand=='undefined' || globalContactAutoExpand!=false) { tmpRef.find('input[type="text"]').bind('keyup', function() { var el = $(this); var row = el.closest('tr[data-type^="%"]'); var isLast = row.attr('data-type')!==row.next().attr('data-type'); if(isLast && el.val()) { row.find('[data-type="\\%add"] input').trigger('click'); } }); } // one special thing for address if(inputParentSelector=='[data-type="\\%address"]' && tmpRef.attr('data-type')=='%address') tmpRef.find('[data-type="country_type"]').change(function(){set_address_country(this);checkContactFormScrollBar();}); } if(inputParentSelector=='[data-type="\\%address"]') { // execute the "autoselect" var tmp=inputElementID.closest(inputParentSelector).next(); var tmp_select=tmp.find('[data-autoselect]').attr('data-autoselect'); if(tmp_select!=null) { tmp.find('[data-type="country_type"]').children('[data-type="'+jqueryEscapeSelector(tmp_select)+'"]').prop('selected', true); tmp.find('[data-autoselect]').change(); } } tmpRef.find('[data-type="custom_value"]').bind('keyup change', function(){ $(this).parent().find('[data-type="invalid"]').css('display', (vCard.pre['custom_type'].test($(this).val()) ? 'none' : 'inline')); }); if(typeof(globalContactsExtAddElemAfterInsert)=='function') globalContactsExtAddElemAfterInsert(tmpRef, inputDelClassSelector, prevID); return true; } function del_element(inputElementID, inputParentSelector, inputAddClassSelector, inputDelClassSelector) { // all elements except the last can be removed if(inputElementID.closest(inputParentSelector).siblings(inputParentSelector).length>0) { inputElementID.closest(inputParentSelector).remove(); // enable the "add" button on last element $(inputParentSelector).last().find(inputAddClassSelector).css('visibility', ''); // hide the "del" button if only one element is present (we maybe change this in future) if($(inputParentSelector).length==1) $(inputParentSelector).last().find(inputDelClassSelector).css('visibility', 'hidden'); } else // currently not used because the "-" button is hidden on the last element (we maybe change this in future) inputElementID.closest(inputParentSelector).find('input[data-type="value"]').val(''); } /* BEGIN image manipulation */ function process_image(event) { event.stopPropagation(); event.preventDefault(); // allow image manipulation only if the editor is in "edit" state if($('#vCardEditor').attr('data-editor-state')!="edit") return false; if(typeof event.originalEvent.dataTransfer!='undefined') var files=event.originalEvent.dataTransfer.files; // fileList object from drag&drop else var files=event.originalEvent.target.files; // fileList object from input type file // files is a FileList of File objects. List some properties. for(var i=0;i65536) // continue; // show the image "delete" button $('#reset_img').css('display', 'inline'); // remove the template related to previous image (start with clean one) vCard.tplM['contentline_PHOTO'][0]=null; var reader=new FileReader(); // closure to capture the file information. reader.onload=(function(theFile){ return function(e){ //escape(files[i].name), files[i].type, files[i].size, files[i].lastModifiedDate var newImg=new Image(); newImg.src=e.target.result; newImg.onload=function(){ loadImage(this); }; }; })(files[i]); reader.readAsDataURL(files[i]); break; // we handle only the first picture here ... } $('#photoURL, #photoURLHidden').val(''); } /* END image manipulation */ function hideNotVisibleMessage() { globalAddressbookList.contactToReload=null; animate_message('#ABInMessageEditBox', '#ABInMessageTextEditBox', 0, '-='); $('#ABInMessageEditBox').css('display',''); } function initSearchCardDav() { if(globalQs==null) { $('#SearchBox').find('input[data-type="search"]').keyup(function(){ globalAddressbookList.contactToReload=null }); globalQs=$('#SearchBox').find('input[data-type="search"]').quicksearch(globalAddressbookList.contacts, { delay: 250, hide: function(){ var tmp=$(this)[0]; if(!tmp.headerOnly) tmp.search_hide=true; }, show: function(){ var tmp=$(this)[0]; if(!tmp.headerOnly) tmp.search_hide=false; }, prepareQuery: function (val){ return val.multiReplace(globalSearchTransformAlphabet).toLowerCase().split(' '); }, onBefore: function(){ if($('#SearchBox').find('input[data-type="search"]').val()=='') $('#SearchBox').find('img[data-type="reset"]').css('display','none'); else $('#SearchBox').find('img[data-type="reset"]').css('display',''); }, onAfter: function(){ globalAddressbookList.applyABFilter(dataGetChecked('#ResourceCardDAVList'),false); // XXX maybe this was the reason for data-filter-url? // globalAddressbookList.applyABFilter(globalRefAddContact.attr('data-filter-url'),false); // maybe useful for somebody // if((selected_contact=globalRefABListTable.find('.ablist_item_selected')).length==1) // globalRefABList.scrollTop(globalRefABList.scrollTop()+selected_contact.offset().top-globalRefABList.offset().top-globalRefABList.height()*globalKBNavigationPaddingRate); } }); } } function initKbAddrNavigation() { $(document.documentElement).keyup(function(event) { if(typeof globalActiveApp=='undefined' || globalActiveApp!='CardDavMATE') return true; if(globalActiveApp=='CardDavMATE' && globalObjectLoading==true) { event.preventDefault(); return true; } //if($('#SystemCardDavMATE').css('display')!='none' && $('#ABListLoader').css('display')=='none' && $('#ABListOverlay').css('display')=='none' && !$('input[data-type="search"]').is(':focus')) /* XXX - System display:none changes */ if($('#SystemCardDavMATE').css('visibility')!='hidden' && isCardDAVLoaded && $('#ABListOverlay').css('display')=='none' && !$('input[data-type="search"]').is(':focus')) { // 37 = left, 38 = up, 39 = right, 40 = down var selected_contact=null, next_contact=null; if((selected_contact=globalRefABListTable.find('.ablist_item_selected')).length==1) { if(event.keyCode == 38 && (next_contact=selected_contact.prevAll('.ablist_item').filter(':visible').first()).attr('data-id')!=undefined || event.keyCode == 40 && (next_contact=selected_contact.nextAll('.ablist_item').filter(':visible').first()).attr('data-id')!=undefined) globalAddressbookList.loadContactByUID(next_contact.attr('data-id')); } } }); $(document.documentElement).keydown(function(event) { if(typeof globalActiveApp=='undefined' || globalActiveApp!='CardDavMATE') return true; if(globalActiveApp=='CardDavMATE' && globalObjectLoading==true) { event.preventDefault(); return true; } //if($('#SystemCardDavMATE').css('display')!='none' && $('#ABListLoader').css('display')=='none' && $('#ABListOverlay').css('display')=='none' && !$('input[data-type="search"]').is(':focus')) /* XXX - System display:none changes */ if($('#SystemCardDavMATE').css('visibility')!='hidden' && isCardDAVLoaded && $('#ABListOverlay').css('display')=='none' && !$('input[data-type="search"]').is(':focus')) { // 37 = left, 38 = up, 39 = right, 40 = down var selected_contact=null, next_contact=null; if((selected_contact=globalRefABListTable.find('.ablist_item_selected')).length==1) { var wrapperRef = $('.ablist_table_wrapper'); if(event.keyCode == 38 && (next_contact=selected_contact.prevAll('.ablist_item').filter(':visible').first()).attr('data-id')!=undefined || event.keyCode == 40 && (next_contact=selected_contact.nextAll('.ablist_item').filter(':visible').first()).attr('data-id')!=undefined) { switch(event.keyCode) { case 38: event.preventDefault(); if(wrapperRef.scrollTop()>wrapperRef.scrollTop()+next_contact.offset().top-wrapperRef.offset().top-wrapperRef.height()*globalKBNavigationPaddingRate) wrapperRef.scrollTop(wrapperRef.scrollTop()+next_contact.offset().top-wrapperRef.offset().top-wrapperRef.height()*globalKBNavigationPaddingRate); else if(wrapperRef.scrollTop()wrapperRef.scrollTop()+next_contact.offset().top-wrapperRef.offset().top-wrapperRef.height()*globalKBNavigationPaddingRate) wrapperRef.scrollTop(wrapperRef.scrollTop()+next_contact.offset().top-wrapperRef.offset().top-wrapperRef.height()*globalKBNavigationPaddingRate); else return false; break; default: break; } } else // no previous contact and up pressed || no next contact and down pressed { switch(event.keyCode) { case 38: wrapperRef.scrollTop(0); break; case 40: wrapperRef.scrollTop(wrapperRef.prop('scrollHeight')); break; default: break; } } } } }); } function initDatePicker(inputObject) { if(!inputObject.hasClass('hasDatepicker')) { inputObject.datepicker({ disabled: inputObject.prop('readonly') || inputObject.prop('disabled'), showMonthAfterYear: true, prevText: '', nextText: '', monthNamesShort: ['01','02','03','04','05','06','07','08','09','10','11','12'], dateFormat: globalSettings.datepickerformat.value, defaultDate: '-'+Math.round(30*365.25-1), minDate: '-120y', maxDate: '+0', yearRange: 'c-120:+0', firstDay: globalSettings.datepickerfirstdayofweek.value, weekendDays: globalSettings.weekenddays.value, changeMonth: true, changeYear: true, showAnim: '', afterUpdate: function(inst) { /*************************** BAD HACKS SECTION ***************************/ // IE and FF datepicker selectbox problem fix if($.browser.msie || $.browser.mozilla) { var calendar=inst.dpDiv; setTimeout(function(){ if($.browser.msie && parseInt($.browser.version, 10)==10) /* IE 10 */ calendar.find('select').css({'padding-top': '1px', 'padding-left': '0px', 'padding-right': '0px'}); var newSVG=$(SVG_select).attr('data-type', 'select_icon').css({'pointer-events': 'none', 'z-index': '1', 'display': 'inline', 'margin-left': '-19px', 'vertical-align': 'top', 'background-color': '#ffffff'}); // background-color = stupid IE9 bug calendar.find('select').after($($('
').append($(newSVG).clone()).html())); },1); } else if(navigator.platform.toLowerCase().indexOf('win')==0 && $.browser.webkit && !!window.chrome) /* Chrome on Windows */ { var calendar=inst.dpDiv; setTimeout(function(){ calendar.find('select').css({'padding-left': '0px', 'padding-right': '13px'}); },1); } /*************************** END OF BAD HACKS SECTION ***************************/ }, beforeShow: function(input, inst) // set the datepicker value if the date is out of range (min/max) { inst.dpDiv.removeClass('ui-datepicker-simple'); var valid=true; try {var currentDate=$.datepicker.parseDate(globalSettings.datepickerformat.value, inputObject.val())} catch (e) {valid=false} if(valid==true && currentDate!=null) { var minDateText=inputObject.datepicker('option', 'dateFormat', globalSettings.datepickerformat.value).datepicker('option', 'minDate'); var maxDateText=inputObject.datepicker('option', 'dateFormat', globalSettings.datepickerformat.value).datepicker('option', 'maxDate'); var minDate=$.datepicker.parseDate(globalSettings.datepickerformat.value, minDateText); var maxDate=$.datepicker.parseDate(globalSettings.datepickerformat.value, maxDateText); if(currentDatemaxDate) inputObject.val(maxDateText); } // Timepicker hack (prevent IE to re-open the datepicker on date click + focus) var index=inputObject.attr("data-type"); var d = new Date(); if(globalTmpTimePickerHackTime[index]!=undefined && d.getTime()-globalTmpTimePickerHackTime[index]<200) return false; }, onClose: function(dateText, inst) // set the datepicker value if the date is out of range (min/max) and reset the value to proper format (for example 'yy-mm-dd' allows '2000-1-1' -> we need to reset the value to '2000-01-01') { var valid=true; try {var currentDate=$.datepicker.parseDate(globalSettings.datepickerformat.value, dateText)} catch (e) {valid=false} if(valid==true && currentDate!=null) { var minDateText=inputObject.datepicker('option', 'dateFormat', globalSettings.datepickerformat.value).datepicker('option', 'minDate'); var maxDateText=inputObject.datepicker('option', 'dateFormat', globalSettings.datepickerformat.value).datepicker('option', 'maxDate'); var minDate=$.datepicker.parseDate(globalSettings.datepickerformat.value, minDateText); var maxDate=$.datepicker.parseDate(globalSettings.datepickerformat.value, maxDateText); if(currentDatemaxDate) inputObject.val(maxDateText); else inputObject.val($.datepicker.formatDate(globalSettings.datepickerformat.value, currentDate)); } // Timepicker hack (prevent IE to re-open the datepicker on date click + focus) var index=inputObject.attr("data-type"); var d = new Date(); globalTmpTimePickerHackTime[index]=d.getTime(); inputObject.focus(); if(inputObject.closest('tr').attr('data-attr-name')==='X-ABDATE') { inputObject.trigger('keyup'); } } }); inputObject.mousedown(function(){ if(inputObject.datepicker('widget').css('display')=='none') inputObject.datepicker('show'); else inputObject.datepicker('hide'); }); inputObject.on('keydown', function(event){ // show datepicker on keydown (up/down/left/right) but only if it not causes cursor position move if(this.selectionStart!=undefined && this.selectionStart!=-1) if(((event.which==38 || event.which==37) && this.selectionStart==0) || ((event.which==40 || event.which==39) && this.selectionStart==$(this).val().length)) { if(inputObject.datepicker('widget').css('display')=='none') inputObject.datepicker('show'); else inputObject.datepicker('hide'); } }); inputObject.blur(function(event){ // handle onblur event because datepicker can be already closed // note: because onblur is called more than once we can handle it only if there is a value change! var valid=true; try {var currentDate=$.datepicker.parseDate(globalSettings.datepickerformat.value, inputObject.val())} catch (e) {valid=false} if(valid==true && inputObject.val()!=$.datepicker.formatDate(globalSettings.datepickerformat.value, currentDate)) { var minDateText=inputObject.datepicker('option', 'dateFormat', globalSettings.datepickerformat.value).datepicker('option', 'minDate'); var maxDateText=inputObject.datepicker('option', 'dateFormat', globalSettings.datepickerformat.value).datepicker('option', 'maxDate'); var minDate=$.datepicker.parseDate(globalSettings.datepickerformat.value, minDateText); var maxDate=$.datepicker.parseDate(globalSettings.datepickerformat.value, maxDateText); if(currentDatemaxDate) inputObject.val(maxDateText); else inputObject.val($.datepicker.formatDate(globalSettings.datepickerformat.value, currentDate)); } }); inputObject.on('keyup change', function(){ if(!$(this).prop('readonly') && !$(this).prop('disabled')) { var valid=true; if($(this).val()!='') { try {$.datepicker.parseDate(globalSettings.datepickerformat.value, $(this).val())} catch (e) {valid=false} } if(valid) $(this).parent().find('img').css('display','none'); else $(this).parent().find('img').css('display','inline'); } }); // show the datepicker after the initialization inputObject.datepicker('show'); } } function checkForVcardGroups(contactUID) { if($('#vCardEditor').attr('data-url')==contactUID) { var collUID= contactUID.replace(RegExp('[^/]*$'),''); var select_elem=$('#vCardEditor').find('[data-attr-name="_DEST_"]').find('[data-type="'+jqueryEscapeSelector(collUID)+'"]'); if(select_elem.length==1) { var vGroupC = globalAddressbookList.getMyContactGroups(contactUID).length; if(vGroupC>1) select_elem.text(localization[globalInterfaceLanguage].txtVcardGroupsTextMulti.replace('%coll%',globalResourceCardDAVList.getCollectionByUID(collUID).displayvalue).replace('%n%',vGroupC)); else if(vGroupC==1) select_elem.text(localization[globalInterfaceLanguage].txtVcardGroupsTextSingle.replace('%coll%',globalResourceCardDAVList.getCollectionByUID(collUID).displayvalue)); } } } function checkContactFormScrollBar() { var baseWidth = 582; var scrollWidth = $('#EditorBox').length ? $('#ABContact').outerWidth() - $('#EditorBox').outerWidth() : 0; var previousWidth = parseInt($('#ABList').css('right'), 10); var newWidth = baseWidth+scrollWidth; if(previousWidth===newWidth) return true; $('.collection_d, #SearchBox, #ABList').css('right', newWidth); $('#ABListOverlay').css('right', newWidth+1); $('.contact_d, #ABMessage, #ABContactOverlay').width(newWidth); $('#ABContactColor').css('right', newWidth-3); $('#ABContact').width(newWidth-3); var columnLengths = []; for(var i=0; i'); var destSelected = dest.children(':selected'); var header = null; var headerShown = false; var currentGroups = typeof $('#vCardEditor').attr('data-vcard-uid')=='undefined' ? [] : globalAddressbookList.getMyContactGroups($('#vCardEditor').attr('data-url')); dest.parent().after(extendedDest); for(var i=0; i').addClass('extended_dest_header').text(header.displayvalue).appendTo(extendedDest); headerShown = true; } var itemEl = $('
').addClass('extended_dest_item'); var resourceEl = $('
').addClass('extended_dest_resource').text(resource.displayvalue); var groupContEl = $('
').addClass('extended_dest_group_container'); $('').attr({'type':'checkbox','data-id':resource.uid}) .prop('checked',resource.uid==destSelected.attr('data-type')) .change(function(){ if($(this).prop('checked')) { var newCollection = globalResourceCardDAVList.getCollectionByUID($(this).attr('data-id')); $(this).parent().parent().siblings().find('input[type="checkbox"]').prop('checked',false); dest.children('[data-type="'+newCollection.uid+'"]').prop('selected',true).text(newCollection.displayvalue); $('#ABContactColor').css('background-color',newCollection.color); } else $(this).prop('checked',true); }) .prependTo(resourceEl); $('
').addClass('extended_dest_resource_color').css('background-color',resource.color).prependTo(resourceEl); for(var j=0; j').addClass('extended_dest_group').text(group.displayvalue); $('').attr({'type':'checkbox','data-id':group.uid}) .prop('checked',currentGroups.indexOf(group.uid)!=-1 || typeof selGroup!= 'undefined' && selGroup==group.uid) .change(function(){ var groupCount = $(this).parent().parent().find('input[type="checkbox"]:checked').length; var newCollectionUID = $(this).parent().parent().prev().children('input[type="checkbox"]').attr('data-id'); var newCollection = globalResourceCardDAVList.getCollectionByUID(newCollectionUID); if(groupCount>1) dest.children('[data-type="'+newCollectionUID+'"]').text(localization[globalInterfaceLanguage].txtVcardGroupsTextMulti.replace('%coll%',newCollection.displayvalue).replace('%n%',groupCount)); else if(groupCount==1) dest.children('[data-type="'+newCollectionUID+'"]').text(localization[globalInterfaceLanguage].txtVcardGroupsTextSingle.replace('%coll%',newCollection.displayvalue)); else dest.children('[data-type="'+newCollectionUID+'"]').text(newCollection.displayvalue); if($(this).prop('checked')) { $(this).parent().parent().prev().children('input[type="checkbox"]').prop('checked',true); $(this).parent().parent().parent().siblings().find('input[type="checkbox"]').prop('checked',false); dest.children('[data-type="'+newCollectionUID+'"]').prop('selected',true); $('#ABContactColor').css('background-color',newCollection.color); } }) .prependTo(groupEl); $('
').addClass('extended_dest_group_color').css('background-color',group.color).prependTo(groupEl); groupEl.appendTo(groupContEl); } resourceEl.appendTo(itemEl); groupContEl.appendTo(itemEl); itemEl.appendTo(extendedDest); } } dest.mousedown(function(e){ e.stopPropagation(); e.preventDefault(); this.blur(); if(extendedDest.height()>0) { dest.removeClass('inverse_select'); /*************************** BAD HACKS SECTION ***************************/ if($.browser.msie || $.browser.mozilla) { var newSVG=$(SVG_select).attr('data-type', 'select_icon').css({'pointer-events': 'none', 'z-index': '1', 'display': 'inline', 'margin-left': '-19px', 'vertical-align': 'top', 'background-color': '#ffffff'}); // background-color = stupid IE9 bug dest.parent().find('svg[data-type="select_icon"]').replaceWith($('
').append($(newSVG).clone()).html()); } /*************************** END OF BAD HACKS SECTION ***************************/ extendedDest.animate({'height':0},200); $('html').unbind('mousedown'); } else { dest.addClass('inverse_select'); /*************************** BAD HACKS SECTION ***************************/ if($.browser.msie || $.browser.mozilla) { var newSVG=$(SVG_select_inv).attr('data-type', 'select_icon').css({'pointer-events': 'none', 'z-index': '1', 'display': 'inline', 'margin-left': '-19px', 'vertical-align': 'top', 'background-color': '#ffffff'}); // background-color = stupid IE9 bug dest.parent().find('svg[data-type="select_icon"]').replaceWith($('
').append($(newSVG).clone()).html()); } /*************************** END OF BAD HACKS SECTION ***************************/ extendedDest.animate({'height':164},200); $('html').mousedown(function(e){ if(e.target.id=='ExtendedDest' || $.contains(document.getElementById('ExtendedDest'),e.target)) return true; dest.removeClass('inverse_select'); /*************************** BAD HACKS SECTION ***************************/ if($.browser.msie || $.browser.mozilla) { var newSVG=$(SVG_select).attr('data-type', 'select_icon').css({'pointer-events': 'none', 'z-index': '1', 'display': 'inline', 'margin-left': '-19px', 'vertical-align': 'top', 'background-color': '#ffffff'}); // background-color = stupid IE9 bug dest.parent().find('svg[data-type="select_icon"]').replaceWith($('
').append($(newSVG).clone()).html()); } /*************************** END OF BAD HACKS SECTION ***************************/ extendedDest.animate({'height':0},200); $('html').unbind('mousedown'); }); } }); } /* $(document).on("mouseover", "#vCardEditor .ablist_item", function() { if(!$(this).is('.ui-draggable') && (typeof globalDisableDragAndDrop=='undefined' || globalDisableDragAndDrop!=true)) { $(this).draggable({ delay: 250, revert: 'invalid', scroll: false, opacity: 0.8, stack: '#SystemCardDavMATE', containment: '#SystemCardDavMATE', appendTo: 'body', start: function( event, ui ){ // disallow on read-only collection if(globalResourceCardDAVList.getCollectionPrivByUID($(this).attr('data-id').replace(RegExp('[^/]*$'),''))==true) return false; }, helper: function(){ $('#ResourceCardDAVList').find('.resourceCardDAV.ui-droppable').droppable( 'option', 'accept', false); $('#ResourceCardDAVList').find('.group.ui-droppable').droppable( 'option', 'accept', false); $('#ResourceCardDAVList').find('.resourceCardDAV[data-id!='+jqueryEscapeSelector($(this).attr('data-id').replace(RegExp('[^/]+$'),''))+'].ui-droppable').droppable( 'option', 'accept', '.ablist_item'); var myContactGroups=globalAddressbookList.getMyContactGroups($(this).attr('data-id')); $('#ResourceCardDAVList').find('.group[data-id^='+jqueryEscapeSelector($(this).attr('data-id').replace(RegExp('[^/]+$'),''))+'].ui-droppable').not('.resourceCardDAV_selected').each(function(index, element){ if(myContactGroups.indexOf($(element).attr('data-id'))==-1) $(element).droppable( 'option', 'accept', '.ablist_item'); }); var tmp=$(this).clone(); tmp.addClass('ablist_item_dragged'); // we cannot use .css() here, because we need to add !important (problem with Gecko based browsers) var tmp_style='max-width: '+$(this).outerWidth()+'px;'; if($(this).css('background-image')!='none') tmp_style+='background-image: url(images/company_s_w.svg) !important;'; tmp.attr('style', tmp_style); return tmp; } }); } }); */ function setDataColumnsWidth(cache) { if(!globalRefABListTableCols && !globalRefABListInnerTableCols) { return true; } // remove gutter $('.ablist_table_gutter').remove(); // clear old column widths globalRefABListTableCols.width(''); globalRefABListInnerTableCols.width(''); // use cached column values to compute new column widths var characterWidth = 9; // gross approximation var lastColumn = null; var lastInnerColumn = null; var scrollWidth = $('.ablist_table_wrapper').innerWidth() - globalRefABListTable.outerWidth(); var reservedWidth = 0; globalRefABListTable.children('.ablist_item').first().children().slice(0, globalFixedContactDataColumnsCount).each(function() { reservedWidth += $(this).width(); }); var availableWidth; var maxWidth; availableWidth = maxWidth = globalRefABList.innerWidth() - reservedWidth - scrollWidth; cache.every(function(lengths, index) { // var maxLength = Math.max.apply(null, lengths); lengths.sort(function(a, b) { return a - b; }); var maxLength = lengths[Math.max(Math.min(Math.ceil(lengths.length * globalContactDataMinVisiblePercentage), lengths.length) - 1, 0)]; var column = globalRefABListTableCols.eq(index + globalFixedContactDataColumnsCount); var innerColumn = globalRefABListInnerTableCols.eq(index + globalFixedContactDataColumnsCount); var columnWidth = Math.max(maxLength * characterWidth, getDataColumnMinWidthAtIndex(index)); // exit early if there is not enough space for the column if(columnWidth > availableWidth) { // if exiting at the very first column, mark it as the last visible one anyway // this will ensure that it gets to occupy what width there is available later on if(!lastColumn) { lastColumn = column; } if(!lastInnerColumn) { lastInnerColumn = innerColumn; } return false; } // dont show column if no data are present if(columnWidth && lengths[lengths.length - 1]>0) { lastColumn = column; lastInnerColumn = innerColumn; availableWidth -= columnWidth; column.width(columnWidth); innerColumn.width(columnWidth); } return true; }); // set the last visible column to occupy the rest of the available table width if(lastColumn && lastInnerColumn) { lastColumn.width(lastColumn.width() + availableWidth); lastInnerColumn.width(lastInnerColumn.width() + availableWidth); } // if scrollbar present, create gutter if(scrollWidth) { $('').width(scrollWidth).insertAfter(lastColumn); $('').insertAfter($('.ablist_table_header').children().eq(lastColumn.index())); } } function getDataColumnCount() { return globalSettings.collectiondisplay.value.length; } function isDataColumnDefined(column) { var re = RegExp('(?:^|[^\\\\]){'+column+'(?:\\[.*?\\])*'+'}', 'i'); return globalSettings.collectiondisplay.value.some(function(col) { if(col.hasOwnProperty('value')) { var values = col.value; if($.isPlainObject(values)) { return values.company.some(function(value) { return re.test(value) }) || values.personal.some(function(value) { return re.test(value) }); } return values.some(function(value) { return re.test(value) }); } return false; }); } function getContactDataColumns(isCompany) { return $.map(globalSettings.collectiondisplay.value, function(col) { var value = col.value; if($.isPlainObject(value)) { if(isCompany && value.hasOwnProperty('company')) { return [value.company]; } if(!isCompany && value.hasOwnProperty('personal')) { return [value.personal]; } } return [value]; }); } function getDataColumnLabelAtIndex(index) { if(globalSettings.collectiondisplay.value[index].hasOwnProperty('label')) { var label = globalSettings.collectiondisplay.value[index].label; if($.isPlainObject(label)) { return getDataColumnLabel(label[globalInterfaceLanguage] || ''); } else { return getDataColumnLabel(label); } } } function getDataColumnLabel(formatString) { var result = ''; var variableParts = null; var re = RegExp('(?:^|[^\\\\])({(.*?[^\\\\])})'); while(variableParts = formatString.match(re)) { var value = localization[globalInterfaceLanguage][globalContactDataColumnLabelVars[variableParts[2]]] || ''; formatString = formatString.replace(variableParts[1], value); } return formatString; } function getDataColumnMinWidthAtIndex(index) { return 100; } function setContactDataColumn(contact, column, value, filterData) { var column = column.toUpperCase(); if(globalContactDataColumnDefs.hasOwnProperty(column) && value) { var property = globalContactDataColumnDefs[column].property; if(!contact.hasOwnProperty(property)) { contact[property] = []; } var data = {}; for(var name in filterData) { var filterProperty = globalContactDataColumnDefs[column].filterProperities[name]; data[filterProperty] = filterData[name]; } if($.isArray(value)) { value = value.join(', '); } data.value = value; contact[property].push(data); } } function getContactDataColumn(contact, variables) { var result = ''; var variableParts = null; var re = RegExp('(?:^|[^\\\\])({(.*?[^\\\\])})'); variables.forEach(function(formatString) { var matched = false; while(variableParts = formatString.match(re)) { var value = getContactDataColumnVariable(contact, variableParts[2]); formatString = formatString.replace(variableParts[1], value); matched = matched || value!==''; } if(matched) { result += formatString; } }); return result; } function getContactDataColumnVariable(contact, variable) { var parts = variable.match(/^(.*?)(\[.*\])*$/); var attr = parts[1].toUpperCase(); if(parts && attr && globalContactDataColumnDefs.hasOwnProperty(attr)) { var property = globalContactDataColumnDefs[attr].property; if(contact.hasOwnProperty(property)) { var re = RegExp('\\[(.*?[^\\\\])\\]'); var numeral = 0; var filterStr = parts[2] ? parts[2].toUpperCase() : ''; var filters = []; var matches = contact[property]; while(filterStr) { var match = filterStr.match(re); if(match===null) { break; } filters.push(match[1].replaceAll('\\[', '[').replaceAll('\\]', ']')); filterStr = filterStr.replace(match[0], ''); } filters.forEach(function(filterEl) { if(filterEl[0]===':') { numeral = parseInt(filterEl.slice(1), 10); } else { var filterParts = filterEl.splitCustom('='); var filterType = filterParts[0]; var filterValue = filterParts[1]; if(filterType && filterValue && globalContactDataColumnDefs[attr].hasOwnProperty('filterProperities') && globalContactDataColumnDefs[attr].filterProperities.hasOwnProperty(filterType)) { var filterProperty = globalContactDataColumnDefs[attr].filterProperities[filterType]; matches = matches.filter(function(matchEl) { return matchEl[filterProperty].indexOf(filterValue)>-1; }); } } }); if(!isNaN(numeral) && numeral>-1 && numeral!\$_$/i); if(matched) { return matched[1]; } } return type; } function showPhotoBox(e) { if($('#photoBox').is(':visible')) hidePhotoBox(); else { e.stopPropagation(); $('#photoArrow, #photoBox').css('display', 'block'); $('#photoURL').focus(); $('html').bind('click.photo', function(e) { if(!$.contains(document.getElementById('photoBox'), e.target)) { hidePhotoBox(); } }); } } function hidePhotoBox() { $('#photoURL').val($('#photoURLHidden').val()); $('#photoBoxContent').find('[data-type="invalid"]').css('display', 'none'); $('#photoURL').removeClass('invalid'); $('#photoBox').css('display','none'); $('#photoArrow').css('display','none'); $('html').unbind('click.photo'); }