0

Passing arguments to JS from Zk [closed]

asked 2018-03-12 15:58:52 +0800

pmoskala gravatar image pmoskala
3 2

updated 2018-03-13 10:07:21 +0800

cor3000 gravatar image cor3000
6280 2 7

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?

delete flag offensive retag edit

The question has been closed for the following reason "the question is answered, right answer was accepted" by cor3000
close date 2018-03-26 10:13:21

5 Answers

Sort by ยป oldest newest most voted
0

answered 2018-03-19 16:13:52 +0800

cor3000 gravatar image cor3000
6280 2 7

updated 2018-03-19 16:14:26 +0800

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

link publish delete flag offensive edit
0

answered 2018-03-13 10:39:31 +0800

cor3000 gravatar image cor3000
6280 2 7

updated 2018-03-13 10:43:19 +0800

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

link publish delete flag offensive edit
0

answered 2018-03-16 15:16:35 +0800

pmoskala gravatar image pmoskala
3 2

updated 2018-03-19 15:36:36 +0800

@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.

link publish delete flag offensive edit
0

answered 2018-03-19 10:00:17 +0800

cor3000 gravatar image cor3000
6280 2 7

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

link publish delete flag offensive edit
0

answered 2018-03-19 15:28:36 +0800

pmoskala gravatar image pmoskala
3 2

updated 2018-03-19 15:30:16 +0800

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...

link publish delete flag offensive edit

Question tools

Follow
1 follower

RSS

Stats

Asked: 2018-03-12 15:58:52 +0800

Seen: 38 times

Last updated: Mar 19 '18

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More