Given this:
view layout [ field [print "1" ] field [print "2"] ]
When I shift+tab from field #2 to field #1, no actions are fired.
How do I get them to fire just like a normal tab?
It is a bug in the key handler for field style in the Rebol/View engine. Here is a quick patch you can include in your code to fix it and make SHIFT+Tab work:
use [body f pos][
;-- patch `ctx-text/back-field` function to fix the bug
body: copy/deep second f: get in ctx-text 'back-field
insert body/2/while [if head? item [item: tail item]]
ctx-text/back-field: func first :f :body
;-- remove test that disables face/action for back-tabs
body: second get in ctx-text 'edit-text
body: find body 'word?
pos: at body/3/7/tab-char/5/6 11
change/part pos pos/4 4
]
This code will walk through View engine functions at run-time (code is data in Rebol) and hot-patch the functions bodies, by injecting or removing code where required.
If you happen to be a Rebol/SDK user, I can give you the instructions for patching the source files directly, so you can encap a fixed View executable.
Enjoy.
Related
Some functions that are used in the 'layout function do apparently not exist, yet 'layout works fine. But when you try to replace the 'layout function by an adapted version containing some debugging statements, the functions and undeclared variables will immediately cause an error.
The functions BIND? and BOUND? don't show results for, for example, the used TRACK function, so there is no extra information by using those.
Special interest in the do-facets and grow-facets functions.
Here are two ways to create anonymous contexts in Rebol 2:
context [
semi-hidden-function: does [print "ok"]
set 'non-hidden-function does [semi-hidden-function]
]
use [semi-hidden-function] [
semi-hidden-function: does [print "ok"]
set 'non-hidden-function does [semi-hidden-function]
]
In the first form you may reach the context of the word semi-hidden-function:
>> probe bound? first body-of :non-hidden-function
make object! [
semi-hidden-function: func [][print "ok"]
]
But in second form you may not:
>> probe bound? first body-of :non-hidden-function
make object! [
]
I see many Rebolers use one of above forms, not only to hide but to keep the main function clean and separate.
Here I also add the functions you like to see, it is a bit long so I compressed & enbased:
You can simply paste below line to the console, copy the below text and execute the line to decompress it:
write clipboard:// decompress debase trim/lines read clipboard://
eJyNVrty6zYQrcmvWKuJPWNFqXkn0Uyq29zbpeKwgMElhRgCOABoRfn67C7Ah5xkksJje3dxcPZ1w
N4fB6UxxQaG2Wlo6+rw62xsD2/W63fwA0wqqCsmDBGeletBpRTM25wQbj708QVuF2MRnE+g4MP0Yg
YfIKa7xR8PdRUn1DFHZ2OEE6ErC/luMAmvdUd3L1y0n+7QdnWVsVsGT8rYMwhWxzwrPkW0TYgpm9k
2QMR05LvO0HAEtG8B1TthVWjSBQM8OMnMh5Sj+wZD6VEGx0xVAsRWSLOh2+BWtsZFDGlJptwiiBxV
KWuhzZCCtqF3m188gnD85O/a5I/WZHvhsDi79u88Tt7Z+0JGsuRA+pEaNeDwj7VeZA7Yz5pKnJtU/
rugKmyo1vCFm4sLpAoI+KHsrBL2FBnwqe7qegz+9mmWHN4oely7PSnqFSS6n9K7qpFKqr31gevC9Z
WRi0DYkK6TNJkgTgsoQ9V19eV4hG+zTUbsQPfOE7HSGicm9ByTSkYzyozxpa7k1gZAW1RBhkoYPFg
yjWZnEUYPMZndPibnsLPQMR+4nZI194ZYLCMq9KkLN5P05dTjoCgJSPcJzydpLect/WTGTwDQqmlC
GotcN3LLPBiXcEQK+Gd3pO104+bN5V68aZ4sPm3Qpf6LW3Lc3HmUtrbkqTeCsELk3i3eOVh2/otXK
ra7vkzB4tYXlRPntr/jXfsem9Vr/Wj0U/H2Kime5duJ+72L6lETKpHYha3Zmyuu+OHhGHdAXHkl1+
UVceAF5SN5M2k2m7zJm61hnOVINbtkeKdpC5Lx7lwmQA7K+sl482ItITB4a/2tqOQrjDOpLjUa+wL
J09NA7zcoWNYrR3Qr3Y3fXk+adbyqVQl/gl9+JokfSDLPAjncjjSeF2iJGs2Zp8V3stRl+cvx/5fg
Evyf1IuM7Yhlrc8HBS8vFIZA78rhm4mRZpyN8xUdKa8Ph9yCFaiinCgFuYkzL8CTjyaZDzyvaVPKA
6IoDmynq4edXVhSVdBGfCUV/oEkx4F/+x11gmdiRZXCF4izvoAiQfNEi6z8eG6g1JwNF9qresf8To
yPZPkN4oKf8lhtZ7qNTP3pj/K7I47f5SmWRys/xrluJsoj7WiosH8Fqsci9zc/04t/UR8IWs3jhci
kegXdHppS/99cQO1HZ/7Efvs8aA7MPb81XdHpr/TBQCSuLNflcXiFIn35JTGO2mJYuIfgr2vmTZZ+
OXhiCQMpjojZ3hWJQ3aJCu5drDzZJRq0d4nsiCsL0N4niii+rI17X/4mYl/WxLr7C5ZY7idACQAA
You can find the definitions in the source files of the sdk
e.g
track: func [blk] [if verbose [print blk]]
in view-vid.r
Here a helper function to get the definition/source of a word/function in an unknown context and e.g. without access to the sdk
find-anon: func [ words fn /local ] [
foreach word words [
if word = fn [set :fn probe get word halt]
if block? word [
find-anon word fn
]
]
]
find-anon second :layout 'grow-facets
help grow-facets
I want to add GUI items from a series. I am trying following code but it does not work:
mylist: ["first" "second" "third" "fourth" ]
view[
foreach i mylist [
text i ]]
The error is:
*** Script Error: VID - invalid syntax at: [foreach ll mylist]
*** Where: do
*** Stack: view layout cause-error
Where is the problem and how can it be solved? Thanks for your answers.
Remember that...
view [... what goes in here...]
...is a dialect, it is not regular code. It's a special dialect that has some evaluative qualities, but the normal rules don't always apply.
Don't forget that a dialect is just a block of values like anything else in Red. You can pre-build it as such:
view collect [
foreach i mylist [
keep 'text keep i
]
]
You can stick a PROBE between VIEW and COLLECT there to see what you're generating and COLLECT/KEEP gives you a lot of scope for tuning the values that end up in your view spec.
Your problem is you are mixing dialects. You have a VID dialect inside the View block, but you're also using the DO dialect there as well which is not understood by View.
At least in Rebol you would add a do block as an initialization sequence inside the VID dialect eg.
view [
VID dialect goes here ...
do [ do dialect stuff that could initialize gui elements go here ]
]
So i'm trying to grab a row a of table headers off a page:
header_row = #page.send('header_row_element')
headers = header_row.ths.collect { |th| th.text }
table_of_elements.raw.flatten.each do |option|
expect(headers).to include option
end
Note: table_of_elements is coming from a Cucumber Table ie:
| value |
| another value |
| etc |
I'm having no problem finding the header row on the page and returning the values but my problem is that the table is in a scroll window
So the code headers = header_row.ths.collect { |th| th.text }is returning an array with only the headers that are within the view of the current location of the scroll:
headers = [ "value", "another value", "", "" ]
I can't seem to handle the side scrolling window to get the other headers in view. I've tried RAutomation, send_keys, nothing seems to work. I'm not sure why the ths.collect method wont return all the values regardless of visibility.
How the scroll window is implemented will impact whether detect the text as visible or not. For example, some scroll windows set the overflow text to be hidden, which will result in Selenium/Watir seeing no text. I believe it was some of the DevExtreme controls where I ran into this.
If there are no tags within the th elements, the easiest solution is to gather the inner HTML instead. This will allow you to bypass the visibility checks:
headers = header_row.ths.collect { |th| th.inner_html }
Here is the code pruned down to a minimum to show the error:
Rebol []
view center-face layout [
fld1: field
fld2: field
flds: [fld1 fld2]
]
Here is the shortest example to show the error:
layout [ test: []]
>>Misplaced item: []
Rebol uses a number of different dialects, and the two you are using in this example are the do dialect and the view dialect. Now inside the 'layout function, you can only have the view dialect but you have mixed the two. So, the parser used by the 'layout function complains of the misplaced item. The dialect expects to see after flds: one of the faces such as field, area, label etc but instead finds a block.
Regarding your clarification comment, if you wish to create a block of fields, you can just create the block first and then provide it to the 'layout function like this so that you end up with fields named var1 to var9.
lo: [ across ]
for i 1 9 1 [
repend lo [ 'label form join "var" i to set-word! join "var" i 'field 'return ]
]
view layout lo
This one is really simple. I've got a <select> and I want to update some internal state based on the selection. No need to redisplay anything. The problem is that after the selection and the AJAX request have been made, the list loses its contents.
renderContentOn: html
|value myId|
html form with: [
html select list: #('one' 'two' 'tree' 'four' 'five');
id: (myId := html nextId);
callback: [ :v | value := myId ];
onChange: (
html prototype updater
triggerFormElement: myId;
callback: [:h | value "do something with the value here"];
return: false
).
]
The #updater needs an DOM ID of the element to update. If you fail to provide an ID, it default to this, the DOM element triggering the event. Thus, you end up with an empty list. If you do not need to update something you should use #request instead of #updater. If you want to update something you need to provide a valid ID using #id:.
Read the section AJAX: Talking back to the Server of the Seaside Book, it explains AJAX in great detail.
Because the updater replaces the html of the element it was defined on with the content generated by the callback and your callback does not generate any html, the list is empty, I think.