This has probably done before, cant remnber seeing it though. But the code below is just using a view with a repeating number of labels and textfields to collect some data. What I have done is pretty crappy, but it does illustrate a different idea from using the dialogs module or a tableview to collect data. The difficulty to move away from them is the flexibility they offer thats built in. But this approach in my mind could be ok if you had modest needs. Hmmm, maybe. As I say It's just an idea.
Look many things are missing from this idea, like a scrolling view.
Maybe this type of an idea would be better moved in to a class. Maybe it should be disregarded altogether. I just wanted to try it out!
import ui
def text_form(items=None, width=320, **kwargs):
if not items or not len(items):
raise ValueError('items needs to be a list of strings or dicts')
global _results
input_flds = []
_results = None
_current_y = 6
_gap = 6
v = ui.View(frame=(0, 0, width, 100), **kwargs)
def obj_kwargs_setter(obj, **kwargs):
'''
generic way to set the kwargs for a given object
'''
[setattr(obj, k, v) for k, v in kwargs.items() if hasattr(obj, k)]
def _collect_data(sender):
'''
collect the data in the textfields
'''
global _results
_results = [{'key': obj.key, 'value': obj.text} for obj in input_flds]
sender.superview.close()
def _cancel_action(sender):
sender.superview.close()
def make_btn(name, title, action=None, **kwargs):
'''
create what I think is a std btn. kwargs will overwite any attr
'''
btn = ui.Button(height=32,
name=name,
title=title,
border_width=.5,
border_color='black',
bg_color='white',
corner_radius=6,
action=action,
)
btn.width = 80
obj_kwargs_setter(btn, **kwargs)
return btn
def make_field(fld_dict, y, **kwargs):
'''
create what I think is a std label + textField.
kwargs will overwite any attr of the textfield
'''
current_y = y
lb = ui.Label(frame=(6, current_y, 100, 32),
text=str(fld_dict['title']),
name=str(fld_dict['title']),
)
fld = ui.TextField(frame=(82, current_y, 230, 32))
fld.key = fld_dict['key']
input_flds.append(fld)
obj_kwargs_setter(fld, **kwargs)
v.add_subview(lb)
v.add_subview(fld)
return fld.height + _gap
flds = []
'''
step 1. checking to see if we have a list of strings or dicts.
hmmm, only checking the first element :(
This is imcomplete, just looking at a list of str's at the moment,
but still creating dict items. Although they are still not finished yet
'''
if isinstance(items[0], str):
for l in items:
flds.append(dict(type='Text', key=l, value='', title=l))
elif isinstance(items[0], dict):
'''
Not implemented yet
'''
pass
# make the labels & fields
for fld in flds:
y = make_field(fld, _current_y)
_current_y += y
# make & position the ok and canel buttons
ok_btn = make_btn('ok', 'OK', bg_color='purple', action=_collect_data,
tint_color='white')
v.add_subview(ok_btn)
cancel_btn = make_btn('cancel', 'Cancel', _cancel_action,
bg_color='deeppink', tint_color='white')
v.add_subview(cancel_btn)
ok_btn.y = _current_y + _gap
ok_btn.x = v.frame.max_x - (ok_btn.width + _gap)
_current_y += ok_btn.height + _gap
cancel_btn.y = ok_btn.y
cancel_btn.x = ok_btn.frame.min_x - (ok_btn.width + _gap)
v.height = _current_y + _gap
# make the first field ready for input, without having to tap it
input_flds[0].begin_editing()
v.present('sheet', animated=False)
v.wait_modal()
return _results
if __name__ == '__main__':
results = text_form(['Service', 'Account', 'Password'], bg_color='white',
name='Add KeyChain Service')
#results = text_form(['First', 'Last', 'Age', 'email'], bg_color='white',
#name='Add Person')
print(results)