/* CardDavMATE - CardDav Web Client Copyright (C) 2011-2012 Jan Mate 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 . */ function processEditorElements(processingType, inputIsReadonly) { var cssShowAsTxtClass='element_show_as_text'; var cssGrayedTxt='element_grayed'; var cssElementNoDisplay='element_no_display'; var cssElementHide='element_hide'; if(processingType=='hide') { $('[id=vcard_editor]').attr('data-editor-state','show'); disabled=true; readonly=true; } else { $('[id=vcard_editor]').attr('data-editor-state','edit'); disabled=false; readonly=false; } // company checkbox and text var tmp=$('[id="vcard_editor"]').find('[data-type="isorg"]'); tmp.prop('disabled',disabled); if(processingType=='hide' && !tmp.prop('checked')) tmp.parent().addClass(cssGrayedTxt); else tmp.parent().removeClass(cssGrayedTxt); $('[data-type^="date_"]').prop('disabled', disabled || readonly); // family name, given name, and organization name var typeList = new Array('family','given','middle','nickname','prefix','suffix','date_bday','date_anniversary','tags','title','department','org'); for(i=0;i=0; i--) { for(var j=0; j=0; i--) { for(var j=0; j 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); } } } // 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, maxElements, newElementID) // note: newElementSelector is always used with .last() { // allow only maxElements items for this attribute if((count=inputElementID.closest(inputParentSelector).parent().children(inputParentSelector).length) < maxElements) { newElement=$(newElementSelector).last().clone().wrap('
'); // CUSTOM PLACEHOLDER // remove the "placeholder" data (custom placeholder label for IE) newElement.find('label').remove(); newElement.find('[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"]').val(''); // add the data-id value newElement.find(inputParentSelector).attr("data-id",newElementID); // disable the "add" on last element if maximum count is reached if(count==maxElements-1) newElement.find(inputAddClassSelector).css('visibility','hidden'); newElement=newElement.closest(inputParentSelector).parent().html(); // disable the "add" button on the current element inputElementID.filter(inputAddClassSelector).css('visibility','hidden'); // add the new element (with enabled "add" button) inputElementID.parent().after(newElement); // CUSTOM PLACEHOLDER // enable custom placeholder support (it is enable only if needed) $(newElementSelector).last().find('input[data-type="value"][placeholder],textarea[data-type="value"][placeholder]').placeholder(); // enable the "del" button on all elements $(inputParentSelector).find(inputDelClassSelector).css('visibility',''); 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"]').children('[data-type="'+jqueryEscapeSelector(tmp_select)+'"]').prop('selected',true); tmp.find('[data-autoselect]').change(); } } return true; } else return false; } 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',''); // disable the "del" button if only one element is present if($(inputParentSelector).length==1) $(inputParentSelector).last().find(inputDelClassSelector).css('visibility','hidden'); } } var globalCounter = new Object(); globalCounter['phoneID']=1; globalCounter['emailID']=1; globalCounter['urlID']=1; globalCounter['personID']=1; globalCounter['imID']=1; globalCounter['addressID']=1; $(document).on('keyup change', '[data-type^="date_"]', function(){ if(!$(this).prop('readonly') && !$(this).prop('disabled')) { var valid=true; if($(this).val()!='') { try {$.datepicker.parseDate(globalDatepickerFormat, $(this).val())} catch (e) {valid=false} } if(valid) $(this).parent().find('img').css('display','none'); else $(this).parent().find('img').css('display','inline'); } }); // Timepicker hack (prevent IE to re-open the datepicker on date click + focus) var globalTmpTimePickerHackTime=new Object(); $(document).on('focus', '[data-type^="date_"]', function(){if(!$(this).hasClass('hasDatepicker')){$(this).datepicker({disabled: $(this).prop('readonly') || $(this).prop('disabled'), showMonthAfterYear: true, prevText: '', nextText: '', monthNamesShort: ['01','02','03','04','05','06','07','08','09','10','11','12'], dateFormat: globalDatepickerFormat, defaultDate: '-'+Math.round(30*365.25-1), minDate: '-120y', maxDate: '+0', yearRange: 'c-120:+0', firstDay: 0, changeMonth: true, changeYear: true, showAnim: '', beforeShow: function(input, inst) // set the datepicker value if the date is out of range (min/max) { var valid=true; try {var currentDate=$.datepicker.parseDate(globalDatepickerFormat, $(this).val())} catch (e) {valid=false} if(valid==true) { var minDateText=$(this).datepicker('option', 'dateFormat', globalDatepickerFormat).datepicker('option', 'minDate'); var maxDateText=$(this).datepicker('option', 'dateFormat', globalDatepickerFormat).datepicker('option', 'maxDate'); var minDate=$.datepicker.parseDate(globalDatepickerFormat, minDateText); var maxDate=$.datepicker.parseDate(globalDatepickerFormat, maxDateText); if(currentDatemaxDate) $(this).val(maxDateText); } // Timepicker hack (prevent IE to re-open the datepicker on date click + focus) var index=$(this).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(globalDatepickerFormat, dateText)} catch (e) {valid=false} if(valid==true) { var minDateText=$(this).datepicker('option', 'dateFormat', globalDatepickerFormat).datepicker('option', 'minDate'); var maxDateText=$(this).datepicker('option', 'dateFormat', globalDatepickerFormat).datepicker('option', 'maxDate'); var minDate=$.datepicker.parseDate(globalDatepickerFormat, minDateText); var maxDate=$.datepicker.parseDate(globalDatepickerFormat, maxDateText); if(currentDatemaxDate) $(this).val(maxDateText); else $(this).val($.datepicker.formatDate(globalDatepickerFormat, currentDate)); } // Timepicker hack (prevent IE to re-open the datepicker on date click + focus) var index=$(this).attr("data-type"); var d = new Date(); globalTmpTimePickerHackTime[index]=d.getTime(); $(this).focus(); } }); $(this).mousedown(function(){ if($(this).datepicker('widget').css('display')=='none') $(this).datepicker('show'); else $(this).datepicker('hide'); }); $(this).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! if($(this).val()!=$.datepicker.formatDate(globalDatepickerFormat, $.datepicker.parseDate(globalDatepickerFormat, $(this).val()))) { var valid=true; try {var currentDate=$.datepicker.parseDate(globalDatepickerFormat, $(this).val())} catch (e) {valid=false} if(valid==true) { var minDateText=$(this).datepicker('option', 'dateFormat', globalDatepickerFormat).datepicker('option', 'minDate'); var maxDateText=$(this).datepicker('option', 'dateFormat', globalDatepickerFormat).datepicker('option', 'maxDate'); var minDate=$.datepicker.parseDate(globalDatepickerFormat, minDateText); var maxDate=$.datepicker.parseDate(globalDatepickerFormat, maxDateText); if(currentDatemaxDate) $(this).val(maxDateText); else $(this).val($.datepicker.formatDate(globalDatepickerFormat, currentDate)); } } }) }}); if(typeof globalEnableKbNavigation=='undefined' || globalEnableKbNavigation!==false) { $(document.documentElement).keyup(function (event) { if($('#System').css('display')!='none' && $('#ABListLoader').css('display')=='none' && $('#ABListOverlay').css('display')=='none' && !$('input[data-type="search"]').is(':focus')) { // 37 = left, 38 = up, 39 = right, 40 = down if((selected_contact=$('#ABList').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($('#System').css('display')!='none' && $('#ABListLoader').css('display')=='none' && $('#ABListOverlay').css('display')=='none' && !$('input[data-type="search"]').is(':focus')) { // 37 = left, 38 = up, 39 = right, 40 = down if((selected_contact=$('#ABList').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) { switch(event.keyCode) { case 38: event.preventDefault(); if(next_contact.offset().top<$('#ABList').height()*0.25) { var move=next_contact.offset().top-selected_contact.offset().top; if(next_contact.offset().top<0) $('#ABList').scrollTop($('#ABList').scrollTop()+next_contact.offset().top-$('#ABList').height()*0.25); else $('#ABList').scrollTop(Math.max(0,$('#ABList').scrollTop()+move)); } else if(next_contact.offset().top>$('#ABList').height()*0.75) /* contact invisible (scrollbar moved) */ $('#ABList').scrollTop($('#ABList').scrollTop()+next_contact.offset().top-($('#ABList').height()*0.75)); else return false; break; case 40: event.preventDefault(); if(selected_contact.offset().top>$('#ABList').height()*0.75) { var move=next_contact.offset().top-selected_contact.offset().top; if($('#ABList').scrollTop()+$('#ABList').height()*0.75