-
FEATURED COMPONENTS
First time here? Check out the FAQ!
I have a js function, which do something, for example
<script type="text/javascript">
function doSomething(clickedCell){
alert(clickedCell);
}
</script>
And I want to pass to this function some objects from zul:
<grid id="dataGrid" model="@load(vm.items) @template('rowTemplate')">
<columns >
</columns>
<template name="rowTemplate">
<row children="@load(each.visibleColumns)">
<template name="children" var="col">
<cell
onClick='Clients.evalJavaScript("doSomething(col)")'
</cell>
</template>
</row>
</template>
</grid>
And when i click on the cell, the onClick event is fired, and invokes JS function, but doesn't pass the col reference. I got an error
script col is not defined (ReferenceError)
Is anyone, who could show me how to do it properly?
If you don't want to repeat the code you can override a prototype function on the Cell widget class directly using zk.override(...)
Here an updated example overriding the default behavior of every cell on that page in a single function override: http://zkfiddle.org/sample/3o1ci5f/3-prevent-row-click-when-drag-selecting-text
Robert
When using Children-binding the child array is iterated upon at server side. The Templates are instantiated at server side as well. So that the variable col
is only visible at server side, the client side doesn't know about it at all, unless you send the information to the client side as needed.
Here again your template:
<template name="children" var="col">
<cell onClick='Clients.evalJavaScript("doSomething(col)")'/>
</template>
onClick
is a server side listener which has access to the col
variable.
When putting the 3 characters c o l
into the String "doSomething(col)"
does nothing but sending/executing this exact string at client side.
In case your col
variable refers to a Java-String object you have to at least concatenate the String into valid JS code: "doSomething('" + col + "')"
(mind the single quotes around col to build a JS string)
If col
is not a String you still have to create a valid JS expression by accessing members accordingly:
"doSomething('" + col.getLabel() + "')"
"doSomething(" + col.getIndex() + ")" /*(no quotes around a number here)*/
This is just the blunt way to get it working... in order to implement it properly (without using a zscript event listener, and more MVVM compliant I would suggest something different) but it depends a bit on your scenario.
Do you want/need a server side event listener at all? Right now every click will go straight to the server just to return JS code to be executed (which has some limitations keyword "trusted events". JS code returned from the server will execute with limited privileges at client side and certain functions like opening new browser tabs might be blocked, or focussing other UI elements ... browsers are not consistent there) In your case the doSomething method would then be executed with limited privileges.
A pure client side event listener doesn't have those limitations if called directly from a user triggered event (such as a click).
<zk xmlns:w="client">
...
<template name="children" var="col">
<!-- again mind the single quotes around the ${col.label} producing a JS String literal -->
<cell w:onClick="doSomething('${col.label}')"/>
</template>
Now the client side listener w:onClick
doesn't need a server side round trip to call doSomething
with the pre-filled parameter.
There are other possibilities (client binding, data handler, AuInvoke, JSONAware) to make this more convenient ... so if you think non of the above feels right in your case just give a little more background so I can help with a more suitable/detailed example.
Also a runnable example on zkfiddle will help to understand your problem/question better and instantly provide a runnable response by just adding what's missing to produce the desired results.
Robert
@cor3000 The reason I wanted to do it is a fact, that when I'm trying to select text in cell, the event "onClick" is being generated after selection ends. I had an idea to use JS function, which checks if it was only a click or text selection, end eventually sends or not event to server.
if you can tell me you algorithm that distinguishes simple clicks from text selection events I might be able to help you integrating it with ZK. Imagine other methods of text selection... e.g. double/triple clicking will also select word/paragraph - The first click event will already be fired before the second/third clicks can be handled to determine text selection - at this time it's already too late to stop the first click event.
A simpler way to allow row selection is to provide a dedicated checkbox for row selection. So that mouse clicks while selecting text don't interfere.
e.g. here a simple case http://zkfiddle.org/sample/3o1ci5f/2-check-row
Unfortunately, I can't change the way of selecting text - the standard mouse selection is required.
I tried something like this:
<cell onClick="@command('doSomethingOnServerSide', col=col)"/>
<attribute w:name="doClick_">
function (evt) {
if(window.getSelection().type != "Range"){
this.$doClick_(evt);
}
}
</attribute>
by overriding onClick method of each cell, and checking if there was selection or not. If not - call the super method doClick_. It works, but the performance is considerable. While analyzing the HTML code, i noticed this little function multiplied for each cell (e.g 1000 cells per page - 1000 JS functions). I'm searching for more general solution...
Asked: 2018-03-12 15:58:52 +0800
Seen: 38 times
Last updated: Mar 19 '18