Update to latest jquery.tagedit version; extract tagedit stylesheets for shared use

This commit is contained in:
Thomas Bruederli 2014-03-27 19:17:18 +01:00
parent e94bdf64a5
commit c6b5283180
5 changed files with 228 additions and 179 deletions

186
plugins/tasklist/jquery.tagedit.js Executable file → Normal file
View file

@ -5,13 +5,14 @@
* Examples and documentation at: tagedit.webwork-albrecht.de
*
* Copyright (c) 2010 Oliver Albrecht <info@webwork-albrecht.de>
* Copyright (c) 2012 Thomas Brüderli <thomas@roundcube.net>
*
* License:
* This work is licensed under a MIT License
* http://www.opensource.org/licenses/mit-license.php
*
* @author Oliver Albrecht Mial: info@webwork-albrecht.de Twitter: @webworka
* @version 1.2.1 (11/2011)
* @version 1.5.1 (10/2013)
* Requires: jQuery v1.4+, jQueryUI v1.8+, jQuerry.autoGrowInput
*
* Example of usage:
@ -52,6 +53,7 @@
options = $.extend(true, {
// default options here
autocompleteURL: null,
checkToDeleteURL: null,
deletedPostfix: '-d',
addedPostfix: '-a',
additionalListClass: '',
@ -67,14 +69,15 @@
}
},
breakKeyCodes: [ 13, 44 ],
checkNewEntriesCaseSensitive: false,
checkNewEntriesCaseSensitive: false,
texts: {
removeLinkTitle: 'Remove from list.',
saveEditLinkTitle: 'Save changes.',
deleteLinkTitle: 'Delete this tag from database.',
deleteConfirmation: 'Are you sure to delete this entry?',
deletedElementTitle: 'This Element will be deleted.',
breakEditLinkTitle: 'Cancel'
breakEditLinkTitle: 'Cancel',
forceDeleteConfirmation: 'There are more records using this tag, are you sure do you want to remove it?'
},
tabindex: false
}, options || {});
@ -169,16 +172,16 @@
.each(function() {
$(this).autoGrowInput({comfortZone: 15, minWidth: 15, maxWidth: 20000});
// Event ist triggert in case of choosing an item from the autocomplete, or finish the input
// Event is triggert in case of choosing an item from the autocomplete, or finish the input
$(this).bind('transformToTag', function(event, id) {
var oldValue = (typeof id != 'undefined' && id.length > 0);
var oldValue = (typeof id != 'undefined' && (id.length > 0 || id > 0));
var checkAutocomplete = oldValue == true? false : true;
// check if the Value ist new
var isNewResult = isNew($(this).val(), checkAutocomplete);
if(isNewResult[0] === true || isNewResult[1] != null) {
if(isNewResult[0] === true || (isNewResult[0] === false && typeof isNewResult[1] == 'string')) {
if(oldValue == false && isNewResult[1] != null) {
if(oldValue == false && typeof isNewResult[1] == 'string') {
oldValue = true;
id = isNewResult[1];
}
@ -199,7 +202,8 @@
// close autocomplete
if(options.autocompleteOptions.source) {
$(this).autocomplete( "close" );
if($(this).is(':ui-autocomplete'))
$(this).autocomplete( "close" );
}
})
@ -288,7 +292,7 @@
}
return false;
})
// forward focus event
// forward focus event (on tabbing through the form)
.focus(function(e){ $(this).click(); })
}
@ -321,7 +325,7 @@
}
textfield.remove();
$(this).find('a.tagedit-save, a.tagedit-break, a.tagedit-delete, tester').remove(); // Workaround. This normaly has to be done by autogrow Plugin
$(this).find('a.tagedit-save, a.tagedit-break, a.tagedit-delete').remove(); // Workaround. This normaly has to be done by autogrow Plugin
$(this).removeClass('tagedit-listelement-edit').unbind('finishEdit');
return false;
});
@ -356,7 +360,16 @@
.click(function() {
window.clearTimeout(closeTimer);
if(confirm(options.texts.deleteConfirmation)) {
markAsDeleted($(this).parent());
var canDelete = checkToDelete($(this).parent());
if (!canDelete && confirm(options.texts.forceDeleteConfirmation)) {
markAsDeleted($(this).parent());
}
if(canDelete) {
markAsDeleted($(this).parent());
}
$(this).parent().find(':text').trigger('finishEdit', [true]);
}
else {
$(this).parent().find(':text').trigger('finishEdit', [true]);
@ -386,6 +399,42 @@
});
}
/**
* Verifies if the tag select to be deleted is used by other records using an Ajax request.
*
* @param element
* @returns {boolean}
*/
function checkToDelete(element) {
// if no URL is provide will not verify
if(options.checkToDeleteURL === null) {
return false;
}
var inputName = element.find('input:hidden').attr('name');
var idPattern = new RegExp('\\d');
var tagId = inputName.match(idPattern);
var checkResult = false;
$.ajax({
async : false,
url : options.checkToDeleteURL,
dataType: 'json',
type : 'POST',
data : { 'tagId' : tagId},
complete: function (XMLHttpRequest, textStatus) {
// Expected JSON Object: { "success": Boolean, "allowDelete": Boolean}
var result = $.parseJSON(XMLHttpRequest.responseText);
if(result.success === true){
checkResult = result.allowDelete;
}
}
});
return checkResult;
}
/**
* Marks a single Tag as deleted.
*
@ -451,12 +500,11 @@
}
});
}
// If there is an entry for that already in the autocomplete, don't use it (Check could be case sensitive or not)
for (var i = 0; i < result.length; i++) {
var label = typeof result[i] == 'string' ? result[i] : result[i].label;
if (options.checkNewEntriesCaseSensitive == false)
label = label.toLowerCase();
var resultValue = result[i].label? result[i].label : result[i];
var label = options.checkNewEntriesCaseSensitive == true? resultValue : resultValue.toLowerCase();
if (label == compareValue) {
isNew = false;
autoCompleteId = typeof result[i] == 'string' ? i : result[i].id;
@ -476,60 +524,60 @@
// See related thread: http://stackoverflow.com/questions/931207/is-there-a-jquery-autogrow-plugin-for-text-fields
$.fn.autoGrowInput = function(o) {
o = $.extend({
maxWidth: 1000,
minWidth: 0,
comfortZone: 70
}, o);
this.filter('input:text').each(function(){
var minWidth = o.minWidth || $(this).width(),
val = '',
input = $(this),
testSubject = $('<tester/>').css({
position: 'absolute',
top: -9999,
left: -9999,
width: 'auto',
fontSize: input.css('fontSize'),
fontFamily: input.css('fontFamily'),
fontWeight: input.css('fontWeight'),
letterSpacing: input.css('letterSpacing'),
whiteSpace: 'nowrap'
}),
check = function() {
if (val === (val = input.val())) {return;}
// Enter new content into testSubject
var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
testSubject.html(escaped);
// Calculate new width + whether to change
var testerWidth = testSubject.width(),
newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
currentWidth = input.width(),
isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
|| (newWidth > minWidth && newWidth < o.maxWidth);
// Animate width
if (isValidWidthChange) {
input.width(newWidth);
}
};
testSubject.insertAfter(input);
$(this).bind('keyup keydown blur update', check);
check();
});
return this;
o = $.extend({
maxWidth: 1000,
minWidth: 0,
comfortZone: 70
}, o);
this.filter('input:text').each(function(){
var minWidth = o.minWidth || $(this).width(),
val = '',
input = $(this),
testSubject = $('<tester/>').css({
position: 'absolute',
top: -9999,
left: -9999,
width: 'auto',
fontSize: input.css('fontSize'),
fontFamily: input.css('fontFamily'),
fontWeight: input.css('fontWeight'),
letterSpacing: input.css('letterSpacing'),
whiteSpace: 'nowrap'
}),
check = function() {
if (val === (val = input.val())) {return;}
// Enter new content into testSubject
var escaped = val.replace(/&/g, '&amp;').replace(/\s/g,'&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
testSubject.html(escaped);
// Calculate new width + whether to change
var testerWidth = testSubject.width(),
newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
currentWidth = input.width(),
isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth)
|| (newWidth > minWidth && newWidth < o.maxWidth);
// Animate width
if (isValidWidthChange) {
input.width(newWidth);
}
};
testSubject.insertAfter(input);
$(this).bind('keyup keydown blur update', check);
check();
});
return this;
};
})(jQuery);
})(jQuery);

View file

@ -0,0 +1,108 @@
/**
* Styles of the tagedit inputsforms
*/
.tagedit-list {
width: 100%;
margin: 0;
padding: 4px 4px 0 5px;
overflow: auto;
min-height: 26px;
background: #fff;
border: 1px solid #b2b2b2;
border-radius: 4px;
box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
-moz-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
-webkit-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
-o-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
}
.tagedit-list li.tagedit-listelement {
list-style-type: none;
float: left;
margin: 0 4px 4px 0;
padding: 0;
}
/* New Item input */
.tagedit-list li.tagedit-listelement-new input {
border: 0;
height: 100%;
padding: 4px 1px;
width: 15px;
background: #fff;
border-radius: 0;
box-shadow: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
-o-box-shadow: none;
}
.tagedit-list li.tagedit-listelement-new input:focus {
box-shadow: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
-o-box-shadow: none;
outline: none;
}
.tagedit-list li.tagedit-listelement-new input.tagedit-input-disabled {
display: none;
}
/* Item that is put to the List */
.tagedit span.tag-element,
.tagedit-list li.tagedit-listelement-old {
padding: 3px 0 1px 6px;
background: #ddeef5;
background: -moz-linear-gradient(top, #edf6fa 0%, #d6e9f3 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#edf6fa), color-stop(100%,#d6e9f3));
background: -o-linear-gradient(top, #edf6fa 0%, #d6e9f3 100%);
background: -ms-linear-gradient(top, #edf6fa 0%, #d6e9f3 100%);
background: linear-gradient(top, #edf6fa 0%, #d6e9f3 100%);
border: 1px solid #c2dae5;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
color: #0d5165;
}
.tagedit span.tag-element {
margin-right: 0.6em;
padding: 2px 6px;
/* cursor: pointer; */
}
.tagedit span.tag-element.inherit {
color: #666;
background: #f2f2f2;
border-color: #ddd;
}
.tagedit-list li.tagedit-listelement-old a.tagedit-close,
.tagedit-list li.tagedit-listelement-old a.tagedit-break,
.tagedit-list li.tagedit-listelement-old a.tagedit-delete,
.tagedit-list li.tagedit-listelement-old a.tagedit-save {
text-indent: -2000px;
display: inline-block;
position: relative;
top: -1px;
width: 16px;
height: 16px;
margin: 0 2px 0 6px;
background: url('data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAOCAYAAAD0f5bSAAAAgUlEQVQoz2NgQAKzdxwWAOIEIG5AwiC+AAM2AJQIAOL3QPwfCwaJB6BrSMChGB0nwDQYwATP3nn4f+Ge4ygKQXyQOJKYAUjTepjAm09fwBimEUTDxJA0rWdANxWmaMXB0xiGwDADurthGkEAmwbqaCLFeWQFBOlBTlbkkp2MSE2wAA8R50rWvqeRAAAAAElFTkSuQmCC') left 1px no-repeat;
cursor: pointer;
}
/** Special hacks for IE7 **/
html.ie7 .tagedit span.tag-element,
html.ie7 .tagedit-list li.tagedit-listelement-old {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#edf6fa', endColorstr='#d6e9f3', GradientType=0);
}
html.ie7 .tagedit-list li.tagedit-listelement span {
position: relative;
top: -3px;
}
html.ie7 .tagedit-list li.tagedit-listelement-old a.tagedit-close {
left: 5px;
}

View file

@ -826,99 +826,6 @@ label.block {
}
/**
* Styles of the tagedit inputsforms
*/
.tagedit-list {
width: 100%;
margin: 0;
padding: 4px 4px 0 5px;
overflow: auto;
min-height: 26px;
background: #fff;
border: 1px solid #b2b2b2;
border-radius: 4px;
box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
-moz-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
-webkit-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
-o-box-shadow: inset 0 0 2px 1px rgba(0,0,0, 0.1);
}
.tagedit-list li.tagedit-listelement {
list-style-type: none;
float: left;
margin: 0 4px 4px 0;
padding: 0;
}
/* New Item input */
.tagedit-list li.tagedit-listelement-new input {
border: 0;
height: 100%;
padding: 4px 1px;
width: 15px;
background: #fff;
border-radius: 0;
box-shadow: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
-o-box-shadow: none;
}
.tagedit-list li.tagedit-listelement-new input:focus {
box-shadow: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
-o-box-shadow: none;
outline: none;
}
.tagedit-list li.tagedit-listelement-new input.tagedit-input-disabled {
display: none;
}
/* Item that is put to the List */
.form-section span.tag-element,
.tagedit-list li.tagedit-listelement-old {
padding: 3px 0 1px 6px;
background: #ddeef5;
background: -moz-linear-gradient(top, #edf6fa 0%, #d6e9f3 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#edf6fa), color-stop(100%,#d6e9f3));
background: -o-linear-gradient(top, #edf6fa 0%, #d6e9f3 100%);
background: -ms-linear-gradient(top, #edf6fa 0%, #d6e9f3 100%);
background: linear-gradient(top, #edf6fa 0%, #d6e9f3 100%);
border: 1px solid #c2dae5;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
color: #0d5165;
}
.form-section span.tag-element {
margin-right: 0.6em;
padding: 2px 6px;
/* cursor: pointer; */
}
.form-section span.tag-element.inherit {
color: #666;
background: #f2f2f2;
border-color: #ddd;
}
.tagedit-list li.tagedit-listelement-old a.tagedit-close,
.tagedit-list li.tagedit-listelement-old a.tagedit-break,
.tagedit-list li.tagedit-listelement-old a.tagedit-delete,
.tagedit-list li.tagedit-listelement-old a.tagedit-save {
text-indent: -2000px;
display: inline-block;
position: relative;
top: -1px;
width: 16px;
height: 16px;
margin: 0 2px 0 6px;
background: url(sprites.png) -2px -122px no-repeat;
cursor: pointer;
}
/** Special hacks for IE7 **/
/** They need to be in this file to also affect the task-create dialog embedded in mail view **/
@ -926,17 +833,3 @@ html.ie7 #taskedit-completeness-slider {
display: inline;
}
html.ie7 .form-section span.tag-element,
html.ie7 .tagedit-list li.tagedit-listelement-old {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#edf6fa', endColorstr='#d6e9f3', GradientType=0);
}
html.ie7 .tagedit-list li.tagedit-listelement span {
position: relative;
top: -3px;
}
html.ie7 .tagedit-list li.tagedit-listelement-old a.tagedit-close {
left: 5px;
}

View file

@ -777,11 +777,9 @@ class tasklist extends rcube_plugin
$this->ui->init_templates();
echo $this->api->output->parse('tasklist.taskedit', false, false);
echo html::tag('link', array('rel' => 'stylesheet', 'type' => 'text/css', 'href' => $this->url($this->local_skin_path() . '/tagedit.css'), 'nl' => true));
echo html::tag('script', array('type' => 'text/javascript'),
"rcmail.set_env('tasklists', " . json_encode($this->api->output->env['tasklists']) . ");\n".
// "rcmail.set_env('deleteicon', '" . $this->api->output->env['deleteicon'] . "');\n".
// "rcmail.set_env('cancelicon', '" . $this->api->output->env['cancelicon'] . "');\n".
// "rcmail.set_env('loadingicon', '" . $this->api->output->env['loadingicon'] . "');\n".
"rcmail.add_label(" . json_encode($texts) . ");\n"
);
exit;

View file

@ -81,6 +81,8 @@ class tasklist_ui
$this->plugin->include_script('jquery.tagedit.js');
$this->plugin->include_script('tasklist.js');
$this->plugin->include_stylesheet($this->plugin->local_skin_path() . '/tagedit.css');
}
/**