Landlocked Surfer
Landlocked Surfer

Reputation: 433

How to implement a jQuery Plugin using Scala.js

The Scala.js documentation has a nice example on how to implement a jQuery facade which also supports chaining:

@js.native
trait JQueryGreenify extends JQuery {
  def greenify(): this.type = ???
}

object JQueryGreenify {
  implicit def jq2greenify(jq: JQuery): JQueryGreenify =
   jq.asInstanceOf[JQueryGreenify]
}

However as far as I understood it, this example assumes that the greenify plugin has been implemented in Javascript already. E.g. like

$.fn.greenify = function() {
  this.css( "color", "green" );
  return this;
}

How would this plugin be implemented in Scala.js?

Upvotes: 2

Views: 339

Answers (1)

sjrd
sjrd

Reputation: 22085

There two ways to define a "jQuery plugin" in Scala.js. The first one is a safe and idiomatic Scala-esque way, but is only for consumption by other Scala.js code. The second is a bit ugly, but it can be used by JavaScript code.

For Scala.js

In Scala, and in Scala.js, the patch-the-prototype thing that actual jQuery plugins do is discouraged. Instead, we use implicit classes:

implicit class JQueryGreenify(val self: JQuery) extends AnyVal {
  def greenify(): self.type = {
    self.css("color", "green")
    self
  }
}

And then you can simply do

jQuery("#some-element").greenify()

when you have JQueryGreenify in scope (as an import, typically).

This method does not pollute the actual prototype of jQuery objects. It is a pure-Scala abstraction. It is clean and safe, but that means it cannot be used by JavaScript code.

For JavaScript

If you need to call greenify from JavaScript, you actually need to add a function property on the jQuery.fn object. Since the function needs to use the this parameter, we have to explicitly ascribe it to a js.ThisFunction (see also Access the JS this from scala.js):

js.Dynamic.global.jQuery.fn.greenify = { (self: JQuery) =>
  self.css("color", "green")
  self
}: js.ThisFunction

which is basically a transliteration of the original JavaScript code from the question.

Upvotes: 3

Related Questions