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:
But if you refresh the page your buttons start working right?
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.
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.
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…
Remove the … 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.
//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.
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)
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)
}
//now when this runs, all is good. don't judge me.
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.
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:
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: