Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow usage of custom tags defined in native js libraries #43

Closed
sb-minimal opened this issue Feb 21, 2017 · 11 comments
Closed

Allow usage of custom tags defined in native js libraries #43

sb-minimal opened this issue Feb 21, 2017 · 11 comments

Comments

@sb-minimal
Copy link

I read through the issues of custom tags but must admit, that i did not fully understand if it is possible to extend Binding.scala with custom tags.

Say OnsenUI defines a custom tag <ons-page>, how can i use this in Binding.scala?

I tried the following wrapper

package onsen

import com.thoughtworks.binding._
import Binding._
import org.scalajs.dom.document
import org.scalajs.dom.raw.Node

import scala.language.implicitConversions
import scala.scalajs.js
import scala.scalajs.js.annotation.JSName

case class OnsenBasicComponentBuilder(tagName: String) {

  def render = this

  var modifier: Binding[String] = _

  @dom def build = {
    val element=document.createElement(tagName)
    element.setAttribute("modifier",modifier.bind)
    element
  }
}

object Onsen {
  implicit def autoBinding[A](a: A): Binding[A] = ???

  implicit final class CustomTags(x: dom.Runtime.TagsAndTags2.type) {

    def OnsPage() = OnsenBasicComponentBuilder("ons-page")
    def OnsToolbar() = OnsenBasicComponentBuilder("ons-toolbar")
    def OnsToolbarButton() = OnsenBasicComponentBuilder("ons-toolbar-button")
    def OnsIcon() = OnsenBasicComponentBuilder("ons-icon")
    def OnsButton() = OnsenBasicComponentBuilder("ons-button")

  }

  implicit def toHtml(x: OnsenBasicComponentBuilder): BindingSeq[Node] = {
    Constants(x.build).mapBinding(identity)
  }
}

and use it as follows

import onsen.Onsen._
  @dom
  def page = {
    <div>
      <OnsPage><OnsToolbar></OnsToolbar></OnsPage>
    </div>
  }

getting

overloaded method constructor NodeSeqMountPoint with alternatives:
[error]   (parent: org.scalajs.dom.raw.Node,childBinding: com.thoughtworks.binding.Binding[org.scalajs.dom.raw.Node])com.thoughtworks.binding.dom.Runtime.NodeSeqMountPoint <and>
[error]   (parent: org.scalajs.dom.raw.Node,childBinding: com.thoughtworks.binding.Binding[com.thoughtworks.binding.Binding.BindingSeq[org.scalajs.dom.raw.Node]],dummy: Unit)com.thoughtworks.binding.dom.Runtime.NodeSeqMountPoint <and>
[error]   (parent: org.scalajs.dom.raw.Node,childrenBinding: com.thoughtworks.binding.Binding.BindingSeq[org.scalajs.dom.raw.Node])com.thoughtworks.binding.dom.Runtime.NodeSeqMountPoint
[error]  cannot be applied to (onsen.OnsenBasicComponentBuilder, com.thoughtworks.binding.Binding.BindingSeq[org.scalajs.dom.raw.Node])
[error]       <OnsPage><OnsToolbar></OnsToolbar></OnsPage>
[error]        ^
@Atry
Copy link
Collaborator

Atry commented Feb 22, 2017

I don't like tricks like this.
I would suggest you not to use custom tags like that. You should create simple custom functions instead.

@sb-minimal
Copy link
Author

Ok, but how do i get Binding.Scala to emit <ons-page><ons-toolbar></ons-toolbar></ons-page> even with a "simple custom function" ?

@Atry
Copy link
Collaborator

Atry commented Feb 22, 2017

Something like onsPage(onsToolbar())

@sb-minimal
Copy link
Author

sb-minimal commented Feb 22, 2017

Yes, but how to i implement onsPage? It somehow has to produce Binding.Scala compatible tags of the kind <ons-page> on the browser.
Obviously
@dom onsPage() = { <ons-page></ons-page> }
does not work.

@Atry
Copy link
Collaborator

Atry commented Feb 22, 2017

Let your onsPage function return a org.scalajs.dom.raw.Node or Binding[org.scalajs.dom.raw.Node]

@da-liii
Copy link

da-liii commented Feb 22, 2017

@sb-minimal
It seems <ons-page>${innerHTML}</ons-page> is not supported.
But <ons-page></ons-page> is supported.

see my https://github.com/sadhen/Binding-SemanticUI for example

@Atry
Copy link
Collaborator

Atry commented Feb 22, 2017

@sadhen , I guess @sb-minimal means custom HTML tags, which is not what you are talking about.

@sb-minimal
Copy link
Author

guess I am getting something completely wrong.
I tried:

  def onsPage(content: BindingSeq[Node]) = {
    val element=document.createElement("ons-page")
    content.map{ c =>
      element.appendChild(c)
    }
    element
  }


  def onsToolbar(content: Node) = {
    document.createElement("ons-toolbar")
  }

  val pageTitle: Var[String]=Var("Titel")

  @dom
  def app = {
    <div> {
      onsPage(Seq(
        onsToolbar(
          <div class="left">back</div>
          <div class="center">{ pageTitle.get } </div>
        ),
        <p>
          content
        </p>
      ))
      }
    </div>
  }

getting

type mismatch;
[error]  found   : com.thoughtworks.binding.Binding.BindingSeq[org.scalajs.dom.raw.Node]
[error]  required: org.scalajs.dom.raw.Node
[error]   @dom
[error]    ^
[error] one error found

Is document.createElement("ons-page") even the correct way to produce the org.scalajs.dom.raw.Node?
Would be very helpful if you could point me to some example code or could give a simple implementation for onsPage().

@Atry
Copy link
Collaborator

Atry commented Feb 22, 2017

You can use NodeSeqMountPoint at the moment. See https://scalafiddle.io/sf/gII6UlB/0

@Atry
Copy link
Collaborator

Atry commented Feb 22, 2017

However, I guess it would be good if we have a special syntax to disable tag name checking, like the data: prefix for attributes. https://github.com/ThoughtWorksInc/Binding.scala#custom-attributes

@Atry
Copy link
Collaborator

Atry commented Oct 21, 2018

Fixed in #110

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants