Julian Pieles
Julian Pieles

Reputation: 3996

Scala JS: Call a Javascript function on an element

I have the following problem. I would like to use https://github.com/aehlke/tag-it/ in my project. However I am not sure how I am supposed to implement the following example given on the github page:

<script type="text/javascript">
$(document).ready(function() {
 $("#myTags").tagit();
});
</script>

<ul id="myTags">
 <!-- Existing list items will be pre-added to the tags -->
 <li>Tag1</li>
 <li>Tag2</li>
</ul>

So far I am able to manipulate the object:

val document = js.Dynamic.global.document
document.getElementById("myTags").innerHTML = "Test"

This works! Test is being rendered.

When I call tagit() instead I am being told that tagit is not a function.

val document = js.Dynamic.global.document
document.getElementById("myTags").tagit()

When I do the "same" call with the chrome java script console everything works fine:

$("#myTags").tagit();

Can someone explain what I am doing wrong? Thank you in advance!

EDIT

It is not a problem of tag-it or jquery not being loaded. Again chrome console works. It is also not a loading issue. Even by clicking a button after everything is loaded for a 100% it doesn't work.

EDIT

Added my partial build defintion so everybody can see that the dependencies are correct:

.jsSettings(
      jsDependencies ++= Seq(
        "org.webjars" % "bootswatch-yeti" % "3.3.5" / "js/bootstrap.js" minified "js/bootstrap.min.js" dependsOn "jquery.js",
        "org.webjars" % "jquery-ui" % "1.11.4" / "jquery-ui.js" minified "jquery-ui.min.js" dependsOn "jquery.js",
        "org.webjars" % "tag-it" % "2.0" / "js/tag-it.js" dependsOn "jquery.js" dependsOn "jquery-ui.js"
      ),
      libraryDependencies ++= Seq(
        "io.github.widok" %%% "widok" % "0.2.2" exclude ("org.webjars", "bootstrap"),
        "be.doeraene" %%% "scalajs-jquery" % "0.8.0",
        "com.lihaoyi" %%% "scalatags" % "0.4.6",
        "org.webjars" % "bootswatch-yeti" % "3.3.5",
        "org.webjars" % "font-awesome" % "4.4.0",
        "org.webjars" % "jquery-ui-themes" % "1.11.4"
      ),
      persistLauncher := true
    )

Upvotes: 2

Views: 1906

Answers (3)

Julian Pieles
Julian Pieles

Reputation: 3996

I found a solution which works. It uses jQuery bindings for Scala JS. By building your own static bindings is the correct way I guess.

jQuery("#myTags").asInstanceOf[js.Dynamic].tagit()

UPDATE

Please see the following post (https://stackoverflow.com/a/32994303/1029251) since this approach is simply wrong considering what scala.js stands for. My solution is not typesafe!

Upvotes: 0

sjrd
sjrd

Reputation: 22085

Your problem, initially, is that

// Scala.js code
document.getElementById("myTags").tagit()

is not "the same" as

// JavaScript code
$("#myTags").tagit();

Instead, it is the same as, guess what?

// JavaScript code
document.getElementById("myTags").tagit();

which is not valid because tagit() is not a method of HTMLElement returned by getElementById. tagit() is a (pimped) method of JQuery objects returned by the $ function.

You can obtain the $ function in a dynamically typed way using:

// Scala.js code
val $ = js.Dynamic.global.$

and then you can write the same as the jQuery invocation by writing this:

// Scala.js code
$("#myTags").tagit()

The solution found is essentially similar, because the jQuery object is equivalent as $. But then the returned element is a JQuery object, which statically does not have a tagit() method, which is why you needed to cast it to js.Dynamic.

Another way would be to type the tagit() method pimp using this:

// Scala.js code
@js.native
trait JQueryTagIt extends js.Object {
  def tagit(): Unit = js.native
}

implicit def tagItExtensions(jq: JQuery): JQueryTagIt =
  jq.asInstanceOf[JQueryTagIt]

With that, you can more simply do:

// Scala.js code
jQuery("#myTags").tagit()

and it will be statically typechecked.

Upvotes: 6

Omidam81
Omidam81

Reputation: 1917

$(document).ready(function(){
  $("#myTags").tagit();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="http://bitar.tk/tag-it.min.js"></script>

<ul id="myTags">
 <!-- Existing list items will be pre-added to the tags -->
 <li>Tag1</li>
 <li>Tag2</li>
</ul>

Upvotes: 0

Related Questions