Skip to content
Anjunar/ DOCS

A form from a descriptor

The writable properties of a case class become input fields, their accessors bind them to an instance. The form below is built that way in your browser.

Live

Generated, bound, typed

Change a field: the accessor writes the instance, and the line below reads it back. The age field only accepts numbers because the property type says scala.Int.

Profile form

Three vars, three fields, no field written by hand.

profile
Profile(Ada,[email protected],36)
scala
case class Profile(var name: String, var email: String, var age: Int) val descriptor = ReflectMacros.reflectWithAccessors[Profile] descriptor.getWriteableProperties.foreach { property => val accessor = property.accessor.get val numeric = property.propertyType.typeName == "scala.Int" textField(property.name, accessor.get(profile).toString, numeric) { value => accessor.set(profile, if numeric then value.toIntOption.getOrElse(0) else value) } }
Why it works in the browser

No runtime reflection involved

Scala.js has no java.lang.reflect. The descriptor and its accessors were generated at compile time, so the form is ordinary code that happens to be written by a macro.

Extending the recipe
Read a @Label annotation for the field caption instead of the property name.
Choose the input by propertyType: a checkbox for scala.Boolean, a date field for java.time.LocalDate.
Validate before set, and keep the previous value when a conversion fails.
Use getReadableProperties for a read-only detail view of the same class.