4

I am trying to make calls to the jquery-ui from scala.js. I have tried modifying the way the jquery library is implemented but without success so far. So I have defined the following trait and package object:

trait JQueryUI extends js.Object {

    def apply(selector: String): JQueryUI = ???
    val buttonset: js.Any = ???
}

package object jqueryui extends js.GlobalScope {
    val jQueryUI: JQueryUI = ???
}

And then added a JSApp as follows:

object JQueryUIApp extends JSApp {
    def main(): Unit = {
        jqueryui.jQueryUI("#sports").buttonset
    }   
}

But on my JavaScript console I get the following error:

TypeError: ScalaJS.g["jQueryUI"] is not a function (0, ScalaJS.g["jQueryUI"])("#sports")["buttonset"]

Can someone tell me what I am missing?

1 Answer 1

5

By declaring the val jQueryUI like that in your package object, you tell the Scala.js that this corresponds to a global variable in JavaScript named jQueryUI. Now that's not true: the actual variable you're looking for is named jQuery. You can fix this by naming explicitly the value with @JSName:

import scala.scalajs.js.annotation.JSName

package object jqueryui extends js.GlobalScope {
  @JSName("jQuery")
  val jQueryUI: JQueryUI = ???
}

However, since jQuery-UI is literally an extension of the jQuery object, I would define this with extension methods on the JQuery trait of scalajs-jquery. This will allow to use the normal jQuery for both usages (jQuery-core methods and jQuery-UI methods). The general mechanism is explained in the Calling JavaScript guide under the title "Monkey patching". In your case, it would look like this:

trait JQueryUI extends JQuery {
  val buttonset: js.Any = ???
}

object JQueryUI {
  implicit def jQueryUIExtensions(query: JQuery): JQueryUI =
    query.asInstanceOf[JQueryUI]
}

Using these definitions, you can do:

import org.scalajs.jquery._
import JQueryUI.jQueryUIExtensions

def main(): Unit = {
  jQuery("#sports").buttonset
}

Note that I'm using the normal jquery.jQuery object, which returns a normal JQuery object, but then I call the buttonset value, which is defined in JQueryUI. This works because of the implicit conversion jQueryUIExtensions.

Sign up to request clarification or add additional context in comments.

3 Comments

Worked perfectly. Just had to change "val buttonset" to a "def buttonset()"
Is it possible to add function to a trait JQueryStatic. For example, to get result like this jQuery.someFunction() ?
@AlexKarasev Yes. Use exactly the same technique, but replace JQuery by JQueryStatic in the implicit def. The technique works for any JavaScript type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.