EditableDomElements
function EditableDomElements($container, selector, config) {
var defaultOpts = {
textCancel: "Відміна",
textSave: "Зберегти",
textNoText: null,
inputType: 'textarea', // textarea|input
extractTextFromView: function($view) { return $view.text().trim() },
setTextToView: function($view, text) { $view.empty().text(text) },
configureTextarea: function($editor, $view) { $editor.height($view.outerHeight()) },
placeEditor: function($editor, $view) { $editor.insertAfter($view) },
domBtnCancel: function(textCancel) { return $("<button>").addClass('btn btn-mini').prop('type', 'button').text(textCancel + " (Esc)") },
domBtnSave: function(textSave) { return $("<button>").addClass('btn btn-mini').prop('type', 'button').text(textSave + " (Ctrl+Enter)").css('margin-left', '4px') },
domEditor: function($textarea, $btnCancel, $btnSave) {
return $div().addClass('inlineEditor').append(
$textarea,
$div().append( $btnCancel, $btnSave ) // buttons
)
},
// Should return {status: OK, text: "saved text"} if submission was successful, otherwise {status: "error_message"}
submit: function(text, $view, done) {
alert('submit option of EditableDomElements was not configured!')
done( { status: "OK", text: text } )
},
showSubmissionError: function(message) { alert(message) }
}
var opts = $.extend({}, defaultOpts, config)
function startEditor($view) {
var text = opts.extractTextFromView($view)
if (opts.textNoText != null && text == opts.textNoText)
text = ''
var inputType = opts.inputType || 'textarea'
if (inputType != 'textarea' && inputType != 'input')
inputType = 'textarea'
var $t = $("<"+inputType+">").val(text)
opts.configureTextarea($t, $view)
var $btnCancel = opts.domBtnCancel(opts.textCancel)
var $btnSave = opts.domBtnSave(opts.textSave)
var $editor = opts.domEditor($t, $btnCancel, $btnSave)
var $actionControls = $([]).add($editor).add($btnCancel).add($btnSave)
opts.placeEditor($editor, $view)
$view.hide()
$t.focus()
function hideEditor() {
$editor.remove()
$view.show()
}
function showSubmissionError(text) {
$actionControls.removeAttr('disabled')
opts.showSubmissionError(text)
}
function submitEditor() {
$actionControls.attr('disabled', 'disabled')
opts.submit($t.val(), $view, function(res){
if (typeof res != "object" || !res.status)
showSubmissionError('Submission result does not contain "status" property')
else if (res.status != "OK")
showSubmissionError(res.status)
else if (typeof res.text == "undefined")
showSubmissionError('Submission result does not contain "text" property')
else {
var textForView = res.text
if (opts.textNoText != null && textForView == '')
textForView = opts.textNoText
opts.setTextToView($view, textForView)
hideEditor()
$view.show()
}
})
}
$btnCancel.click(function(ev){ hideEditor() })
$btnSave.click(function(ev) { submitEditor() })
$t.keydown(function(e){
if (e.keyCode == 27) hideEditor() // esc
if (e.ctrlKey && e.keyCode == 13) { submitEditor() } // ctrl+enter
})
}
function editEvent(ev) { startEditor($(this)) }
if ($container == null)
$(selector).on('dblclick', editEvent)
else
$container.on('dblclick', selector, editEvent)
}