I like the markup that eureka uses.
But there is a concern - and I am wondering how I get round it
Consider
form +++ Section()
<<< TextRow(){ row in
row.title = "Username"
row.tag = "username"
row.placeholder = "Login Email"
}
<<< PasswordRow(){ row in
row.title = "Password"
row.tag = "password"
row.placeholder = "Password"
}
now imagine you MUST have a object that returns there (I am looping inside json meta data).. how do you go about it?
(Pseudo code - consider these 2 code sampled do the EXACT same job and need to be identical)
let someFormEngine = someEurekaFormEngine() //doesn't exist yet this is the question
let nodes = GetJsonNodes() //returns two items in an array
EG: nodes = [(type: 'TextRow', name: 'username'),(type: 'PasswordRow', name: 'password')]
form +++ Section()
for node in nodes {
if (node.type=='TextRow'){
someFormEngine.DisplayTextRow(node.name)
}
if (node.type=='PasswordRow'){
someFormEngine.DisplayPasswordRow(node.name)
}
}
So it is certainly possible to dynamically and programmatically create a form that has rows and sections within it that are driven by a configuration file. I do that myself in an app I created.
However, you are going to have to create your own json meta-data format, and use a switch statement to dynamically add specific row types and configure them properly. Eureka does not have a mechanism that "serializes" a form's configuration meta-data for storage in say json, then deserialize it from that json meta-data. But you can do like I did and create your own "deserializer", looping though some json meta-data creating Rows and Sections and configuring their necessary parameters.
To adapt your own sample code:
let section = Section()
form +++ section
for node in nodes {
switch node.type {
case 'TextRow':
section <<< makeTextRow(node: node)
case 'PasswordRow':
section <<< makePasswordRow(node: node)
:
:
default:
}
:
:
func makeTextRow(node:Node) -> TextRow {
return TextRow() {
$0.tag = node.tag
$0.title = node.title
$0.placeholder = node.placeholder
:
:
}
}
Of course, you could just make a makeRow(node:Node) function and move the switch statement into that one master function, then the loop has just section <<< makeRow(node: node)
in it. There are many possible design patterns you can use.
Note too that you can use a .cellUpdate { cell, row in
to further dynamically customize a dynamic row based upon additional metadata in your Node class. For example, in my app I have defined a dynamic row type "Hexadecimal"; Eureka currently does not have a HexadecimalRow; but I have various custom keyboards one of which is a hexadecimal keypad which I just assigned to a TextRow.
Or you could assign different rules again based upon metadata in your Node class. Really you can create all sorts of dynamic fields that do not currently exist as specific Row types in Eureka.
I have also used programmatic loops to create a series of say TextAreaRow that allows the end-user to enter the name of their organization in various languages. The quantity and ordering of those languages is not known in advance, hence a loop is used rather than a "waterfall" of a fixed quantity of TextAreaRows.
So certainly, although all the Eureka examples show simple "waterfall" form definitions, using loops to create dynamic form rows and sections based upon database or json contents is highly useful.