This page explains each component in more details.
There are 4 different field constructors you can use. You only need to declare any of them implicitly on top of your template. Then every input will take it by default. All of them extend the b3.B3FieldConstructor class.
b3.B3FieldConstructor
@implicitFieldConstructor = @{ b3.vertical.fieldConstructor }
Or simply:
@import b3.vertical.fieldConstructor
This will let you render form-group's like this:
form-group
<div class="form-group" id="foo_field"> <label class="control-label" for="foo">A simple text</label> <input type="text" id="foo" name="foo" value="" aria-describedby="foo_info_0" class="form-control" placeholder="A simple text showing a help..."> <span id="foo_info_0" class="help-block">This is a help text</span> </div>
You have to specify its column widths for the form-group.
@implicitFieldConstructor = @{ b3.horizontal.fieldConstructor("col-md-2", "col-md-10") }
<div class="form-group" id="foo_field"> <label class="control-label col-md-2" for="foo">A simple text</label> <div class="col-md-10"> <input type="text" id="foo" name="foo" value="" aria-describedby="foo_info_0" class="form-control" placeholder="A simple text showing a help..."> <span id="foo_info_0" class="help-block">This is a help text</span> </div> </div>
@implicitFieldConstructor = @{ b3.inline.fieldConstructor }
Or:
@import b3.inline.fieldConstructor
<div class="form-group" id="foo_field"> <label class="control-label sr-only" for="foo">A simple text</label> <input type="text" id="foo" name="foo" value="" aria-describedby="foo_info_0" class="form-control" placeholder="A simple text showing a help..."> <span id="foo_info_0" class="help-block">This is a help text</span> </div>
This field constructor renders the input helpers directly. It is useful for those cases you need the input without its corresponding form-group. However, although it is used for specific cases, you can also declare it as the default field constructor within a template.
@import b3.clear.fieldConstructor
There are also 4 extra field constructors reserved to use for specify them instead of the default one. In short, these field constructors are equivalent to the previous ones but they are preferred when an implicit field constructor is needed. See the section Forms with a specific B3FieldConstructor for more details.
b3.vertical.fieldConstructorSpecific b3.horizontal.fieldConstructorSpecific("col-md-2", "col-md-10") b3.inline.fieldConstructorSpecific b3.clear.fieldConstructorSpecific
args
For every component there is a list of arguments you can add and they will be put within the corresponding input tag as normal HTML. However it will only happen with those arguments without a prefixed underscore (_). The underscored arguments are used to complement the corresponding form-group or to parameterize its behaviour.
For example, the following component has the argument placeholder that will be added to the input text tag. The _label argument set the label for the form-group and the _showConstraints one specifies if the constraints should be shown.
placeholder
_label
_showConstraints
@b3.text( fooForm("foo"), '_label -> "Constraints", '_showConstraints -> true, 'placeholder -> "A simple text showing its constraints..." )
The previous example outputs the HTML:
<div class="form-group" id="foo_field"> <label class="control-label" for="foo">Constraints</label> <input type="text" id="foo" name="foo" value="" class="form-control" placeholder="A simple text showing its constraints..."> <span class="help-block">Maximum length: 10</span> </div>
As we see before, there are some special arguments that are reserved to parameterize the corresponding form-group's behaviour. All of these special arguments are prefixed with an underscore (_). And the list is:
_id
_class
_hideLabel
sr-only
_hiddenLabel
_help
_success
Boolean
Any
_warning
_error
Option[play.api.data.FormError]
_showErrors
_showIconOnError
_showIconWarning
_showIconValid
Note there are 3 arguments for rendering the label for each field: '_label, '_hideLabel and '_hiddenLabel. Screen readers will have trouble with your forms if you don't include a label for every input. So you should always add a label even if you don't want it to be displayed. That's the reason for hiding the label. Let's see when to use each case with some examples:
'_label
'_hideLabel
'_hiddenLabel
@b3.text( fooForm("foo"), '_label -> "Input Text", 'placeholder -> "A simple text..." )
@import b3.inline.fieldConstructor @b3.text( fooForm("foo"), '_hiddenLabel -> "Input Text", 'placeholder -> "A simple text..." )
// checkbox and radio without label @b3.checkbox( fooForm("foo"), '_text -> "Checkbox", 'checked -> true ) @b3.radio( fooForm("foo"), options = Seq("M"->"Male","F"->"Female") )
If a field has validation constraints they will be added automatically as HTML5 data form validation (please visit this web to learn more and check wufoo for more examples and browser compatibility).
Then, the following constraints are automatically represented in HTML with these corresponding attributes:
nonEmpty
nonEmptyText
required="true"
minLength
minlength="N"
maxLength
maxlength="N"
min
min="N"
max
max="N"
pattern
pattern="XXX"
Remember you have also the specific b3.email, b3.url and b3.number helpers for the corresponding validations.
b3.email
b3.url
b3.number
For example, if you have this form
val validationForm = Form(tuple( "username" -> nonEmptyText(maxLength = 20), "email" -> email, "age" -> number(min = 18, max = 99), "color" -> nonEmptyText.verifying(pattern("^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$".r)) ))
and this CSS
input:valid { color: green; } input:invalid { color: red; }
The constraints will be automatically added as you can see here:
@b3.text( validationForm("username"), '_label -> "Username", '_help -> "A username between 1 and 20 characters" ) @b3.email( validationForm("email"), '_label -> "Email" ) @b3.number( validationForm("age"), '_label -> "Age", '_help -> "From 18 to 99 years old" ) @b3.text( validationForm("color"), '_label -> "Hexadecimal color", '_help -> "Format is #CCC or #CCCCCC" )
In some cases, you may need to add an argument only if a condition happens. In this situation you can simply use an Option value and it will be omitted if it is not defined (i.e. None).
Option
None
'foo -> Some("foo-value") // foo="foo-value" 'foo -> None // (this argument is omitted) 'foo -> maybeValue(...) // foo="result-value" or it's ommited
The boolean arguments are simply that, booleans. Let's see an example for the disabled attribute. Look all of these different codes:
disabled
<input type="text" name="foo" disabled> <input type="text" name="foo" disabled="true"> <input type="text" name="foo" disabled="false"> <input type="text" name="foo" disabled="blah">
And all of them are equivalents... But don't worry, every false argument will be automatically removed. So you can feel free to do something like:
false
@b3.text( fooForm("foo"), '_label -> "A maybe disabled text", 'disabled -> maybeTrueFunction(...) )
And what happens if you need to set a "false" value to an attribute? Ok, you can simply convert it to a string:
"false"
@b3.text( fooForm("foo"), '_label -> "With a false attribute", 'fooAttr -> "false" ) @b3.text( fooForm("foo"), '_label -> "With a boolean attribute", 'fooAttr -> maybeTrueFunction(...).toString )
Note only regular arguments with false value are removed. It doesn't happen with the special ones (i.e. the underscored ones).
data-*
You always add any argument to helpers using tuples of (Symbol, Any), like 'class -> "foo-class". However, when you need to add an argument with dashes you cannot declare the symbol as 'data-attr. So to get this you have different solutions:
(Symbol, Any)
'class -> "foo-class"
'data-attr
Symbol("data-attr") -> "data-value"
views.html.helper.Implicits.toAttributePair
@import helper.Implicits._
"data-attr" -> "data-value"
The WAI-ARIA attributes are a very helpful tool for accesibility. However we know it could be difficult and boring to integrate it everywhere within your web. Because of that, the library will do automatically for you for any field constructor.
@b3.text( fooForm("text"), '_label -> "A text", '_help -> "Something helpful" )
And it will render the following if there is an error:
<div class="form-group has-error has-feedback" id="text_field"> <label class="control-label" for="text">A text</label> <input type="text" id="text" name="text" value="" aria-describedby="text_info_0 text_error_0" aria-invalid="true" class="form-control"> <span id="text_error_0" class="help-block">This field is required</span> <span id="text_info_0" class="help-block">Something helpful</span> </div>
Note the library adds automatically for you:
span
id
'_help
'_showConstraints
aria-describedby
aria-invalid
The b3.form takes a Call object and a list of arguments. The implicit B3FieldConstructor argument is used to know which class is needed. Each B3FieldConstructor add its corresponding class:
b3.form
Call
B3FieldConstructor
HorizontalFieldConstructor:
class="form-horizontal"
InlineFieldConstructor:
class="form-inline"
VerticalFieldConstructor:
class="form-vertical"
ClearFieldConstructor:
class="form-clear"
The helper also adds the role="form" attribute by default.
role="form"
Every input helper will use the default B3FieldConstructor (the implicit one), unless you specify another. To do this you can use the form helper. There is one for each type of form. Here is an example of how to add an inline form within a view with a vertical form as default.
form
@import b3.vertical.fieldConstructor @b3.form(routes.Application.handleRequest) { // vertical form as default @b3.text( fooForm("foo"), '_label -> "Input Text" ) ... } @b3.inline.form(routes.Application.handleRequest) { implicit ifc => // an inline form @b3.text( fooForm("foo"), '_label -> "Input Text" ) ... }
There are 4 different options to insert each type of form. Note that there is also one for a clear B3FieldConstructor (it simply outputs the input helper without any more). So we have:
@b3.vertical.form(routes.Application.handleRequest) { implicit vfc => ... } @b3.horizontal.form(routes.Application.handleRequest, "col-md-2", "col-md-10") { implicit hfc => ... } @b3.inline.form(routes.Application.handleRequest) { implicit ifc => ... } @b3.clear.form(routes.Application.handleRequest) { implicit cfc => ... }
If you would need to specify a different B3FieldConstructor within a form, you can do:
@import b3.vertical.fieldConstructor @horizontalFC = @{ b3.horizontal.fieldConstructor("col-md-2", "col-md-10") } @b3.form(routes.Application.handleRequest) { // vertical form as default @b3.text( fooForm("foo"), '_label -> "Vertical input text" ) @b3.text( fooForm("bar"), '_label -> "Horizontal input text" )(horizontalFC, implicitly[Messages]) ... }
@import b3.vertical.fieldConstructor @b3.form(routes.Application.handleRequest) { // vertical form as default @b3.text( fooForm("foo"), '_label -> "Vertical input text" ) ... // an inline inner section @defining(b3.inline.fieldConstructorSpecific) { implicit ifc => @b3.text( fooForm("bar"), '_label -> "Inline input text" ) ... } ... }
But remember that horizontal and inline controls need to be inside their corresponding .form-horizontal and .form-inline to be rendered correctly. So you may need to wrap them with a div with these classes.
.form-horizontal
.form-inline
div
If you want to add automatically a CSRF token to a form, you can do it simply using the equivalent formCSRF. Be sure you implement your project correctly for CSRF support as it is explained at the Play's documentation.
formCSRF
@b3.formCSRF(...) { ... } @b3.vertical.formCSRF(...) { implicit vfc => ... } @b3.horizontal.formCSRF(...) { implicit hfc => ... } @b3.inline.formCSRF(...) { implicit ifc => ... } @b3.clear.formCSRF(...) { implicit cfc => ... }
It will simply add the helper @helper.CSRF.formField(token) within the form for you.
@helper.CSRF.formField(token)
readonly
Both the disabled and readonly attributes for an input prevent the user from modify it. However, the disabled attribute means this input will NOT be sent within the POST request, whereas the readonly one means it will.
Nevertheless, for checkbox, radio and select tags it doesn't happen. To support the readonly attribute for these tags, the corresponding helpers have been adapted to behave as would be expected. To do that, when the readonly attribute appears the helper will:
checkbox
radio
select
<input type="hidden">
checkbox-group
radio-group
select-group
You can see an example in the Readonly Demo.
You can set any validation state for a field with one of the following special arguments:
@b3.text( fooForm("foo"), '_label -> "Success", '_success -> true, 'placeholder -> "Success text..." ) @b3.text( fooForm("foo"), '_label -> "Warning", '_warning -> "Be carefull with this...", 'placeholder -> "Warning text..." ) @b3.text( fooForm("foo"), '_label -> "Error", '_error -> "An error occurred!", 'placeholder -> "Error text..." )
You can also add optional feedback icons with the addition of:
@b3.text( fooForm("foo"), '_label -> "Success", '_showIconValid -> true, 'placeholder -> "Success text..." ) @b3.text( fooForm("foo"), '_label -> "Warning", '_warning -> "Be carefull with this...", '_showIconWarning -> true, 'placeholder -> "Warning text..." ) @b3.text( fooForm("foo"), '_label -> "Error", '_showIconOnError -> true, '_error -> "An error occurred!", 'placeholder -> "Error text..." )
b3.inputType
It renders a simple input with a specific type attribute and it adds class="form-control" by default, but you can add an extra class with 'class -> "extra_class".
class="form-control"
'class -> "extra_class"
The argument 'placeholder is automatically internationalized.
'placeholder
@b3.inputType( "text", fooForm("name"), 'class -> "extra_class", '_label -> "Name", 'placeholder -> "John Doe" ) @b3.inputType( "email", fooForm("email"), '_label -> "Email", 'placeholder -> "example@mail.com" ) @b3.inputType( "password", fooForm("password"), '_label -> "Password", '_help -> "With at least 8 characters" )
b3.text
It is a short version of b3.inputType for type="text".
type="text"
@b3.text( fooForm("name"), '_label -> "Name", 'placeholder -> "John Doe" )
b3.password
It is a short version of b3.inputType for type="password".
type="password"
For security reasons, this helper doesn't display the possible value the field could have (for example when the form is reloaded after a validation failure).
@b3.password( fooForm("password"), '_label -> "Password", '_help -> "With at least 8 characters" )
b3.file
It is a short version of b3.inputType for type="file".
type="file"
@b3.file( fooForm("file"), '_label -> "File" ) @b3.file( fooForm("file"), '_label -> "File", 'class -> "form-control" )
b3.textarea
It renders a textarea and it adds class="form-control" by default.
@b3.textarea( fooForm("foo"), '_label -> "Textarea", 'rows -> 3 )
b3.checkbox
It renders a checkbox. It has the attribute value set to true by default, but you can use another one using the 'value argument.
value
'value
The special '_text argument lets you put a text after the checkbox. It is automatically internationalized.
'_text
Regarding to the checked attribute, if you want to set it to true as default, use '_default -> true. And if you need to force its value use directly the 'checked argument.
checked
'_default -> true
'checked
It supports readonly attribute adding an additional disabled one and a <input type="hidden">.
@b3.checkbox( fooForm("foo"), '_text -> "Remember me" ) // uses "bar" as value for the checkbox @b3.checkbox( fooForm("foo"), '_text -> "Remember me", 'value -> "bar" ) // checked by default (if the form is filled, this value will be taken) @b3.checkbox( fooForm("foo"), '_text -> "Remember me", '_default -> true ) // always checked (even if the form has been filled with a false) @b3.checkbox( fooForm("foo"), '_text -> "Remember me", 'checked -> true ) // disabled -> it will NOT be sent within the POST request @b3.checkbox( fooForm("foo"), '_text -> "Remember me", 'disabled -> true ) // readonly -> it will be sent within the POST request @b3.checkbox( fooForm("foo"), '_text -> "Remember me", 'readonly -> true )
Note you can use any value for the _text argument.
_text
@b3.checkbox( fooForm("foo"), '_text -> Html("Do you want a beer? <i class=\"fa fa-beer\"></i>") )
b3.radio
It renders a radio. It supports readonly attribute adding an additional disabled one and a <input type="hidden">.
It has an additional special _inline argument to make it an inline radio (for vertical and horizontal forms).
_inline
@opts = @{ Seq("M"->"Male","F"->"Female") } @b3.radio( fooForm("foo"), options = opts, '_label -> "Radio Group" ) // an inline radio within a vertical or horizontal form @b3.radio( fooForm("foo"), options = opts, '_label -> "Radio Group", '_inline -> true ) // with value "F" by default (if the form is filled, this value will be taken) @b3.radio( fooForm("foo"), options = opts, '_label -> "Radio Group", 'value -> "F" ) // disabled -> it will NOT be sent within the POST request @b3.radio( fooForm("foo"), options = opts, '_label -> "Radio Group", 'disabled -> true ) // readonly -> it will be sent within the POST request @b3.radio( fooForm("foo"), options = opts, '_label -> "Radio Group", 'readonly -> true )
Note you can use any value for the options argument. But they are automatically internationalized only for _String_ values.
options
@b3.radio( fooForm("foo"), options = Seq("B" -> Html("Beer <i class=\"fa fa-beer\"></i>"), "C" -> Html("Coffee <i class=\"fa fa-coffee\"></i>")), '_label -> "What do you prefer?" )
b3.radioOption
If you need more versatility you can fully customize your radio options:
@b3.radio( fooForm("foo3"), '_label -> "Ok, now that we're alone, what do you really prefer?" ) { implicit extraInfo => @b3.radioOption("B", Html("Beer <i class=\"fa fa-beer\"></i>")) @b3.radioOption("B", Html("Coffee <i class=\"fa fa-coffee\"></i>"), 'disabled -> true) }
Note you can use any value for the text argument. But it is automatically internationalized only for _String_ values.
text
b3.select
It renders a select. It supports readonly attribute adding an additional disabled one and a <input type="hidden">.
Note the value for each option argument is automatically internationalized.
option
@fruits = @{ Seq("A"->"Apples","P"->"Pears","B"->"Bananas") } @b3.select( fooForm("foo"), options = fruits, '_label -> "Select" ) // disabled -> it will NOT be sent within the POST request @b3.select( fooForm("foo"), options = fruits, '_label -> "Select", 'disabled -> true ) // readonly -> it will be sent within the POST request @b3.select( fooForm("foo"), options = fruits, '_label -> "Select", 'readonly -> true )
You can add a default first value using the argument '_default with a string. It will add a first option to the select with an empty string value. So you could add a required constraint to the field to force the user to select one other option. In addition, this default option is always disable to avoid the user to select it, and if any other option is selected this default one will not appear at all. Note it's automatically internationalized.
'_default
@b3.select( fooForm("foo"), options = fruits, '_label -> "Select", '_default -> "Select an option" ) @b3.select( fooForm("foo"), options = fruits, '_label -> "With default and Pears as value", '_default -> "Select an option", 'value -> "P" )
For a multiple select you only need to add the 'multiple argument. In that case, the '_default argument will be ignored.
multiple select
'multiple
@fruits = @{ Seq("A"->"Apples","P"->"Pears","B"->"Bananas") } @b3.select( fooForm("foo"), options = fruits, '_label -> "Fruits", 'multiple -> true ) // with value "A" and "B" by default // it is a string with every value separated by commas @b3.select( fooForm("foo"), options = fruits, '_label -> "Fruits", 'multiple -> true, 'value -> "A,B" )
b3.selectOption
If you need more versatility you can fully customize your select options:
@b3.select( fooForm("foo"), '_label -> "Grouped select" ) { implicit values => <optgroup label="Group 1"> @b3.selectOption("opt_1-1", "Option 1.1") @b3.selectOption("opt_1-2", "Option 1.2", 'disabled -> true) @b3.selectOption("opt_1-3", "Option 1.3") </optgroup> <optgroup label="Group 2"> @b3.selectOption("opt_2-1", "Option 2.1", 'disabled -> true) @b3.selectOption("opt_2-2", "Option 2.2") </optgroup> } class Fruit (id: Long, name: String, isCitrus: Boolean) @fruitsWithCitrus = @{ Seq( Fruit(1L, "Apple", false), Fruit(2L, "Orange", true), Fruit(3L, "Pear", false), Fruit(4L, "Lemon", true), Fruit(5L, "Banana", false) )} @b3.select( fooForm("foo"), '_label -> "Fruits select (lemon preselected)" ) { implicit values => <optgroup label="Citrus fruits"> @fruitsWithCitrus.filter(_.isCitrus).map { citrus => @b3.selectOption(citrus.id, citrus.name, 'selected -> (citrus.name == "Lemon")) } </optgroup> <optgroup label="Rest of fruits"> @fruitsWithCitrus.filterNot(_.isCitrus).map { fruit => @b3.selectOption(fruit.id, fruit.name) } </optgroup> }
Note the value for the name is automatically internationalized.
name
b3.hidden
It simply renders a hidden input.
@b3.hidden("fooName", "fooValue", 'fooAttr -> "fooAttrValue")
Renders to:
<input type="hidden" name="fooName" value="fooValue" fooAttr="fooAttrValue">
b3.hiddens
Render a list of hidden inputs.
@b3.hiddens("fooId" -> 1L, "barId" -> 2L)
<input type="hidden" name="fooId" value="1"> <input type="hidden" name="barId" value="2">
Important note: the new HTML5 input types are not fully supported for web browsers. Those not supported by old web browsers, will behave as input type text.
b3.color
It is a short version of b3.inputType for type="color".
type="color"
@b3.color( fooForm("color"), '_label -> "Color", 'value -> "#3264c8" )
b3.date
It is a short version of b3.inputType for type="date".
type="date"
@b3.date( fooForm("date"), '_label -> "Date" )
b3.datetime
It is a short version of b3.inputType for type="datetime".
type="datetime"
@b3.datetime( fooForm("datetime"), '_label -> "Datetime" )
b3.datetimeLocal
It is a short version of b3.inputType for type="datetime-local".
type="datetime-local"
@b3.datetimeLocal( fooForm("datetimeLocal"), '_label -> "Datetime-Local" )
It is a short version of b3.inputType for type="email".
type="email"
@b3.email( fooForm("email"), '_label -> "Email", 'placeholder -> "example@mail.com" )
b3.month
It is a short version of b3.inputType for type="month".
type="month"
@b3.month( fooForm("month"), '_label -> "Month" )
It is a short version of b3.inputType for type="number".
type="number"
@b3.number( fooForm("number"), '_label -> "Number", 'min -> 0, 'max -> 50, 'step -> 5 )
b3.range
It is a short version of b3.inputType for type="range".
type="range"
@b3.range( fooForm("range"), '_label -> "Range", 'min -> 0, 'max -> 50 )
b3.search
It is a short version of b3.inputType for type="search".
type="search"
@b3.search( fooForm("search"), '_label -> "Search" )
b3.tel
It is a short version of b3.inputType for type="tel".
type="tel"
@b3.tel( fooForm("tel"), '_label -> "Telephone" )
b3.time
It is a short version of b3.inputType for type="time".
type="time"
@b3.time( fooForm("time"), '_label -> "Time" )
It is a short version of b3.inputType for type="url".
type="url"
@b3.url( fooForm("url"), '_label -> "URL" )
b3.week
It is a short version of b3.inputType for type="week".
type="week"
@b3.week( fooForm("week"), '_label -> "Week" )
The following helpers use an auxiliar helper that creates a form-group without a field. Here are the special arguments they use:
b3.static
It renders a static control to place within your form. It takes a HTML as parameter, so you can render whatever you want. Actually, it is like a wrapper for a static HTML.
HTML
This is a link
@b3.static("Static HTML"){ <a href="#"><span class="glyphicon glyphicon-star"></span> This is a link</a> }
There are two equivalent more versions of b3.static helper: one for labels with HTML, and another one to omit the label. Note that you can also have a hidden label using '_hideLabel' argument.
'_hideLabel'
Basic control with label
Basic control with hidden label
Basic control without label
@b3.static(Html("Label with icon <i class=\"fa fa-beer\"></i>")){ <a href="#">Basic control with label</a> } @b3.static("Hidden label", '_hideLabel -> true){ <a href="#">Basic control with hidden label</a> } @b3.static(){ <a href="#">Basic control without label</a> }
b3.buttonType
It renders a simple button to place within your form. It takes a HTML as parameter, so you can render whatever you want.
@b3.buttonType("submit", 'class -> "btn btn-default"){ <span class="glyphicon glyphicon-ok"></span> Sign in }
b3.submit
It is a short version of b3.buttonType for type="submit".
@b3.submit('class -> "btn btn-primary"){ <span class="glyphicon glyphicon-ok"></span> Sign in }
b3.reset
It is a short version of b3.buttonType for type="reset".
@b3.reset('class -> "btn btn-danger"){ <span class="glyphicon glyphicon-remove"></span> Reset }
b3.button
It is a short version of b3.buttonType for type="button".
@b3.button('class -> "btn btn-default"){ <span class="glyphicon glyphicon-heart"></span> Favorite }
b3.free
It renders whatever you want within a form-group div.
@b3.free('_id -> "idFormGroup") { <button type="submit" class="btn btn-primary"> <span class="glyphicon glyphicon-ok"></span> Save changes</button> <a class="btn btn-default"> <span class="glyphicon glyphicon-remove"></span> Cancel</a> }
The purpose of these helpers is to be a tool for creating your own helpers. Please see more about creating new helpers here.
b3.inputWrapped
This is the same as b3.inputType but specifying a custom wrapper for the input tag. It is useful for input groups and inputs with validation states and feedback icons.
@b3.inputWrapped( "email", fooForm("email"), '_label -> "Email", 'placeholder -> "example@mail.com" ) { input => <div class="input-group"> <span class="input-group-addon">@@</span> @input <div class="input-group-btn"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">Action <span class="caret"></span></button> <ul class="dropdown-menu" role="menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </div><!-- /btn-group --> </div> }
b3.multifield
Sometimes you may need two or more fields within the same line in a horizontal or vertical form (for a set of checkboxes, a date range, ...).
The helper b3.multifield tries to:
To know how it works and how to use it go the the Multifield section.