Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Integrating JQuery 3rd party app into SmartGWT

    Hi,

    We're trying to integrate an existing 3rd party JQuery application into SmartGWT. We have successfully been able to do by creating a GWT (not SmartGWT) wrapper using a GWT widget.

    However, we cannot seem to get this to work if we use a native SmartGWT Canvas object as the wrapper. Specifically, the 1st attached code works fine (since we're extending a GWT Widget); but the second one (in which we try to extend SmartGWT Canvas) does not work. (There are no errors, but nothing gets displayed either.) I'm almost certain that SmartGWT would support integrating with 3rd party JQuery applications, so we're wondering what simple thing we're doing wrong....

    The code that *does* work (because we're extending a GWT Widget).

    Code:
    package com.smartgwt.sample.client;
    
    import java.util.Date;
    
    import com.google.gwt.core.client.JavaScriptObject;
    import com.google.gwt.user.client.DOM;
    import com.google.gwt.user.client.Element;
    import com.google.gwt.user.client.ui.Widget;
    import com.smartgwt.client.widgets.Canvas;
    
    /**
     * @author gsaxena
     *
     */
    public class SpectraViewer extends Widget {
    	 int count=0;
    
        public SpectraViewer(String id)
        {           
            super();
            
            Element divEle = DOM.createDiv();
            setElement(divEle);
            divEle.setId(id);
        }
        
        @Override
        protected void onLoad()
        {
        	System.out.println("Calling on load");
            createSpectraViewer(this, getElement().getId()); 
            super.onLoad();
            
        }
       
        
        private native void createSpectraViewer(SpectraViewer x, String id) /*-{    	    
        $wnd.$("#" + id).specview({sequence: "FDSFGDLSSASAIMGNPK", 
    								scanNum: 2441,
    								charge: 2,
    								precursorMz: 1012.1,
    								fileName:'sh_1617_JX_070209p_KO410_run1',
    								//staticMods: staticMods, 
    								variableMods: [], 
    								ntermMod: 164.07, 
    								//ctermMod: ctermMod,
    								peaks: [[283.751526,6.493506],[287.601379,11.096813],[295.031097,2.801403],[305.472137,2.626226],[307.404083,3.930447],[308.360321,9.893921],[310.225128,3.961838],[311.703918,3.872004]]
    								});	
    }-*/;
    	
    }
    The code that does NOT work (ie nothing gets displayed) is below. We're extending here a SmartGWT Canvas object. (We noticed that in SmartGWT Canvas objects, the "OnLoad" doesn't seem to get called; so we tried to use the "OnDraw", but though it does get called, it just didn't display the actual 3rd party JQuery results.)

    Code:
    /**
     * 
     */
    package com.smartgwt.sample.client;
    
    
    import java.util.Date;
    
    import com.google.gwt.core.client.JavaScriptObject;
    import com.google.gwt.user.client.DOM;
    import com.google.gwt.user.client.Element;
    import com.google.gwt.user.client.ui.Widget;
    import com.smartgwt.client.widgets.Canvas;
    
    /**
     * @author gsaxena
     *
     */
    public class SmartGWTSpectraViewer extends Canvas {
    	 int count=0;
    
        public SmartGWTSpectraViewer(String id)
        {           
            super();
            setWidth("80%");
            setHeight("80%");
          //  setBackgroundColor("black");
            setBorder("red");
            System.out.println("The element is " + getElement());
            System.out.println("THe id is " + getID());
           // Element divEle = DOM.createDiv();
           // setElement(divEle);
           // divEle.setId(id);
           // System.out.println("The element is now " + getElement());
           // System.out.println("THe id is now " + getID());
        }
        
        @Override
        protected void onLoad()
        {
        	System.out.println("Calling on load");
            createSpectraViewer(this, getElement().getId()); 
            super.onLoad();
            
        }
        
        @Override
        protected void onDraw() {
        	System.out.println("Calling on draw with count of " + count);
        	
        	super.onDraw();
        	if (count==1) createSpectraViewer(this, getElement().getId());
        	count++;
        }
        
        private native void createSpectraViewer(SmartGWTSpectraViewer x, String id) /*-{    	    
        $wnd.$("#" + id).specview({sequence: "FDSFGDLSSASAIMGNPK", 
    								scanNum: 2441,
    								charge: 2,
    								precursorMz: 1012.1,
    								fileName:'sh_1617_JX_070209p_KO410_run1',
    								//staticMods: staticMods, 
    								variableMods: [], 
    								ntermMod: 164.07, 
    								//ctermMod: ctermMod,
    								peaks: [[283.751526,6.493506],[287.601379,11.096813],[295.031097,2.801403],[305.472137,2.626226],[307.404083,3.930447],[308.360321,9.893921],[310.225128,3.961838],[311.703918,3.872004]]
    								});	
    }-*/;
    	
    }
    Additional info:

    We tried

    Also, the code that calls this object is very simple and is shown here just for completeness. We don't think it's relevant to the discussion though:

    Code:
    ...
    final VLayout vlRoot = new VLayout();
    ... <stuff deleted that refers to formating vlRoot>
    SpectraViewer x = new SpectraViewer("gs_test1");
    vlRoot.addMember(x);   
    
    ... <stuff deleted> 
    vlRoot.draw();
    ...
    Additional infracstructure details are below:
    ==================================================

    OS: Windows XP Pro
    IDE: MyEclipse 9.0 with Google Plugin for Eclipse (2.4.2)
    SmartGWT EE 3.0 (Release of November 22, 2011, ie latest)
    Browwer: Mozilla Firefox 4.0.1
    GWT SDK: 2.3
    Sun JDK 1.6.0_27

    #2
    Kind of an obvious problem in this case - you're not creating an element for the JQuery library to replace, at all :)

    Use either an override of getInnerHTML() or a call to setContents() to make the Canvas' interior HTML be a DIV with whatever ID you want, then call the JQuery library onDraw.

    Comment


      #3
      Your team is awesome as usual with speed and clarity. However, we implemented about a dozen variations on your suggestion, and it still doesn't work. We even hardcoded the div id name to "lorikeet" to minimize coding errors. The code is below. We're wondering there's something about "when" the call to JQuery should execute with respect to the "onDraw" method? (In particular, we noticed that onDraw method gets called twice. Because of this, we called the JQuery library on the 2nd call to the OnDraw method, but still before the 2nd super.OnDraw gets runs) Also, we're running "debug" mode within Eclipse -- we're not sure if that has an impact.

      Code:
      package com.smartgwt.sample.client;
      
      import java.util.Date;
      
      import com.google.gwt.core.client.JavaScriptObject;
      import com.google.gwt.user.client.DOM;
      import com.google.gwt.user.client.Element;
      import com.google.gwt.user.client.ui.Widget;
      import com.smartgwt.client.widgets.Canvas;
      
      public class SmartGWTSpectraViewer extends Canvas {
      	 int count=0;
      
          public SmartGWTSpectraViewer(String id)
          {           
              super();
              setWidth("80%");
              setHeight("80%");
              setContents("<div id=\"lorikeet\"></div>");
          }
          
          
          @Override
          protected void onDraw() {
          	System.out.println("Calling on draw with count of " + count);
          	System.out.println("Inner html is " + getInnerHTML());
          		 
          	if (count==1) 	{
          		System.out.println("Inner html is " + getInnerHTML());
          		createSpectraViewer(this, "lorikeet");
          	}
          	super.onDraw();
          	 
          	count++;
          }
          
          private native void createSpectraViewer(SmartGWTSpectraViewer x, String id) /*-{    	    
          $wnd.$("#" + id).specview({sequence: "FDSFGDLSSASAIMGNPK", 
      								scanNum: 2441,
      								charge: 2,
      								precursorMz: 1012.1,
      								fileName:'sh_1617_JX_070209p_KO410_run1',
      								//staticMods: staticMods, 
      								variableMods: [], 
      								ntermMod: 164.07, 
      								//ctermMod: ctermMod,
      								peaks: [[283.751526,6.493506],[287.601379,11.096813],[295.031097,2.801403],[305.472137,2.626226],[307.404083,3.930447],[308.360321,9.893921],[310.225128,3.961838],[311.703918,3.872004]]
      								});	
      }-*/;
      	
      }

      Comment


        #4
        Nothing wrong with the approach and you can easily verify the DOM element you're trying to create exists in the DOM. Next step is to troubleshoot what's going wrong with your third-party library, eg, is it writing out the expected DOM elements at all? Are they just too small / clipped off?

        Comment


          #5
          Hi,

          So we don't think it's the 3rd party JQuery app, since we *can* see the 3rd party app if we use a GWT wrapper (a GWT Widget) instead of a SmartGWT wrapper (a SmartGWT Canvas), as described in the 1st post. Nonetheless, to verify this, we did the following:

          0) We downloaded the latest SmartGWT EE 3.x build (as of Tuesday, November 22, 2011).
          1) We removed the use of the esoteric 3rd party app (which is used by very few people) and replaced its use with a trivial, publicly available, and highly used JQuery UI (a JQuery UI slider). (http://jqueryui.com/demos/slider/). We then retested using both a GWT wrapper and a SmartGWT wrapper. As expected, teh GWT wrapper displayed the slider; the SmartGWT did not.
          3) We ran in "debug" mode in Eclipse.

          That is, we created a simple standalone test case.

          Here's the code for the GWT wrapper that *does* work.

          Code:
          package com.smartgwt.sample.client;
          
          import com.google.gwt.core.client.EntryPoint;
          import com.smartgwt.client.widgets.layout.VLayout;
          
          
          
          /**
           * Entry point classes define <code>onModuleLoad()</code>.
           */
          public class BuiltInDS implements EntryPoint {
          	/**
          	 * This is the entry point method.
          	 */
          	public void onModuleLoad() {
          
          		final VLayout vlRoot = new VLayout();
          
          		 SpectraViewer x = new SpectraViewer("lorikeet","FDSFGDLSSASAIMGNPK",2441,2,1012.1f,"sh_1617_JX_070209p_KO410_run1");
          		//	SmartGWTSpectraViewer x = new SmartGWTSpectraViewer("lorikeet");
          		vlRoot.addMember(x);    
          		vlRoot.draw();
          	}
          }
          and

          Code:
          /**
           * 
           */
          package com.smartgwt.sample.client;
          
          
          import com.google.gwt.user.client.DOM;
          import com.google.gwt.user.client.Element;
          import com.google.gwt.user.client.ui.Widget;
          
          
          /**
           * @author gsaxena
           *
           */
          public class SpectraViewer extends Widget {
          	 int count=0;
          	 
          	 String id;
          	 String sequence;
          	 int scanNum;
          	 int charge;
          	 float precursorMz;
          	 String fileName;
          	 
          
              public SpectraViewer(String id, String sequence, int scanNum, int charge, float precursorMz, String fileName)
              {           
                  super();
                  Element divEle = DOM.createDiv();
                  setElement(divEle);
                  divEle.setId(id);
                  
                  //initis
                  this.id=id;
                  this.sequence=sequence;
                  this.scanNum=scanNum;
                  this.charge=charge;
                  this.precursorMz=precursorMz;
                  this.fileName=fileName;
              }
              
              @Override
              protected void onLoad()
              {
              	System.out.println("Calling on load");
                  //createSpectraViewerMaster();
              	createSliderJS(this,id);
                  super.onLoad();
                  
              }
             
              private native void createSliderJS(SpectraViewer x, String id) /*-{
              
              $wnd.$("#" + id).slider();
          }-*/;
              
              
              private void createSpectraViewerMaster() {
              	createSpectraViewer(this, id, sequence, scanNum, charge, precursorMz, fileName);
              }
              
              private native void createSpectraViewer(SpectraViewer x, String id,String sequence, int scanNum, int charge, float precursorMz, String fileName) /*-{    	    
              $wnd.$("#" + id).specview({sequence: sequence, 
          								scanNum: scanNum,
          								charge: charge,
          								precursorMz: precursorMz,
          								fileName:fileName,
          								//staticMods: staticMods, 
          								variableMods: [], 
          								ntermMod: 164.07, 
          								//ctermMod: ctermMod,
          								peaksString: "[[283.751526,6.493506],[287.601379,11.096813],[295.031097,2.801403],[305.472137,2.626226],[307.404083,3.930447],[308.360321,9.893921],[310.225128,3.961838],[311.703918,3.872004]]",
          								variableModsString: "[{index: 14, modMass: 16.0, aminoAcid: 'M'}, {index: 15, modMass: 10.0, aminoAcid: 'G'}]"
          								});	
          }-*/;
          	
          }
          (Note: We commented out the call the JSNI native methode createSpectraViwer and instead replaced it with a call to the JSNI native method createSliderJS).


          And now here's the code for the SmartGWT wrapper that *does NOT* work.


          Code:
          package com.smartgwt.sample.client;
          
          import com.google.gwt.core.client.EntryPoint;
          import com.smartgwt.client.widgets.layout.VLayout;
          
          
          
          /**
           * Entry point classes define <code>onModuleLoad()</code>.
           */
          public class BuiltInDS implements EntryPoint {
          	/**
          	 * This is the entry point method.
          	 */
          	public void onModuleLoad() {
          
          		final VLayout vlRoot = new VLayout();
          
          		// SpectraViewer x = new SpectraViewer("lorikeet","FDSFGDLSSASAIMGNPK",2441,2,1012.1f,"sh_1617_JX_070209p_KO410_run1");
          			SmartGWTSpectraViewer x = new SmartGWTSpectraViewer("lorikeet");
          		vlRoot.addMember(x);    
          		vlRoot.draw();
          	}
          }
          and

          Code:
          /**
           * 
           */
          package com.smartgwt.sample.client;
          
          import com.smartgwt.client.widgets.Canvas;
          
          /**
           * @author gsaxena
           *
           */
          public class SmartGWTSpectraViewer extends Canvas {
          	 int count=0;
          
              public SmartGWTSpectraViewer(String id)
              {           
                  super();
                  setWidth("80%");
                  setHeight("80%");
                  setContents("<div id=\"lorikeet\"></div>");
              }
              
              
              @Override
              protected void onDraw() {
              	System.out.println("Calling on draw with count of " + count);
              	System.out.println("Inner html is " + getInnerHTML());
              		 
              	if (count==1) 	{
              		System.out.println("Inner html is " + getInnerHTML());
              //		createSpectraViewer(this, "lorikeet");
              		createSliderJS(this,"lorikeet");
              	}
              	super.onDraw();
              	 
              	count++;
              }
              
              
              private native void createSliderJS(SmartGWTSpectraViewer x, String id) /*-{
              
              $wnd.$("#" + id).slider();
          }-*/;
              
              
              private native void createSpectraViewer(SmartGWTSpectraViewer x, String id) /*-{    	    
              $wnd.$("#" + id).specview({sequence: "FDSFGDLSSASAIMGNPK", 
          								scanNum: 2441,
          								charge: 2,
          								precursorMz: 1012.1,
          								fileName:'sh_1617_JX_070209p_KO410_run1',
          								//staticMods: staticMods, 
          								variableMods: [], 
          								ntermMod: 164.07, 
          								//ctermMod: ctermMod,
          								peaks: [[283.751526,6.493506],[287.601379,11.096813],[295.031097,2.801403],[305.472137,2.626226],[307.404083,3.930447],[308.360321,9.893921],[310.225128,3.961838],[311.703918,3.872004]]
          								});	
          }-*/;
          	
          }
          (Note: To minimize coding errors, we actually hardcoded the div id to "lorikeet").

          And, just for completeness, here's the BuiltInDs.html file. (The only part that's useful, we think, is the reference to the JQuery UI source files and any dependant JQuery libraries.)


          Code:
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <!-- The HTML 4.01 Transitional DOCTYPE declaration-->
          <!-- above set at the top of the file will set     -->
          <!-- the browser's rendering engine into           -->
          <!-- "Quirks Mode". Replacing this declaration     -->
          <!-- with a "Standards Mode" doctype is supported, -->
          <!-- but may lead to some differences in layout.   -->
          
          <html>
            <head>
              <meta http-equiv="content-type" content="text/html; charset=UTF-8">
              <!--                                           -->
              <!-- Any title is fine                         -->
              <!--                                           -->
              <title>Integrated Analysis - Making Sense of Data</title>
              
              <!-- IMPORTANT : You must set the variable isomorphicDir to [MODULE_NAME]/sc/ so that the SmartGWT resource are 
          	  correctly resolved -->	
          	<script> var isomorphicDir = "builtinds/sc/"; </script>
          	
          	<link media="all" type="text/css" 
                  href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/base/jquery-ui.css" rel="stylesheet"> 
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" 
                  type="text/javascript" charset="utf-8"></script> 
          <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js" 
                  type="text/javascript" charset="utf-8"></script> 
          	
          	    
          
          	
          	
              <!--                                           -->
              <!-- This script loads your compiled module.   -->
              <!-- If you add any GWT meta tags, they must   -->
              <!-- be added before this line.                -->
              <!--                                           -->      
              <script type="text/javascript" language="javascript" src="builtinds/builtinds.nocache.js"></script>
            </head>
          
            <!--                                           -->
            <!-- The body can have arbitrary html, or      -->
            <!-- you can leave the body empty if you want  -->
            <!-- to create a completely dynamic UI.        -->
            <!--                                           -->
            <body>
          
              <!--load the datasources-->
              <script src="builtinds/sc/DataSourceLoader?dataSource=to_workflow,dsGenericWorkflow,dsXTandemProcess,dsProcessMSConvert,dsProcessProteinProphet,dsProcessIProphet,dsProcessPeptideProphet,dsProcessFTP,dsIAFileOrFolder,dsIAFolderONLY,dsSQLSelectedFiles,dsProcessXTandemToPepXML,dsProcessLoadPASS,dstf_prot_xml_peptides,dsProcessOMSSA,dsProteinPerspective,dsProtXMLFileName,dstm_percentages,dstd_prot_xml_proteins,dsModsObserved,dsMzObserved"></script>
          
              <!-- OPTIONAL: include this if you want history support -->
              <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
          
            </body>
          </html>
          Additional infracstructure details are below:
          ==================================================

          **Ran in Debug Mode** in Eclipse
          OS: Windows XP Pro
          IDE: MyEclipse 9.0 with Google Plugin for Eclipse (2.4.2)
          SmartGWT EE 3.0 (Downloaded this morning; Release of November 22, 2011, ie latest)
          Browwer: Mozilla Firefox 4.0.1
          GWT SDK: 2.3
          Sun JDK 1.6.0_27

          Comment


            #6
            No need for any of this - as mentioned you can use Firebug to verify whether or not your DOM element is being written out as you intended, and then use Firebug to see whether your JQuery logic successfully replaced the target element.

            Comment


              #7
              Just a follow-up:

              1) I used FireBug and it appeared that it was correctly putting in the correct divID but that the 3rd party app's code was not getting inserted within that div id

              2) So, I stopped using the "setContents" method and instead overode the "getInnerHtml()" method and everything worked. (I don't think I made any other changes).

              So, hope this helps others reading this post....

              Comment


                #8
                Would a ViewLoader be applicable in this circumstance, that of embedding an external .js app within a SmartGWT canvas?

                Comment


                  #9
                  No, a ViewLoader loads SmartClient/SmartGWT interfaces, it does not apply here.

                  Comment


                    #10
                    Oh, ok. I've been able to get ViewLoader to load very simple js files but I haven't got it to load SmartGWT packages.
                    I'm guessing that the structure of my jar/war is not what it's expecting, but I haven't found any templates to follow.

                    Comment

                    Working...
                    X