jducoeur / jsext

Commonly-useful extensions for Scala.js, particularly for facade development
28 stars 12 forks source link

How do you build nested options with JSOptionBuilder #13

Open nh13 opened 7 years ago

nh13 commented 7 years ago

For example the columns option in https://datatables.net/examples/api/row_details.html

@js.native
trait DataTableOptions extends js.Object
object DataTableOptions extends DataTableOptionsBuilder(noOpts)
class DataTableOptionsBuilder(val dict: OptMap)
  extends JSOptionBuilder[DataTableOptions, DataTableOptionsBuilder](new DataTableOptionsBuilder(_)) {
  def columns(obj: js.Array[js.Object]) = jsOpt("columns", obj)
}

@js.native
trait DataTableColumnOptions extends js.Object
object DataTableColumnOptions extends DataTableColumnOptionsBuilder(noOpts)
class DataTableColumnOptionsBuilder(val dict: OptMap)
extends JSOptionBuilder[DataTableColumnOptions, DataTableColumnOptionsBuilder](new DataTableColumnOptionsBuilder(_)) {
  def data(v: String) = jsOpt("data", v)
  def className(v: String) = jsOpt("className", v)
  def orderable(v: Boolean) = jsOpt("orderable", v)
  def defaultContent(v: String) = jsOpt("defaultContent", v)
}

but I don't know how to wire them together. Thanks for any help.

jducoeur commented 7 years ago

I don't understand -- why don't you just give the type of columns as js.Array[DataTableColumnOptions]?

nh13 commented 7 years ago

I didn't understand, thank-you.

nh13 commented 7 years ago

It looks like I am missing something again, and thank-you in advance for all your help. If I can get this right I can make a facade for JQuery's DataTables, with all of its options! Below is my source, and also a screenshot of where the code crashes in datatables.js.

screen shot 2017-07-01 at 7 09 30 am
@js.native
trait JQueryDataTable extends js.Object {
  def rows(): JQueryDataTableRow = js.native
  def draw(): JQueryDataTableRow = js.native
}

@js.native
trait JQueryDataTableRow extends js.Object {
  def invalidate(): JQueryDataTable = js.native
}

@js.native
trait JQueryDataTableFacade extends js.Object {
  def DataTable(options: DataTableOptions): JQueryDataTable = js.native
}

object JQueryDataTableFacade {
  implicit def jq2DataTable(jq: JQuery): JQueryDataTableFacade = jq.asInstanceOf[JQueryDataTableFacade]
  implicit def element2dataTableElement(e: dom.Element): JQueryDataTableFacade = e.asInstanceOf[JQueryDataTableFacade]
}

@js.native
trait DataTableOptions extends js.Object
object DataTableOptions extends DataTableOptionsBuilder(noOpts)
class DataTableOptionsBuilder(val dict: OptMap)
  extends JSOptionBuilder[DataTableOptions, DataTableOptionsBuilder](new DataTableOptionsBuilder(_)) {
  def columns(options: js.Array[DataTableColumnOptionsBuilder]) = jsOpt("columns", options)
  def destroy(b: Boolean) = jsOpt("destroy", b)
}

@js.native
trait DataTableColumnOptions extends js.Object
object DataTableColumnOptions extends DataTableColumnOptionsBuilder(noOpts)
class DataTableColumnOptionsBuilder(val dict: OptMap)
extends JSOptionBuilder[DataTableColumnOptions, DataTableColumnOptionsBuilder](new DataTableColumnOptionsBuilder(_)) {
  def data(v: String)           = jsOpt("data", v)
  def className(v: String)      = jsOpt("className", v)
  def orderable(v: Boolean)     = jsOpt("orderable", v)
  def defaultContent(v: String) = jsOpt("defaultContent", v)
}

...
jQuery(() =>
      val taskTableIds   = Seq("", "name", "id", "status", "description", "attempts", "last", "script", "log", "depends_on", "dependents", "parent", "children")

      // Construct the DataTable for the tasks
      val taskDataTable = {
        import JQueryDataTableFacade._
        val dataTableColumns = taskTableIds.map { id => DataTableColumnOptions.data(id) }
        val dataTableOptions = DataTableOptions.destroy(true).columns(js.Array(dataTableColumns:_*)) //DataTableOptions.columns(js.Array(dataTableColumns:_*)).destroy(true)
        jQuery("#tasks").DataTable(dataTableOptions)
      }
    )