0
votes

With a play view template I know I can convert a Scala List into a javascript Array e.g. for example.scala.html:

@(list: List[Any])

@import play.api.libs.json.Json

<script type="text/javascript">
    $(document).ready(function () {
        var jsArr = @Json.toJson(list);
        console.log(jsArr);
    });
</script>

but how does one go back the other way, converting a javascript array into a scala list to pass on to a controller?

I have template code (test.scala.html) like this:

@(selected: List[String])

@main("Test Scripts Page") {

    <div class="page-header page-heading">
        <h1 class="pull-left">Test Scripts Page</h1>
        @helper.form(action = helper.CSRF(routes.DoSomething.create(selected))) {
        <input type="submit" class="btn btn-primary pull-right" value="Done >"> }
        <div class="clearfix"></div>
        <p class="lead text-left">Choose Buttons</p>
    </div>

    @for(index <- 0 to 3) {
    <div class="btn-group" data-toggle="buttons">
        <label class="btn btn-primary"><input type="checkbox" name="options" id="option-@index" aria-pressed="false" autocomplete="off" checked>option @index</label>
    </div> <!-- buttons --> }

    <input type="text" id="buttonvalue"/>

    <script>
        $(window).unload(function() {
            var jsArray = []
            $('.btn-group checkbox:selected').each(function() {
                jsArray.push($(this).attr("id"));
            });
            selected = Json.fromJson(jsArray, String);    
            $("#buttonvalue").val(selected.text());
        });
    </script>
}

Which doesn't seem to be working... only returns an empty list [] to my DoSomething(List) controller... basically I'm trying to let the user set the state of some widgets (in my case a bootstrap button-grp, with the ids of the buttons being object ids of static reference data in my database) and then read that selection back into my DoSomething controller as a List of ids when they hit a "done" button. Can anyone offer some advice on what I've missed here or a better way to handle this situation?

2

2 Answers

0
votes

When you load a page, this happens: Your browser asks the server for a HTML page. Your scala code is run on the server and generates a HTML page with some javascript on it.

The server sends the HTML page to the browser. The javascript code then runs in the browser and therefore can't talk to the server code (Scala).

To send data back to the server you can make an HTTP call e.g. to a REST endpoint that your server offers.

0
votes

Ok. I have a solution for this.

My view template looks like this, with the Bootstrap button-grp tagged with "myButtons" (note: if you insert anything between the btn-group div and the label class buttons, JQuery doesn't seem to pick up the checked options), and an script with ajax call bound to the submitButton.

Test Scripts Page "> Choose Buttons

 <div id="myButtons" class="btn-group" data-toggle="buttons">
    <label class="btn btn-primary active">
        <input type="checkbox" name="options" id="option1" autocomplete="off" checked> Box 1 (preselected)
    </label>
    <label class="btn btn-primary">
        <input type="checkbox" name="options" id="option2" autocomplete="off"> Box 2
    </label>
    <label class="btn btn-primary">
        <input type="checkbox" name="options" id="option3" autocomplete="off"> Box 3
    </label>
</div>


<script>
    $('#submitButton').click(function(e) {
        var selected = $( "#myButtons :checked" ).map(function() {
            return this.id;
        }).get().join();
        var selections = JSON.stringify({ 'selected' : selected });
        $.ajax({
            type :  "POST",
            dataType: 'json',
            data: selections,
            contentType: "application/json; charset=utf-8",
            url  :  "@routes.Application.getSelection()",
            success: function(data) {
                console.log(data);
            }
        });
        return false;
    });
</script>

my controller then picks up the selection via the AJAX post thus:

public static Result getSelection() 
    {
        JsonNode json = request().body().asJson();

        if( json == null)
        {
            Logger.info("Expecting JSON!");
            return badRequest("Expecting Json data!");
        }
        else
        {
            String selection = json.findPath("selected").textValue();
            if (selection == null)
            {
                Logger.info("Missing Parameter: selected");
                return badRequest("Missing Parameter: selected");
            }
            else
            {
                Logger.info("selection = " + selection);
                String[] ids = selection.split(",");
            }
        }
        return ok(modaltest.render());
    }

in my application code, those selections map to object ids in a model stored in my database, and then can be re-used in a subsequent request.

The only issue now is that the final return Request of my getSelection() controller (i.e. another GET to render a new page with a form) doesn't get invoked. No idea why yet. Probably something to do with the Ajax POST.