Sanitise (validate) textinput

1,201 views
Skip to first unread message

Leon A

unread,
Dec 16, 2013, 4:59:31 AM12/16/13
to kivy-...@googlegroups.com
Ive been trying to wrap my head around how to sanitise (validate) text input before its passed on to a function that uses its value.
And so far i have managed to lose more hair than normal.

I know its a simple thing thats why im getting so frustrated.
If somebody could show me a simple example with the code below so that only numbers are allowed to pass through to the function, I would be grateful!

import kivy
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.switch import Switch
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
Builder.load_string('''


<sanTool>:
    orientation: '
vertical'
    s_text: s_text
    e_text: e_text
    Switch:
        id: switch
    Button:
        id: btn
   
    text: 'btn'
        on_release: root.scan()
    TextInput:
        id: s_text
        bind: self.on_text_validate == root.validate(self,self.text)
        multiline: False
    TextInput:
        id: e_text
        bind: self.on_text_validate == root.validate(self,self.text)
        multiline: False
'''
)

class sanTool(BoxLayout):
   
def __init__(self, **kwargs):
       
super(sanTool, self).__init__(**kwargs)
           
   
def validate(self,instance,value):
       
print value              
       
       
   
def scan(self):
       
for i in range(int(self.s_text.text),int(self.e_text.text)):
           
print i
   

class sanApp(App):
   
def build(self):
       
return sanTool()

if __name__ == '__main__':
    sanApp
().run()


Alexander Taylor

unread,
Dec 16, 2013, 8:06:00 AM12/16/13
to kivy-...@googlegroups.com
You can't use a widget's bind method that way - in fact, in general you can't call arbitrary methods like this in kivy language. What your code actually does is check through everything, find that there is no bind *property*, and so create a new ObjectProperty called bind whose contents is the result of the boolean expression - which is False.

The correct way to do something when on_text_validate is dispatched is `on_text_validate: root.validate(self, self.text)`. That is, you refer to the event directly.

Ben Rousch

unread,
Dec 16, 2013, 8:06:05 AM12/16/13
to kivy-...@googlegroups.com
Here is a filtered textinput snippet that I found about a year ago. I haven't tested it. http://pastebin.com/vjPJHcqS


--
You received this message because you are subscribed to the Google Groups "Kivy users support" group.
To unsubscribe from this group and stop receiving emails from it, send an email to kivy-users+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
 Ben Rousch
   bro...@gmail.com
   http://clusterbleep.net/

Leon A

unread,
Dec 16, 2013, 1:29:32 PM12/16/13
to kivy-...@googlegroups.com
Thank you for both replies, I did think of using regex but I thought KIvy may have had a built in method or function of doing this?.

@Alexander Taylor - I realise I implemented this wrongly, the way I did it was the only way I could grab the value of the text input eg print it.

If I do on_text_validate: root.validate(self,self.text)

and do a print value, it prints nothing why?

ZenCODE

unread,
Dec 22, 2013, 4:17:23 PM12/22/13
to kivy-...@googlegroups.com
Howdy Leon ;-)

This should do what you need? I've used the on_text rather than on_text_validate for reasons I think you'll agree with when you use it. but hooked up the validate event in the second text input for demo purposes.


from kivy.app import App
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout

Builder.load_string('''
<sanTool>:
    orientation: '
vertical'
    s_text: s_text
    e_text: e_text
    Switch:
        id: switch
    Button:
        id: btn
        text: '
btn
'

        on_release: root.scan()
    TextInput:
        id: s_text
        #See http://kivy.org/docs/api-kivy.uix.textinput.html
        # on_text_validate is only fired when enter is pressed (if multiline)
        # or if it losses focus (in single-line)
        #on_text_validate: root.validate(self)

        # It might be better to use on_text, so it'
s immediate
        on_text
: root.enforce_numeric(self)
        multiline
: False
   
TextInput:
        id
: e_text
        text
: "0"
        on_text_validate
: root.validate(self)
        multiline
: False
''')

class sanTool(BoxLayout):
    def __init__(self, **kwargs):
        super(sanTool, self).__init__(**kwargs)
           
    def validate(self, text_input):
        print "validate got ", str(text_input)

    def enforce_numeric(self, text_input):
        """ Ensure the text input contains only numeric characters or nothing"""
        if not text_input.text.isdigit():
            digit_list = [num for num in text_input.text if num.isdigit()]
            text_input.text = "".join(digit_list)

    def scan(self):
        print "Scan called."



class sanApp(App):
    def build(self):
        return sanTool()

if __name__ == '
__main__':
    sanApp().run()

Peace

Leon A

unread,
Dec 26, 2013, 8:48:27 AM12/26/13
to kivy-...@googlegroups.com
Thanks Zen! , exactly what I was looking for.
Appreciate the help as always! :)

Geovane Silva

unread,
Mar 25, 2018, 7:41:44 AM3/25/18
to Kivy users support
Thank you very much, I was looking for something about a few hours ago and your answer served me perfectly.
Reply all
Reply to author
Forward
0 new messages