A div of four columns, the first just being label text, the second being text input fields, the third and fourth being submit buttons. Each row of the table is a form, the form action ident is the same for all forms and each form has four hidden fields.
As well as the input text field each form submits button and value, so which of the two buttons is pressed can be identified.
Below is an InputTable5 widget. If the length of an input string is less than 3, or greater than five characters, the input field shows an error colour, otherwise, a green accepted colour is shown.
On a submit button being pressed, the results are shown here:
This table lists the Responders called to produce this page:
skiwidgets,10902 | SubmitData | Sets up title and widget description |
skiwidgets,10904 | This page | This page is a template for the inputtables.InputTable5 widget |
This is a ShowCallData widget, which displays the contents of the skicall.call_data dictionary.
{}
Below is the Python file which populates this page.
import os from skipole import FailPage, GoTo, ValidateError, ServerError, ServeFile, PageData, SectionData # Normally table data would be taken from a file or database or other source of data. TABLECOL = ["one", "two", "three", "four"] def index(skicall): "Called by a SubmitData responder, and sets up the page" # the title and widget decription is in section 'header' which contains a # HeadText widget with name 'title' and a TextBlockPara widget with name 'widgetdesc' # It also has a ButtonLink2 widget with name 'tomodule' headersection = SectionData('header') headersection['title', 'large_text'] = 'InputTable5' # A textblock contains the widget description ref = "widgets.inputtables.InputTable5" headersection['widgetdesc','textblock_ref'] = ref headersection['widgetdesc','text_refnotfound'] = f'Textblock reference {ref} not found' # link to this widgets module page headersection['tomodule','button_text'] = "Module: inputtables" headersection['tomodule','link_ident'] = skicall.makepath('inputtables') skicall.update(headersection) # this code file contents is placed in section 'codefile' which contains a # PreText widget with name 'pretext' codesection = SectionData('codefile') code = os.path.realpath(__file__) with open(code) as f: codesection['pretext', 'pre_text'] = f.read() skicall.update(codesection) pd = PageData() pd['inputtable5','col_label'] = TABLECOL pd['inputtable5','col_input'] = TABLECOL # The hidden field is used to check which row has been submitted pd['inputtable5','hidden_field1'] = TABLECOL skicall.update(pd) def respond(skicall): "Responds to a table button being pressed" if ('inputtable5','hidden_field1') not in skicall.call_data: raise FailPage(message="Invalid submission received") try: # the hidden field should return a string from TABLECOL which # has index position equal to the row of the table row = TABLECOL.index(skicall.call_data['inputtable5','hidden_field1']) except: raise FailPage(message="Invalid submission received") pd = PageData() result = skicall.call_data['inputtable5','col_input'] submit1 = skicall.call_data.get(('inputtable5','button_text1')) submit2 = skicall.call_data.get(('inputtable5','button_text2')) if submit1: pd['result', 'para_text'] = f"Received: Row {row} {submit1} pressed - data: {result}" elif submit2: pd['result', 'para_text'] = f"Received: Row {row} {submit2} pressed - data: {result}" else: raise FailPage(message="Invalid submission received") if 2 < len(result) < 6 : pd['inputtable5','set_input_accepted'] = {row:True} pd['inputtable5','set_input_errored'] = {row:False} else: pd['inputtable5','set_input_accepted'] = {row:False} pd['inputtable5','set_input_errored'] = {row:True} skicall.update(pd)