I am not sure if I phrased the question in the title correctly but here is the situation.. I need to create a dynamic table with heist when table fields (schema) are only available at run time. So usually, when the schema is known at compile, I would do something like this:
<table>
<row-splice>
<tr>
<td> <field1/> </td>
<td> <field2/> </td>
<td> <field3/> </td>
</tr>
</row-splice>
</table>
That is when I know the number of fields and their names at compile time. I understand how to process all that in the handler with 'runChildrenWith', 'mapSplices' and so on ...
Now I am in a situation when the number of fields and schema are available only at run time. So the heist template, as I understand it, would look like this:
<table>
<row-splice>
<tr>
<field-splice>
<td> <field/> </td>
</field-splice>
</tr>
</row-splice>
</table>
I am really stuck with how to implement it within the handler. I assume I would need to do 'mapSplices' twice - one inside the other, correct? So, empirically speaking, that would be an inner and outer loop/map, right?
How would I do this within handler??
Thanks.
Update:
Forgot to mention that schema can be retrieved at run time from the DB and available as:
Table { tableName :: Text
, tableFields :: [Text]
}
But it is not really needed as data comes from schema-less mongodb and converted to Map:
fromList [("FieldName1","Value1"),("FieldName2","Value2"),("FieldName3","Value3")]
Update2:
I tried suggested examples with no luck I just get all my data in a single column. All I need is a simple inner and outer loop to generate fields and rows dynamically. It cannot be simpler then this:
<% @rows.each do |row| %>
<tr>
<% row.each do |field| %>
<td> <%= field %> </td>
<% end %>
</tr>
<% end %>
Update3:
I finally cracked it after a long weekend rest ... Here is the example. it is mongodb specific and I literally just copied and pasted it. But if someone gets stuck with inner/outer loops it would be helpful, I suppose.
showTableH :: AppHandler ()
showTableH = do
table <- liftIO $ fetchTable tname
docs <- liftIO $ getColList tname
let rowSplice doc = mapSplices (\f -> fieldSplice $ T.pack $ at f doc) (tableFields table)
where fieldSplice field = runChildrenWithText [("field", field)]
let listRowsSplice = mapSplices (\d -> runChildrenWith [("fields", rowSplice d)]) docs
heistLocal (bindSplices [("rows", listRowsSplice)]) $ render "show-table"
I think the key here is using mapSplices along with runChildrenWith. I think it would look something like this:
rowSplice = do
rows <- lift getRowsFromDB
mapSplices (\row -> runChildrenWith [("field-splice", fieldSplice row)]) rows
fieldSplice rowId = do
fields <- lift $ getFieldsFromDB rowId
mapSplices (\f -> runChildrenWith [("field", fieldToText f)]) fields
来源:https://stackoverflow.com/questions/13743000/snap-inner-outer-loops-with-heist