How to allow default value selection in a @select helper?
Asked Answered
J

3

8

In my form, I've defined a drop-down:

@select(
myForm("category_id"),
options(Category.options()),
'_label -> "Category",
'_default -> "-- Choose a Category --",
'_showConstraints -> false
)

in my controller code:

Form<Category> catForm = form(Category.class).bindFromRequest();
if(catForm.hasErrors()) {
return badRequest(categoryEdit.render(catForm));
}

The form submission does not allow me to select the default value and catForm.hasErrors() is true if I make no selection. Two questions:

  1. How do I allow default value to be selected in the dropdownlist?

  2. I want the default value to be -1, where to set it? (Maybe this is where the problem is, there is no value associated with -- Choose a Category -- option?)

Joyjoya answered 17/5, 2013 at 10:9 Comment(0)
A
3

aviks suggestion is working. Maybe you have not imported the template correctly. I did it like this. First I created a customSelectField.scala.html in views/helper/ as avik suggested:

@(field: play.api.data.Field, options: Seq[(String,String)], args: (Symbol,Any)*)(implicit handler: FieldConstructor, lang: play.api.i18n.Lang)

@getAsTuple(x : Any) = @{
    x match {
        case (value: String, text: String) => (value, text)
        case _ => ("-1", "Select")
    }
}

@input(field, args:_*) { (id, name, value, htmlArgs) =>
    <select id="@id" name="@name" @toHtmlArgs(htmlArgs)>


@args.toMap.get('_default).map { dv =>
    <option class="blank" value="@getAsTuple(dv)._1">@getAsTuple(dv)._2</option>
}

@options.map { v =>
    <option value="@v._1" @(if(value == Some(v._1)) "selected" else "")>@v._2</option>
}
</select>
}

and then in my template e.g index.scala.html where I want the select I do:

@import helper._ 

@helper.customSelectField(
 field = proposeNewTimeForm("selectTime"),
 options = times.get,
 '_label -> "Category",
 '_default -> ("-1" -> "-- Choose a category --"),
 '_showConstraints -> false
)

Remember you should NOT do:

@implicitField = @{
        FieldConstructor(helper.customSelectField.f)
    }

because this will cause your error.

If you would like to format the html surrounding the select somehow you could do as I with a customField.scala.html in views/helper/:

@(elements: helper.FieldElements)

@elements.input
<span class="errors">@elements.errors.mkString(", ")</span>
<span class="help">@elements.infos.mkString(", ")</span>

and then in the top of index.scala.html:

@import helper._
@implicitField = @{
    FieldConstructor(helper.customField.f)
}

Hope this helps!

Aerodrome answered 12/6, 2013 at 13:28 Comment(1)
Thanks Jakob,i'll try & get back if any further help is needed.Joyjoya
E
1

You could write an alternative to Play's HTML select helper that accepts a Tuple for the default option. This way you can specify both the underlying value and the text that should be displayed.

Here's a first effort, some of the Scala here is admittedly a little amateur:

app/views/_my_select.scala.html

@(field: play.api.data.Field, options: Seq[(String,String)], args: (Symbol,Any)*)(implicit handler: helper.FieldConstructor, lang: play.api.i18n.Lang)

@import helper.input

@getAsTuple(x : Any) = @{
  x match {
    case (value: String, text: String) => (value, text)
    case _ => ("-1", "Select")
  }
}

@input(field, args:_*) { (id, name, value, htmlArgs) =>
  <select id="@id" name="@name" @toHtmlArgs(htmlArgs)>

    @args.toMap.get('_default).map { dv =>
      <option class="blank" value="@getAsTuple(dv)._1">@getAsTuple(dv)._2</option>
    }

    @options.map { v =>
      <option value="@v._1" @(if(value == Some(v._1)) "selected" else "")>@v._2</option>
    }
  </select>
}

Usage

@_my_select(
  myForm("category_id"),
  options(Category.options()),
  '_label -> "Category", 
  '_default -> ("-1" -> "-- Choose a category --"),
  '_showConstraints -> false
)
Edenedens answered 17/5, 2013 at 21:55 Comment(1)
I am getting this error--> type mismatch; found : (play.api.data.Field, Seq[(String, String)], Array[(Symbol, Any)]) => play.api.templates.Html required: views.html.helper.FieldElements => play.api.templates.Html Note: implicit method implicitFieldConstructor is not applicable here because it comes after the application point and it lacks an explicit result typeJoyjoya
M
1

I had a similar problem and found a simpler solution.
Instead of Play! helpers try this inside of your form:

<select name="category_id">
    <option value="-1">-- Choose a Category --</option>
    @(for((key, value) <- Category.options()){
        <option value="@value"> @key </option>
    }
</select>
Mockheroic answered 18/1, 2014 at 22:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.