11

How can I translate the following jquery code to Dart? I'm having difficulty getting the alert callback to work using js.interop.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script>
  $(function () {
    $('p').hide('slow', function() {
      alert("The paragraph is now hidden");
    });
  });
</script>

Any help is appreciated.

Seth Ladd
  • 112,095
  • 66
  • 196
  • 279
basheps
  • 10,034
  • 11
  • 36
  • 45

2 Answers2

15

thanks for your question! I wasn't sure myself, but turns out this is possible. :)

First off, add js to your pubspec.yaml:

name:  jquerydart
description:  A sample application

dependencies:
  js: any

Then, run pub install, either via the command line or via Dart Editor.

Then, in your Dart file:

import 'dart:html';
import 'package:js/js.dart' as js;

hideIsDone() {
  window.alert('all done!');
}

void main() {
  js.scoped(() {
    js.context.jQuery('p').hide(1000, new js.Callback.once(() => hideIsDone()));
  });
}

Note that to callback from JS into Dart, you need to create a Callback object.

Also note you cannot use $ for the jQuery variable, as dart2js also uses $. So in the meantime you need to use jQuery in your Dart code.

Having said all that, it's cool that we can use jQuery via JS-Dart interop, but Dart should really do this for us. So I opened bug http://code.google.com/p/dart/issues/detail?id=6526

Seth Ladd
  • 112,095
  • 66
  • 196
  • 279
  • 5
    Personally I'm not thrilled seeing people trying to use jQuery in Dart (or even in JS for that matter). I rather want to see a good base support for things like manipulating the DOM (which is quite good in Dart already), and then combined with nice libraries for animation etc. The issue you created helps in this regard. – Kai Sellgren Nov 05 '12 at 09:04
  • 3
    I agree Kai, but it's a good bridge service to have during these early days. – John Evans Nov 05 '12 at 13:37
  • I agree @KaiSellgren please star the bug and open more :) – Seth Ladd Nov 05 '12 at 16:07
  • 1
    Can you replace "() => hideIsDone()" with "hideIsDone"? – Shannon -jj Behrens Nov 05 '12 at 20:17
  • @Shannon-jjBehrens I think I tried that, but there was some bug in Dartium. Might be fixed now. – Seth Ladd Nov 18 '12 at 05:28
  • @SethLadd. Is this solution still valid? I cannot find scoped() and Callback.once in `js` package. – Nawaf Alsulami Feb 01 '14 at 18:35
  • There is still a js package, but I don't know if this specific solution still works. Might be better to use the newer `dart:js` library. – Seth Ladd Feb 02 '14 at 10:05
  • Kai, there isn't always an option when, for instance, using a third party lib that extends jQuery. @SethLadd, perhaps it's time to update https://www.dartlang.org/articles/js-dart-interop/ to include usage of 'package:js/js.dart'. – xster Jul 12 '14 at 08:24
6

First add the js dependency to your pubspec.yaml :

dependencies:
  js: any

By using js-interop you can write almost the same code as in javascript.

import 'dart:html';
import 'package:js/js.dart' as js;

void main() {
  js.scoped(() {
    js.context.$(new js.Callback.once(($) {
      $('p').hide('slow', new js.Callback.once(() {
        js.context.alert("The paragraph is now hidden");
      }));
    }));
  });
}

The main differences are :

  • You have to use js.Callback.once or js.Callback.many to set your callback functions. Use js.Callback.once if your callback is call only one time.
  • Your code must be wrapped with the js.scoped. Basically, managing proxy lifetimes is here to prevent memory leak.

That said, you can simplify the above code :

import 'dart:html';
import 'package:js/js.dart' as js;

void main() {
  js.scoped(() {
    js.context.$('p').hide('slow', new js.Callback.once(() {
      window.alert("The paragraph is now hidden");
    }));
  });
}

The changes are :

  • js.context.$(new js.Callback.once(($) { isn't needed because main is equivalent to the jQuery $(function).
  • js.context.alert has been replace by window.alert : it's more efficient to directly use DART functions instead of communicate with JS.
Alexandre Ardhuin
  • 71,959
  • 15
  • 151
  • 132