Search code examples
scalacrudlift

Liftweb CRUD : How to get edited content in an HTML table an return it to lift?


I have a lift code that render an HTML table with some cells with editable content.

For editing I'm using editinplace.js

<script src="/js/jquery.editinplace.js"></script> 

I set the editable attribute in lift rendering the table:

def renderTable(columns: List[(String,List[Model])]) = {
          {val entityCountMax = columns.maxBy(_._2.size)
           for(i <- 0 until entityCountMax._2.size) yield {
            <table style="font-size:80%; float: left; margin-left: 30px; width: auto;" class="table table-striped table-condensed table-hover">
                <tr>{ <th> { prettifyClassName(entityCountMax._2(i))} </th> % Attribute(None, "colspan", Text((columns.size+1).toString), Null)}</tr>
                {renderHeader(columns.map(_._1))}
            {for((key,value) <- entityCountMax._2(i).fields) yield {
            <tr>
            <th style="text-align: right;">{key}</th>
            {for(j <- 0 until columns.size) yield {
              <td>{try{
                            printField(columns(j)._2(i).fields.get(key))
                  }catch { case e:Exception => ""}
             }</td> % Attribute(None, "class", Text({ if(columns(j)._1 contains "DB") "editable" else "" }), Null)
            }}
            </tr>
        }}
        </table> 
         }} ++
          <script><![CDATA[ 
            $(document).ready(function(){
            $('.editable').editInPlace({ callback: function(unused, enteredText){ 
            $(this).css('color','red'); return enteredText;},
            default_text: ''
            })});]]>
          </script>
        } 

Don't look too much at rendering function above, it's working fine and I can edit the wanted cells with no problems. Edited cells are colored in red.

What I want to do now is to get the content of edited cells and return it to my scala application but I have no idea how to do it.

What I was thinking to do is to build a DIY lift CRUD for my model. The problem is that this way (I'm guessing) I have to make an html page to edit every cells one-by-one but I don't like this solution very much.

So here comes the real question:

Is it possible to directly map the html table with my data structure in scala? And If it is, how can I do it?


Solution

  • If you are just looking to directly map a variable to the server, and have changes sent automatically - Lift provides a wiring mechanism, which will send updates as they happen back to the server as well as update any dependent data. You'd still need to handle the event to persist any changes. Also, I am not sure how well it will work with the mechanism you have created.

    I know you are using an external library, but out of the box Lift offers SHtml.swappable which can provide you with a mechanism for toggling between an editable state and a non-editable state. When used in combination with an ajaxText box, will provide you with a way of editing data in place, ie:

    var name="myname"
    SHtml.swappable(
      <span>{name}</span>, 
      SHtml.ajaxText(name, (v) => name = v)
    )
    

    If you are just generating a NodeSeq and want to return that to the browser processed by Lift, you can take a look at LiftSession.processSurroundAndInclude

    I find Lift's functions work best if you use their CSS Selectors and response processing. However, if you are creating the forms using Javascript, and your library is responsible for managing the data, you'd probably be better off using a Rest type service to get the data back into your app. RestHelper makes that pretty easy. I've used it often with AngularJS for doing a similar type app to what it sounds like you are trying for.