-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hello,
I imported a custom version of jQuery and wanted to import a custom version of jQueryUI too. The jQuery import went fine, however the jQueryUI didn't. In developer tools (Chrome), after the page is loaded, if I type:
alert(jQuery.fn.jquery)
the output is:
3.5.1
which is correct. If I type:
alert(jQuery.ui.version)
or
alert(jQuery.ui)
I get undefined.
This is the code:
<?page title="title" contentType="text/html;charset=UTF-8"?>
<zk>
<script type="text/javascript" src="~./js/jquery-3.5.1.min.js" ></script>
<script type="text/javascript" src="~./js/jqueryui.js" ></script>
<window title="title" border="normal">
</window>
</zk>
Am I missing something here?
Thanks
Is there a way to make jQueryUI.js "connect" to a different imported version of jQuery instead of the ZK built-in jQuery?
There is always a way to control the sequence how scripts are loaded and executed. However there are a few things you haven't mentioned in detail. E.g.
In any case adding scripts in an uncontrolled manner is kind of gambling against latency, browser (version) specific and zk specific behavior. ZK has a built in way to control client side js package loading (and especially waiting for a package to be ready), this control can be achieved by defining a js package in a WPD file, which can package both zk js widget code and external files. It will then provide a dedicated callback indicating when your package is loaded (similar to afterMount, just especially dedicated for this usage).
e.g. create a wpd for mypackage
in src/main/resources/web/js/mypackage/zk.wdp
(also place both jquery files in the same mypackage
folder)
<package name="mypackage">
<script src="jquery-3.5.1.min.js"/>
<script src="jquery-ui.min.js"/>
</package>
Now both scripts will be combined into a single resource and downloaded once (no more sequence/latency issue). To trigger loading the package you can use:
zk.load('mypackage', function() {
// will be called after your package is loaded
});
Since it looks like you are integrating a custom 3rd party library the next step would be to define a custom widget to make the inline code reusable.
To implement the widget - create a MyWidget.js
(same mypackage
folder)
mypackage.MyWidget = zk.$extends(zul.wgt.Div, {
/*instance members*/
_myString: '',
_myNumber: 0,
bind_: function() {
this.$supers('bind_', arguments);
alert(jQuery.fn.jquery + ' ' + jQuery.ui.version + ' my props:' + this._myString + this._myNumber);
// initialize your widget here based on parameters
}
}, { /* static members */ }
);
(I added 2 client side widget attributes, you can add more, and change names)
and add it to the zk.wpd file:
<package name="mypackage" language="xul/html" depends="zul.wgt">
<script src="jquery-3.5.1.min.js"/>
<script src="jquery-ui.min.js"/>
<!-- more scripts -->
<widget name="MyWidget"/>
</package>
In the zul file you can now w:use
the widget class (which will load mypackage
automatically) and set widget attributes also using the client namespace w:
declared above.
<zk xmlns:w="client">
<div w:use="mypackage.MyWidget"
w:_myString="'a string'"
w:_myNumber="1234"></div>
</zk>
Like this the required scripts will only be loaded once and only when needed, at the right time, and you can have multiple instances of the same widget in your page.
From the java side you can use setWidgetClass and setWidgetOverride on a Div component
If you want this to be controllable more conveniently from java code you can also implement a server side component class and define a custom component ... however that's too much for here, just read the custom component reference.
I have run with your code and 2 script files are loaded as expected.
Have you ever checked Chrom developer tool > Console? is there any js error?
From the developer tool > Source tab, you should be able to see those 2 files:
Use script directive to ensure its loading order like:
<?script src="~./jquery-3.5.1.min.js"?>
<?script src="~./jquery-ui.min.js"?>
Check the console tab to see if there is an error that fails jquery UI. But even jquery UI doesn't register on 3.5.1, it should register on zk built-in jquery.
So even you just load jqueryui.js
only, jq.ui
should return its version.
Or maybe something in your current project affects the jquery UI. You can also create a new project to test.
(reply to question below)
inside a script running at client side the server side configuration isn't known, however you can encode the url at server side using the c:encodeURL function
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
...
<script type="text/javascript">
var file = jq.getScript("${c:encodeURL('~./path/to/file')}", // should work
function() {alert("script loaded"); });
</script>
should produce something like this:
/yourwebapp/zkau/web/ac142736/path/to/file
still I'd recommend the .wpd approach described above (btw I tried adding the iviewer script as well successfully) it is deliberately designed to load scripts in a particular order inside a ZK application, jquery alone won't be aware of ZK specific timing
Yes, I can see the scripts loaded in the sources of Chrome, both jQuery and jQueryUI.
I also wanted to import another script (iviewer.js) that depends on jQuery and JQueryUI, but as soon as i load the page i get the error message:
Uncaught TypeError: $(...).iviewer is not a function
This is the code so far..
<?page title="" contentType="text/html;charset=UTF-8"?>
<zk>
<script type="text/javascript" src="~./app/component/zoomer/jquery-3.5.1.min.js" ></script>
<script type="text/javascript" src="~./app/component/zoomer/jqueryui.js" ></script>
<script type="text/javascript" src="~./app/component/zoomer/js/iviewer.js" ></script>
<window title="" border="normal">
<div id="wrapper" class="wrapper">
<div id="viewer" class="viewer" style="border: 2px solid red;"></div>
</div>
</window>
<script>
zk.afterMount(function(){
var test = $("$wrapper").css('background-color', 'red'); // works fine
var iv1 = $("$viewer").iviewer({ // error, iviewer not a function
src: path,
zoom : 55
});
});
</script>
</zk>
I can't understand why this doesn't work, thank you for the help
(I can't upload images, if it can be useful, I'm adding the full error message)
Uncaught TypeError: $(...).iviewer is not a function
at eval (eval at <anonymous> (zk.wpd:9), <anonymous>:7:29)
at r (zk.wpd:21)
at s (zk.wpd:21)
at t (zk.wpd:21)
at d (zk.wpd:21)
at zkx (zk.wpd:21)
at zkmx (zk.wpd:21)
at _childjs (eval at c.evalJSON (zk.wpd:25), <anonymous>:4:287)
at y.bind_ (zk.wpd:54)
at y.bind (zk.wpd:19)
I tried using both 8.0.2.2 and 9.5.0.2 versions of ZK getting the same results. The code I provided is actually part of a bigger project. I tried to do the same thing on a new project and it worked, all was imported correctly and I had no problems so far.
I'm assuming that the structure of this project is creating some conflicts on loading these .js files.
About the 3rd part library.. It is a .js file, I don't understand why it should not be loaded like the other two .js files (jQuery and jQueryUI) as you mentioned in your answer, I mean, why shouldn't it be like this?
<package name="mypackage">
<script src="jquery-3.5.1.min.js"/>
<script src="jquery-ui.min.js"/>
<script src="iviewer.js"/> // this is the custom .js that i need to use
</package>
At this point I guess in my .zul page i can go with something like this?
<script type="text/javascript">
zk.load('mypackage', function() {
// will be called after your package is loaded
var iv1 = jq('$viewer').iviewer({
src = 'test.jpg',
zoom : 55
})
});
</script>
The .zul page is at the same level (hierarchically speaking) of the mypackage
folder which contains the zk.pwd
file with the content mentioned above. Did I get it right?
From a really fast test i get:
Uncaught SyntaxError: Invalid shorthand property initializer
at p (zk.wpd:41)
at Function.globalEval (zk.wpd:69)
at zkx (zk.wpd:575)
at zkx_ (zk.wpd:576)
at Object.outer (zk.wpd:675)
at m (zk.wpd:642)
at K (zk.wpd:645)
at Object._doCmds (zk.wpd:652)
at Object.afterResponse (zk.wpd:663)
at Object._onResponseReady (zk.wpd:659)
From documentation:
WPD must be named zk.wpd
This means that you cannot have under mypackage
two files called zk1.pwd
and zk2.pwd
right? None of them would be imported since ZK only "loads" a file called zk.pwd
?
I'm using Chrome version 87.0.4280.88 (Stable build)
Thank you
Update:
I managed to import the .wpd file but still got the jq(...).iviewer is not a function
error message. I don't understand why I should create a widget for a 3rd party library.. Is it necessary? Why does this widget have to extend Div
?
if you would like to give it a try here's the link for the plugin i'm trying to use: https://plugins.jquery.com/iviewer/ again, importing this file in a new project witho pretty much no dependicies, scripts are loading fine, that means that i am not getting any errors so far
aUser ( 2020-12-30 21:21:28 +0800 )editIs there a way to reference a file with the notation "~./..." inside a script?
If i have a file in my project that can be referenced inside a .zul page with "~./path/to/file", how can i replicate that path inside a script in a .zul page?
<script type="text/javascript">
var file = jq.getScript("~./path/to/file", // doesn't work
function() {alert("script loaded"); });
</script>
Updating my situation..
I'm trying to use this iviewer.js plugin in a new project to see if i can run it at least in isolation. No luck so far. Following the instructions recevied in this thread and in this other thread this is what i've done:
I created a new project and inside the index.zul
page under DeployedResources/webapp
i have this code:
<?page title="" contentType="text/html;charset=UTF-8"?>
<zk>
<window title="" border="normal" xmlns:w="client">
<div id="wrapper" style="width: 500px; height: 500px;">
<div id="viewer" style="width: 400px; height: 400px;" w:onBind="doTheThing(this)">
</div>
</div>
</window>
<script type="text/javascript">
function doTheThing(wgt){
zk.load("mypackage", function() {
jq("$wrapper").css("background-color", "red"); // works fine
var iv1 = jq(wgt).iviewer({ // iviewer is not a function
src : "test.jpg",
zoom : 55
});
});
}
</script>
</zk>
Inside src/main/resources/web/js/mypackage
folder i have a zk.wpd
file with this content:
<package name="mypackage" language="xul/html">
<script src="jquery.js" />
<script src="jqueryui.js" />
<script src="jquery.mousewheel.min.js" />
<script src="jquery.iviewer.js" />
</package>
and in the same folder i also have all the .js files listed above.
From Chrome's developers tool i can see that mypackage.wpd is loaded and if i open it i can see the iviewer.js file imported.
The same files were used inside a .html file to display the content and it worked fine (in another zk project) however i can't find a way to make it work again in a .zul page.
The test.jpg
is put at the same level as the index.zul
page but i don't think it has impact on the message jq(...).iviewer is not a function
jq
refers is the custom variable name for ZK's internal version of jquery, by default it's the same js object as $
or jquery
. when loading a custom jquery version later jq
will remain ZK's version, and $
and jquery
will pick up your custom version. That's why jq(wgt).iviewer
fails.
the iviewer plugin is only loaded on your custom jQuery version.
also the custom jquery version is not aware of zk widget classes. so you'll have to use the DOM element corresponding to that widget. $(wgt.$n()).iviewer
should be defined (assuming the scripts were loaded successfully)
Asked: 2020-12-15 23:32:32 +0800
Seen: 33 times
Last updated: Jan 08 '21