Some improvements to new editable item.

This commit is contained in:
Martin Edenhofer 2014-09-27 15:17:58 +02:00
parent 7b8723575f
commit 043bcd9a55
3 changed files with 99 additions and 58 deletions

View file

@ -11,7 +11,33 @@
var DEFAULTS = { var DEFAULTS = {
mode: 'richtext', mode: 'richtext',
multiline: true multiline: true,
allowKey: {
8: true, // backspace
9: true, // tab
16: true, // shift
17: true, // ctrl
18: true, // alt
20: true, // cabslock
37: true, // up
38: true, // right
39: true, // down
40: true, // left
91: true, // cmd left
92: true, // cmd right
},
extraAllowKey: {
65: true, // a + ctrl - select all
67: true, // c + ctrl - copy
86: true, // v + ctrl - paste
88: true, // x + ctrl - cut
90: true, // z + ctrl - undo
},
richTextFormatKey: {
66: true, // b
73: true, // i
85: true, // u
}
} }
var OPTIONS = {} var OPTIONS = {}
@ -40,6 +66,41 @@
} }
} }
// max length check
var maxLengthOk = function(field, typeAhead) {
var length = field.text().length
if (typeAhead) {
length = length + 1
}
if ( length > OPTIONS.maxlength ) {
field.addClass('invalid')
setTimeout(function(){
field.removeClass('invalid')
}, 1000);
return false
}
return true
}
// check if key is allowed, even if length limit is reached
var allowKey = function(e) {
if ( OPTIONS.allowKey[ e.keyCode ] ) {
return true
}
if ( ( e.ctrlKey || e.metaKey ) && OPTIONS.extraAllowKey[ e.keyCode ] ) {
return true
}
return false
}
// check if rich text key is pressed
var richTextKey = function(e) {
if ( ( e.ctrlKey || e.metaKey ) && OPTIONS.richTextFormatKey[ e.keyCode ] ) {
return true
}
return false
}
// get correct val if textbox // get correct val if textbox
$.fn.ceg = function(option) { $.fn.ceg = function(option) {
var options = $.extend({}, DEFAULTS, option) var options = $.extend({}, DEFAULTS, option)
@ -71,8 +132,7 @@
updatePlaceholder( this, 'add' ) updatePlaceholder( this, 'add' )
this.bind('focus', function (e) { this.bind('focus', function (e) {
updatePlaceholder( $(e.target), 'remove' ) updatePlaceholder( $(e.target), 'remove' )
}) }).bind('blur', function (e) {
this.bind('blur', function (e) {
updatePlaceholder( $(e.target), 'add' ) updatePlaceholder( $(e.target), 'add' )
}) })
} }
@ -80,53 +140,43 @@
// maxlength check // maxlength check
if ( options.maxlength ) { if ( options.maxlength ) {
this.bind('keydown', function (e) { this.bind('keydown', function (e) {
// check maxlength
var field = $(e.target) // check control key
var length = $(e.target).text().length if ( allowKey(e) ) {
if ( length >= options.maxlength ) { maxLengthOk( $(e.target) )
switch ( e.keyCode ) {
case 8: // backspace
// just go ahead
break;
case 37: // up
// just go ahead
break;
case 38: // right
// just go ahead
break;
case 39: // down
// just go ahead
break;
case 40: // left
// just go ahead
break;
case 65: // a + ctrl - select all
// just go ahead
if ( e.ctrlKey || e.metaKey ) {
break;
} }
case 65: // x + ctrl - cut
// just go ahead // check type ahead key
if ( e.ctrlKey || e.metaKey ) { else {
break; if ( !maxLengthOk( $(e.target), true ) ) {
}
default:
field.addClass('invalid')
e.preventDefault() e.preventDefault()
} }
} }
}).bind('keyup', function (e) {
// check control key
if ( allowKey(e) ) {
maxLengthOk( $(e.target) )
}
// check type ahead key
else { else {
if ( field.hasClass('invalid') ) { if ( !maxLengthOk( $(e.target), true ) ) {
field.removeClass('invalid') e.preventDefault()
} }
} }
}).bind('focus', function (e) {
maxLengthOk( $(e.target) )
}).bind('blur', function (e) {
maxLengthOk( $(e.target) )
}) })
} }
// just paste text // just paste text
if ( options.mode === 'textonly' ) { if ( options.mode === 'textonly' ) {
this.bind('paste', function (e) { this.bind('paste', function (e) {
var text = (e.originalEvent || e).clipboardData.getData('text/plain'); var text = (e.originalEvent || e).clipboardData.getData('text/plain')
var overlimit = false
if (text) { if (text) {
// replace new lines // replace new lines
@ -136,19 +186,21 @@
text = text.replace(/\t/g, '') text = text.replace(/\t/g, '')
} }
// limit length // limit length, limit paste string
if ( options.maxlength ) { if ( options.maxlength ) {
var pasteLength = text.length var pasteLength = text.length
var currentLength = $(e.target).text().length var currentLength = $(e.target).text().length
var overSize = ( currentLength + pasteLength ) - options.maxlength var overSize = ( currentLength + pasteLength ) - options.maxlength
if ( overSize > 0 ) { if ( overSize > 0 ) {
text = text.substr( 0, pasteLength - overSize ) text = text.substr( 0, pasteLength - overSize )
overlimit = true
} }
} }
// insert new text // insert new text
e.preventDefault() e.preventDefault()
document.execCommand('inserttext', false, text); document.execCommand('inserttext', false, text)
maxLengthOk( $(e.target), overlimit )
} }
}); });
@ -157,18 +209,8 @@
// disable rich text b/u/i // disable rich text b/u/i
if ( options.mode === 'textonly' ) { if ( options.mode === 'textonly' ) {
this.bind('keydown', function (e) { this.bind('keydown', function (e) {
if ( e.ctrlKey || e.metaKey ) { if ( richTextKey(e) ) {
switch ( e.keyCode ) {
case 66: // b
e.preventDefault() e.preventDefault()
break;
case 73: // i
e.preventDefault()
break;
case 85: // u
e.preventDefault()
break;
}
} }
}); });
} }

View file

@ -1,4 +1,4 @@
<h1><span contenteditable="true" class="ticket-title-update"><%= @P( @ticket.title ) %></span></h1> <h1><span contenteditable="true" class="ticket-title-update" data-placeholder="<%= @T('Enter Ticket Title...') %>"><%= @P( @ticket.title ) %></span></h1>
<small class="task-subline"> <small class="task-subline">
<%- @C('ticket_hook') %> <span class="ticket-number"><%- @ticket.number %></span> - <%- @T('created') %> <span class="humanTimeFromNow" data-time="<%- @ticket.created_at %>">?</span> <% if !@isCustomer && @ticket.escalation_time: %> - <%- @T('escalation') %> <span class="humanTimeFromNow escalation" data-time="<%- @ticket.escalation_time %>">?</span><% end %> <%- @C('ticket_hook') %> <span class="ticket-number"><%- @ticket.number %></span> - <%- @T('created') %> <span class="humanTimeFromNow" data-time="<%- @ticket.created_at %>">?</span> <% if !@isCustomer && @ticket.escalation_time: %> - <%- @T('escalation') %> <span class="humanTimeFromNow escalation" data-time="<%- @ticket.escalation_time %>">?</span><% end %>

View file

@ -3432,16 +3432,15 @@ footer {
[contenteditable] { [contenteditable] {
display: block; display: block;
white-space: pre; white-space: pre;
padding: 1px;
outline-style: none; outline-style: none;
} }
[contenteditable]:hover, [contenteditable]:focus { [contenteditable]:hover, [contenteditable]:focus {
padding: 0; margin: -1px;
border: 1px dotted hsl(145,51%,45%); border: 1px dotted hsl(145,51%,45%);
border-radius: 3px; border-radius: 3px;
} }
[contenteditable].invalid { [contenteditable].invalid {
padding: 0; margin: -1px;
border: 1px dotted #F92; border: 1px dotted #F92;
border-radius: 3px; border-radius: 3px;
} }