Question

I don't work much with javascript, but I'm trying to get dragging working with the Modal boxes from the GWT Bootstrap project. So I have a GWT project, I have an entrypoint module. I add a Modal dialog box to the document and give it a title. Then I try to call the draggable method from the jQuery UI framework on that widget. Since it's just a div, everything should work.

My first problem was that the stuff in the <script> tags was getting run before the element ever got added to the DOM. So I moved it into the notifyHostPage() function and hoped to call it from there. But jQuery UI seems to unload itself from the page after it exits the tag the first time. I've included the code to show what I've tried, and the output it results in. This is really crazy.

I've tried moving the <scripts> to below the nocache.js file, I've tried just putting them in the gwt.xml, but because of super dev mode or whatever it won't let me. I've tried using document.write() to add the scripts inside the notifyHostPage() function. I've tried just adding the class ui-draggable to the modal dialog, but because jQuery UI disappears that doesn't work either. I've tried using local resources and a CDN. I'm kind of at my wits end.

module.html


<script type="text/javascript" language="javascript" src="module/js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" language="javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.js"></script>
<script type="text/javascript" language="javascript" src="module/module.nocache.js"></script>

<script type="text/javascript">
  $(function() {
    if (jQuery.ui) {
      // UI loaded
      console.log("yes");
      console.log(jQuery.ui);
    } else {
      console.log("no");
    }
  });
  function startDragging() {
    if (jQuery.ui) {
      // UI loaded
      console.log("yes");
      console.log(jQuery.ui);
    } else {
      console.log("no");
    }
    $("#myModal").draggable({
      handle: ".modal-header"
    }); 
  };
</script>

Entrypoint module


  public native void notifyHostPage() /*-{
    if ($wnd.jQuery.ui) {
      // UI loaded
      console.log("yes");
      console.log(jQuery.ui);
    } else {
      console.log("no");
    }
    $wnd.startDragging();
  }-*/;

Output


yes
Object
  accordion: function ( options, element ) {
  autocomplete: function ( options, element ) {
  button: function ( options, element ) {
  buttonset: function ( options, element ) {
  datepicker: Object
  ddmanager: Object
  dialog: function ( options, element ) {
  draggable: function ( options, element ) {
  droppable: function ( options, element ) {
  hasScroll: function ( el, a ) {
  ie: false
  intersect: function (draggable, droppable, toleranceMode) {
  keyCode: Object
  menu: function ( options, element ) {
  mouse: function ( options, element ) {
  plugin: Object
  position: Object
  progressbar: function ( options, element ) {
  resizable: function ( options, element ) {
  selectable: function ( options, element ) {
  slider: function ( options, element ) {
  sortable: function ( options, element ) {
  spinner: function ( options, element ) {
  tabs: function ( options, element ) {
  tooltip: function ( options, element ) {
  version: "1.10.1"
  __proto__: Object
no
no 

Final Solution:

I've updated my files as so:

entrypoint.java


public class RecondoHISModern implements EntryPoint {
  final RecondoHISServletInterfaceAsync recondoHIS = GWT.create(RecondoHISServletInterface.class);
  public void onModuleLoad() {
    loadScripts();
  }
  private void loadScripts() {
    // ScriptInjector.fromString("public/js/jquery-ui-1.10.4.custom.min.js").inject();
    // ScriptInjector.fromString("public/js/nprogress.js").inject();
    List<String> scripts = Arrays.asList( //"//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.js",
                                          "//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js",
                                          "//cdnjs.cloudflare.com/ajax/libs/nprogress/0.1.2/nprogress.min.js");
    injectScriptsInOrder(scripts);
  }

  private void injectScriptsInOrder(final List<String> scripts) {
    if (scripts.size() > 0) {
      ScriptInjector.fromUrl(scripts.get(0))
      .setRemoveTag(false)
      .setWindow(ScriptInjector.TOP_WINDOW)
      .setCallback(new Callback<Void, Exception>() {

        @Override
        public void onFailure(Exception reason) {
          GWT.log("The script " + scripts.get(0) + " did not install correctly");
        }

        @Override
        public void onSuccess(Void result) {
          GWT.log("The script " + scripts.get(0) + " installed correctly");
          injectScriptsInOrder(scripts.subList(1, scripts.size()));
        }
      }).inject();
    } else {
      createModal();
    }
  }

  public void createModal() {
    Modal modal = new Modal();
    modal.setTitle("Java Created Modal");
    modal.setClosable(true);
    ModalBody modalBody = new ModalBody();
    modalBody.add(new Span("Create in Java Code!"));

    ModalFooter modalFooter = new ModalFooter();
    modal.add(modalBody);
    modal.add(modalFooter);

    modal.setId("myModal");
    modal.show();
    draggable();
  }

  private native void draggable() /*-{
    $wnd.jQuery("#myModal").draggable({
      handle: ".modal-header"
    });
  }-*/;
}

At first it was crashing at this function in modal.show();

private native void modal(final Element e, final String arg) /*-{
    $wnd.jQuery(e).modal(arg);
}-*/;

But then I realized that maybe I shouldn't be loading jQuery twice, so I removed jQuery from the ScriptInjector list and everything started working fine!

Was it helpful?

Solution

You shouldn't load JS dependencies via <script> tags in your HTML file. Either specify them in your module .gwt.xml file via <script> or better use ScriptInjector for compatibility with SuperDevMode.

Create an EntryPoint for your module and inject the JS dependencies there. See how we did it in our GwtBootstrap3 project. Since you're using GwtBootstrap3 you don't need to inject jQuery. This will already be done by GwtBootstrap3. Just inject jQuery UI and make sure to specify your <entry-point> after all <inherits>.

Once this is resolved you should be able to run something like this from your presenter:

private native void draggable() /*-{
   var $modal = $wnd.jQuery("#myModal");
   $modal.draggable(...);
}-*/;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top