The easiest way to do this would be to just swap out the entire HTML table. To do that, you can use a built in function in SHtml
that will memoize the initial transformation.
To do that, we'd give table
an ID like:
<table data-lift="CrudList" id="mytable">
Then in your snippet, you could do:
object CrudList {
object tableMemo extends RequestVar[Box[IdMemoizeTransform]](Empty)
def render = {
def remove(item: String) = () => {
ListDAO.remove(item)
tableMemo.get.foreach{ _.setHtml }
}
"#mytable" #> SHtml.idMemoize{ memo =>
tableMemo(memo)
ClearClearable &
"tr *" #> ListDAO.all.map(item => {
"role=data" #> item &
"role=remove" #> ajaxInvoke(remove(item))
})
}
}
def create = {
var text = ""
def process(): JsCmd = {
val item = ListDAO.create(text)
tableMemo.get.foreach{ _.setHtml }
}
"@text" #> SHtml.text(text, s => text = s) &
"button *+" #> SHtml.hidden(process)
}
}
Any call to tableMemo.get.foreach{ _.setHtml }
will reRender the table provided the first render took place and set the RequestVar
.
If you are looking to only reRender the affected rows, that gets a bit more challenging.
I would probably try something like this:
First, create a template with the HTML for a given row. In this example, we'll put it in templates-hidden/rowtemplate.html
. With the content:
<tr>
<td role="data">Item goes here</td>
<td><button role="remove" type="button">remove</button></td>
</tr>
Then, we'll modify the render to give each tr and retrieve the row from the template
val rowTemplate = Templates("templates-hidden" :: "rowtemplate" :: Nil) openOr <tr></tr>
def render = {
def remove(item: String) = () => {
ListDAO.remove(item)
JsCmds.Run("$('#' + item.id).remove()")
}
ClearClearable &
"tr" #> {
"tr" #> ListDAO.all.map(item => {
"* [id]" #> item.id &
"role=data" #> item &
"role=remove" #> ajaxInvoke(remove(item))
})
}.apply(rowTemplate)
}
Note: The first <tr>
above will bind to the TR in your html, the second will bind to the TR specified in the template.
def create = { var text = ""
def process(): JsCmd = {
val item = ListDAO.create(text)
val rowNS = {
"* [id]" #> item.id &
"role=data" #> item &
"role=remove" #> ajaxInvoke(remove(item))
}.apply(rowTemplate)
JsCmds.Run("tr:last").append(rowNS.toString)
}
"@text" #> SHtml.text(text, s => text = s) &
"button *+" #> SHtml.hidden(process)
}
I haven't tested that to make sure it all works, but hopefully will point you in the right direction.