jQuery and .click()

Using Servoy to administrate the content of your website? Discuss all webrelated Servoy topics on this forum!

jQuery and .click()

Postby bcusick » Wed Mar 01, 2017 3:01 am

Hey Guys,

I'm sure your sick of me by now... but here's another question.

I can't seem to make jQuery listen for the click on a class of items. In the code below, I have a table with a button on each row with the class "btn". I just want jQuery to fire when I click the button to log in the console.

I have a "regular" html sample that works just fine:

Code: Select all
<html>
   <head>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
      <script type="text/javascript">

         $( document ).ready(function() {
            console.log( 'document loaded' );
            $('.btn').click( function() {
                  console.log('HI');
            });
               
         });
      </script>
   </head>
   <body>
      <table id='thisTable' width='100%' cellpadding='5' cellspacing='0'>
         <tr id='1'><td>One</td><td><button type='button' class='btn'>X</button></td></tr>
         <tr id='2'><td>Two</a></td><td><button type='button' class='btn'>X</button></td></tr>
         <tr id='3'><td>Three</a></td><td><button type='button' class='btn'>X</button></td></tr>
      </table>
   </body>
</html>


Next, I set up the same thing in Servoy using a HTML area in a form variable, with a button:

Code: Select all
function onAction(event) {
   
   var aHTML = ["<html><head><script type='text/javascript'>" + getScript() + "</script></head><body>"]
   
   aHTML.push("<table id='thisTable' width='100%' cellpadding='5' cellspacing='0'>");
   aHTML.push("<tr id='1'><td>One</td><td><button type='button' class='btn'>X</button></td></tr>");
   aHTML.push("<tr id='2'><td>Two</a></td><td><button type='button' class='btn'>X</button></td></tr>");
   aHTML.push("<tr id='3'><td>Three</a></td><td><button type='button' class='btn'>X</button></td></tr>");
   aHTML.push("</table></body></html>");
   
   fv_sHTML = aHTML.join("");
}

function getScript() {
   script = "$( document ).ready( function() {" +
         "console.log( 'document loaded' );" +
         "$('.btn').click( function() {" +
            "console.log('HI');" +
         "});" +
      "});";
            
   return script;
}


When I click the button - it pushes it into the head of the document just fine, and the console reads "document loaded". (ALL GOOD)

However, when I click the button - the console doesn't update with "HI" - like it does in the static HTML.

This is Servoy 7.4.9 on Windows 10 with Java 1.8.0_121

Any ideas on what I'm doing wrong? :shock:
Attachments
2017-02-28_16-47-52.png
2017-02-28_16-47-52.png (20.82 KiB) Viewed 973 times
2017-02-28_16-46-50.png
2017-02-28_16-46-50.png (21.53 KiB) Viewed 973 times
Bob Cusick
bcusick
 
Posts: 1183
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA

Re: jQuery and .click()

Postby david » Wed Mar 01, 2017 7:50 am

But if you refresh the page your buttons start working right? 8)

That JS code is not taking into account the change in context. `$( document ).ready` fires immediately because its context is the current Servoy application already running in the browser. `$('.btn').click` is also running but before your markup is returned, parsed and displayed in the form variable — so it doesn't find any matches.

To demonstrate, this will work:

Code: Select all
function getScript() {
   return "(function myScript() { \
      setTimeout(function() { \
         console.log( 'Attaching!' ); \
         $('.btn').click( function() { \
            console.log('HI'); \
         }) \
      } \
      , 500) \
   })()"


Not suitable for production as the XHR response to fill the form variable could be more than the timeout setting. Instead you need to hook into Servoy wicket implementation and in the past we used the webclient utils plugin for this.

Looks like there is a much more complete set of functionalities for web client these days here: https://github.com/Servoy/svyUtils/blob ... ntUtils.js
David Workman, Kabootit

Image
Everything you need to build great apps with Servoy
User avatar
david
 
Posts: 1723
Joined: Thu Apr 24, 2003 4:18 pm
Location: Washington, D.C.

Re: jQuery and .click()

Postby bcusick » Wed Mar 01, 2017 3:54 pm

Wow! :shock:

Thanks very much, David! I didn't even thing about the timing aspect (obviously).

I know that I don't have nearly the experience that you guys do with the inner workings of the webclient - but can you give a little more of a breadcrumb when you say:
Instead you need to hook into Servoy wicket implementation and in the past we used the webclient utils plugin for this.


I use that plug-in quite a bit, but I'm unsure how to harness it to fix this timing issue...

Again, many thanks!

Bob
Bob Cusick
bcusick
 
Posts: 1183
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA

Re: jQuery and .click()

Postby goldcougar » Wed Mar 01, 2017 11:10 pm

Remove the <head>...<head> and use the WebClientUtils plugin (or that new module, but I haven't used the module yet). Some pseudo code here so I'm sure there is some syntax errors.

Code: Select all

//put this in your onShow or some place like that
function onShow(){
   var js = "$('.btn').click( function() {\
                  console.log('HI');\
            });"
   plugins.WebClientUtils.executeClientSideJS(js)
}


Then you can get fancier with it, and have the click call back into a Servoy function.

Code: Select all

function myServoyFunction(myArg){
  application.output(myArg + " was clicked")
}

function onShow(){
    var js = "$('.btn').click( function() {\
                  console.log('HI');\
                  var theId = this.id;"  +
                   plugins.WebClientUtils.addCallback(myServoyFunction, ["theId"]) + "\
            });"
   plugins.WebClientUtils.executeClientSideJS(js)
}



Oh...and *sometimes*, (timing issue?) the events don't fire in order (ie the html isn't rendered before the jquery fires, so it doesn't work). So sometimes you have to do this little trick, which adds a cycle to make sure the HTML is there (cover your eyes, its a bit dirty)

Code: Select all

function onShow(){
  //this runs on show in the browser, giving the HTML a chance to load, then calls initJS as the callback as soon as the code has ran.
   var js = "var a=1;"
   plugins.WebClientUtils.executeClientSideJS(js, initJS)
}

function initJS(){
   //now when this runs, all is good.  don't judge me.
   var js = "$('.btn').click( function() {\
                  console.log('HI');\
            });"
   plugins.WebClientUtils.executeClientSideJS(js)
}
Scott Butler
iTech Professionals, Inc.
SAN Partner

Servoy Consulting & Development
Servoy University- Free Training Videos
Servoy Guy- Free Plugins, Tips & Resources
ServoyForge- Open Source Servoy Components
User avatar
goldcougar
Servoy Expert
 
Posts: 657
Joined: Sun Jan 08, 2006 7:15 am
Location: Cincinnati, OH

Re: jQuery and .click()

Postby david » Wed Mar 01, 2017 11:53 pm

goldcougar wrote:
Code: Select all

   //now when this runs, all is good.  don't judge me.


:D :D :D I don't care what tool, library or framework used...web programming has been one big stupid hack. Only recently have things approached a level of sanity.

With that said, you could do some crazy things with Servoy's webclient, webclient utils, and all the JQuery stuff out there.

Bob, for more examples search Github for "plugins.WebClientUtils". Select the "Code" results and browse away. To dig deeper, click any line number to see entire code. If you go crazy and/or get really pissed off at the world, it's a normal reaction.
David Workman, Kabootit

Image
Everything you need to build great apps with Servoy
User avatar
david
 
Posts: 1723
Joined: Thu Apr 24, 2003 4:18 pm
Location: Washington, D.C.

Re: jQuery and .click()

Postby bcusick » Fri Mar 03, 2017 4:28 pm

David: DAMN RIGHT! It's really "messy" - that's for sure. Thanks for the sanity check! :D

Scott - THANK YOU - I actually came up with the same hack-around:

  • Create a callback JS function that will get the attributes of the object ID passed into it
  • Wrap the image in "normal" anchor that triggers a Servoy method
  • Servoy method that is called executes a client-side script (specified above) that specifies the ID of the object I want
  • Second method receives all the settings I wanted
  • Create a jQuery script in that method (to alter the properties of the page object) and fire it using WebClientUtils

:shock:

I'm not sure if it's "right" - but it certainly works. :D

Again, THANK YOU BOTH VERY MUCH for your time and help!
Bob Cusick
bcusick
 
Posts: 1183
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA

Re: jQuery and .click()

Postby david » Fri Mar 03, 2017 7:53 pm

If you start doing a lot of this type of custom Javascript, to scale past one-off code you can load client-side JS with all your functions at solution startup:

Code: Select all
plugins.WebClientUtils.addJsReference("/somewhere-in-servoy-webserver-directory/client-side-utils.js")


Next level is to put your webclient in an iframe. At minimum this has been the easiest way to customize your WC URLs since the day WC came out. Going further it allows you to do all kinds of custom JS stuff in the parent html. Data Sutra used this to hack in pretty URLs, preview and printing, css overrides, spinners, charting libraries, and generally smoothed out a plethora of WC quirks:

https://github.com/datamosaic/data-sutr ... s/js/wc.js
https://github.com/datamosaic/data-sutr ... s/js/ds.js
https://github.com/datamosaic/data-sutr ... .custom.js
https://github.com/datamosaic/data-sutr ... s/print.js
https://github.com/datamosaic/data-sutr ... /router.js

Loading advanced functionality into the client like this makes it easy to write Servoy code against it.

Example: need a chart? Just collect your data and dump it to the client with a configuration object and you have a spiffy looking RaphaelJS chart.
David Workman, Kabootit

Image
Everything you need to build great apps with Servoy
User avatar
david
 
Posts: 1723
Joined: Thu Apr 24, 2003 4:18 pm
Location: Washington, D.C.

Re: jQuery and .click()

Postby bcusick » Sun Mar 05, 2017 2:36 am

David - been looking at your (and Troy's) code... all I can say is: :shock: :shock:

WOW.

Seriously.

WOW.

I sure thank you again for all your helpful insights - I can see you've TOTALLY "been there, done that".... :D
Bob Cusick
bcusick
 
Posts: 1183
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA

Re: jQuery and .click()

Postby steve1376656734 » Sun Mar 05, 2017 11:41 am

Not sure if I haven't missed something here but wouldn't all this be MUCH easier in the NG client?
steve1376656734
 
Posts: 177
Joined: Fri Aug 16, 2013 2:38 pm
Location: Lanzarote

Re: jQuery and .click()

Postby bcusick » Sun Mar 05, 2017 5:51 pm

Hey Steve,

Yeah, it would be (sort of). However, this is a legacy thing all in Webclient. :D
Bob Cusick
bcusick
 
Posts: 1183
Joined: Wed Apr 23, 2003 11:27 pm
Location: Thousand Oaks, CA USA


Return to Web Development

Who is online

Users browsing this forum: No registered users and 1 guest