Difficulties defining custom attributes

213 views
Skip to first unread message

Richard Gomes

unread,
Jun 10, 2014, 9:24:50 PM6/10/14
to scal...@googlegroups.com
Hello,

I'm trying to define a tags which contains a custom attribute, aiming to implemente Dojo Toolkit on top of Scalatags.

<pre>
@JSExport
object ScalaJSExample {

  @JSExport
  def main(args: Array[String]): Unit = {
    val container = g.document.getElementById("container")
    container.innerHTML = render().toString()
  }

  private def render() =
    dijit.select(name := "select1")(
      option(value := "TN")("Tennessee"),
      option(value := "VA")("Virginia"),
      option(value := "WA")("Washington"),
      option(value := "FL")("Florida"),
      option(value := "CA")("California"))
}

object dijit {
  val select = "select".tag[dom.HTMLSelectElement].apply(
    dojo._type := "dijit/form/Select")
}
</pre>

Despite the code above works, it's not convenient.

I would like to move all logic and initialization of attributes to a class.
Then I would be able to define a simple tag which does not contain any logic.



Something like this below (which does not work!):


<pre>
@JSExport
object ScalaJSExample {

  @JSExport
  def main(args: Array[String]): Unit = {
    val container = g.document.getElementById("container")
    container.innerHTML = render().toString()
  }

  private def render() =
      dijit.select(name := "select1", foo := "indeed")(
        option(value := "TN")("Tennessee"),
        option(value := "VA")("Virginia"),
        option(value := "WA")("Washington"),
        option(value := "FL")("Florida"),
        option(value := "CA")("California"))
}


object dijit {
  val select = "select".tag[DijitSelectElement]
}

class DijitSelectElement extends dom.HTMLSelectElement {

  val `data-dojo-type` : String = "dijit/form/Select"

  var foo: String = ???
}
</pre>


The code above presents two issues:

1. The attribute "foo" is not recognized;

2. The attribute `data-dojo-type` is not applied to the object. I have tried other ways to inject the attribute onto the object, like using function "transforms", calling function update and other alternatives I found in the source code of Scalatags, but I was not able to make it work.


Thoughts?


-- Thanks

Richard Gomes

unread,
Jun 11, 2014, 9:01:48 PM6/11/14
to scal...@googlegroups.com
Ansering my own question.

I guess I managed to arrive to something which started to look nice.

See: https://github.com/frgomes/dejawu

------------------

package org.dejawu

import org.scalajs.dom
import scala.scalajs.{js => js}
import scala.scalajs.js.Dynamic.{ global => g }
import scala.scalajs.js.annotation.JSExport

import scala.collection.{SortedMap, mutable}

import scalatags.all._
import scalatags._

import dojo.`data-dojo-id`
import dojo.`data-dojo-props`



@JSExport
object ScalaJSExample {

  @JSExport
  def main(args: Array[String]): Unit = {
    val container = g.document.getElementById("container")
    container.innerHTML = render().toString()
  }

  private def render() =
    div(
      dojo.dijit.select(name := "select1")(

        option(value := "TN")("Tennessee"),
        option(value := "VA")("Virginia"),
        option(value := "WA")("Washington"),
        option(value := "FL")("Florida"),
        option(value := "CA")("California")),
      dojo.store.memory(
        `data-dojo-id`    := "stateStore",
        `data-dojo-props` := """data: [
                                    |{ id: 'EG', name:'Egypt'    },
                                    |{ id: 'KE', name:'Kenya'    },
                                    |{ id: 'SD', name:'Sudan'    },
                                    |{ id: 'CN', name:'China'    },
                                    |{ id: 'IN', name:'India'    },
                                    |{ id: 'RU', name:'Russia'   },
                                    |{ id: 'MN', name:'Mongolia' },
                                    |{ id: 'DE', name:'Germany'  },
                                    |{ id: 'FR', name:'France'   },
                                    |{ id: 'ES', name:'Spain'    },
                                    |{ id: 'IT', name:'Italy'    }
                                    |]""".stripMargin),
      dojo.dijit.combobox(
        name := "combobox1", value := "Egypt",
        `data-dojo-props` := "store:stateStore, searchAttr:'name'")
    )
}


object dojo {

  val `data-dojo-id`    : Attr = "data-dojo-id".attr
  val `data-dojo-type`  : Attr = "data-dojo-type".attr
  val `data-dojo-props` : Attr = "data-dojo-props".attr

  object dijit {
    val select   = "select".dtag[form.SelectElement]("dijit/form/Select")
    val combobox = "input".dtag[form.ComboBoxElement]("dijit/form/ComboBox")

    object form {
      class SelectElement extends dom.HTMLSelectElement
      class ComboBoxElement extends dom.HTMLSelectElement
    }
  }

  object store {
    val memory   = "div".dtag[MemoryElement]("dojo/store/Memory")

    class MemoryElement extends dom.HTMLDivElement
  }

  implicit class DojoConversions(s: String) {
    def dtag[T](dtype: String) = {
      if (!Escaping.validTag(s))
        throw new IllegalArgumentException(
          s"Illegal tag name: $s is not a valid XML tag name"
        )
      HtmlTag[T](s, Nil, SortedMap(`data-dojo-type`.name -> dtype))
    }
  }

}

Reply all
Reply to author
Forward
0 new messages