TextInput widget - make event oninput available to user #539
dddomodossola
started this conversation in
Ideas
Replies: 2 comments 7 replies
|
I have an Even if it does, I've noticed that you have some warnings in places that, IIRC, |
7 replies
|
Hello @johnperry-math , Thanks to your effort. I reworked your ExtendedTextInput this way to keep the previous logic and to add the oninput functionality. I tested it and it seems to work for single and multiline. class TextInput(Widget, _MixinTextualWidget):
"""Editable multiline/single_line text area widget. You can set the content by means of the function set_text or
retrieve its content with get_text.
"""
@property
@editor_attribute_decorator("WidgetSpecific",'''Defines the maximum text content length.''', int, {'possible_values': '', 'min': 0, 'max': 10000, 'default': 0, 'step': 1})
def attr_maxlength(self): return self.attributes.get('maxlength', '0')
@attr_maxlength.setter
def attr_maxlength(self, value): self.attributes['maxlength'] = str(value)
@attr_maxlength.deleter
def attr_maxlength(self): del self.attributes['maxlength']
def __init__(self, single_line=True, hint='', *args, **kwargs):
"""
Args:
single_line (bool): Determines if the TextInput have to be single_line. A multiline TextInput have a gripper
that allows the resize.
hint (str): Sets a hint using the html placeholder attribute.
kwargs: See Widget.__init__()
"""
super(TextInput, self).__init__(*args, **kwargs)
self.type = 'textarea'
self.single_line = single_line
self.attributes['single_line'] = 'false'
if single_line:
self.style['resize'] = 'none'
self.attributes['rows'] = '1'
self.attributes['single_line'] = 'true'
self.set_value('')
if hint:
self.attributes['placeholder'] = hint
self.attributes['autocomplete'] = 'off'
self.attributes[Widget.EVENT_ONCHANGE] = \
"var params={};params['new_value']=document.getElementById('%(emitter_identifier)s').value;" \
"remi.sendCallbackParam('%(emitter_identifier)s','%(event_name)s',params);"% \
{'emitter_identifier': str(self.identifier), 'event_name': Widget.EVENT_ONCHANGE}
def set_value(self, text):
"""Sets the text content.
Args:
text (str): The string content that have to be appended as standard child identified by the key 'text'
"""
if self.single_line:
text = text.replace('\n', '')
self.set_text(text)
def get_value(self):
"""
Returns:
str: The text content of the TextInput. You can set the text content with set_text(text).
"""
return self.get_text()
@decorate_set_on_listener("(self, emitter, new_value)")
@decorate_event_js("""
var is_single_line = (parseInt(document.getElementById('%(emitter_identifier)s').getAttribute('rows')) < 2);
var elem = document.getElementById('%(emitter_identifier)s');
var enter_pressed = (elem.value.indexOf('\\n') > -1);
if(enter_pressed && is_single_line){
elem.value = elem.value.split('\\n').join('');
}
var params={};
params['new_value']=elem.value;
params['enter_pressed']=enter_pressed;
remi.sendCallbackParam('%(emitter_identifier)s','%(event_name)s',params);
""")
def oninput(self, new_value, enter_pressed):
enter_pressed = enter_pressed in ('True', 'true')
if self.single_line and enter_pressed:
self.onchange(new_value)
return (new_value,)
@decorate_set_on_listener("(self, emitter, new_value)")
@decorate_event_js("""
var params={};
params['new_value']=document.getElementById('%(emitter_identifier)s').value;
remi.sendCallbackParam('%(emitter_identifier)s','%(event_name)s',params);""")
def onchange(self, new_value):
"""Called when the user changes the TextInput content.
With single_line=True it fires in case of focus lost and Enter key pressed.
With single_line=False it fires at each key released.
Args:
new_value (str): the new string content of the TextInput.
"""
self.disable_update()
self.set_value(new_value)
self.enable_update()
return (new_value, )
@decorate_set_on_listener("(self, emitter, new_value, keycode)")
@decorate_event_js("""var elem=document.getElementById('%(emitter_identifier)s');
var params={};params['new_value']=elem.value;params['keycode']=(event.which||event.keyCode);
remi.sendCallbackParam('%(emitter_identifier)s','%(event_name)s',params);""")
def onkeyup(self, new_value, keycode):
"""Called when user types and releases a key into the TextInput
Note: This event can't be registered together with Widget.onchange.
Args:
new_value (str): the new string content of the TextInput
keycode (str): the numeric char code
"""
return (new_value, keycode)
@decorate_set_on_listener("(self, emitter, new_value, keycode)")
@decorate_event_js("""var elem=document.getElementById('%(emitter_identifier)s');
var params={};params['new_value']=elem.value;params['keycode']=(event.which||event.keyCode);
remi.sendCallbackParam('%(emitter_identifier)s','%(event_name)s',params);""")
def onkeydown(self, new_value, keycode):
"""Called when the user types a key into the TextInput.
Note: This event can't be registered together with Widget.onchange.
Args:
new_value (str): the new string content of the TextInput.
keycode (str): the numeric char code
"""
return (new_value, keycode)Have a wonderful day, |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Actually the oninput event is internally used to manage ENTER key confirmation, this is related to single-line / multiline editing.
We should be able to achieve the same behaviour and expose the event to the user.
All reactions