Subscribe for automatic updates: RSS icon RSS

Login icon Sign in for full access | Help icon Help
Advanced search

Pages: [1]
  Reply  |  Print  
Author Topic: Copy Entire Table from Display Array  (Read 9979 times)
Tim S.
Posts: 26


« on: November 04, 2008, 10:51:43 pm »

When doing display array to a table container, the right-click menu offers an option for "Copy Visible Table". Is there an option somewhere for "Copy Entire Table"?

Thanks,
Tim Sodowsky
Sebastien F.
Four Js
Posts: 509


« Reply #1 on: November 05, 2008, 09:19:21 am »

Tim,

The client has only a window (page) of the complete list of rows, this is why there is only a "Copy Visible Table" option, that copies the visible rows (i.e. rows of the current page).

To copy all rows to the clipboard, for now you have to code this by hand, and use the cbset front-end call to pass the values.

https://4js.com/techdocs/genero/fgl/devel/DocRoot/User/FrontEndFunctions.html#STANDARD

    ON ACTION tablecopy
       LET sb = base.StringBuffer.create() -- previous ref will be destroyed
       FOR i=1 to DIALOG.getArrayLength("sr")
              LET s = a.col1, "\t",
                      a.col2, "\t",
                      a.col3, "\t",
                      a.col4, "\t",
                      a.col5, "\t",
                      "\n"
              CALL sb.append(s)
       END FOR
       CALL ui.Interface.frontCall("standard","cbset",[sb.toString()],[])

In 2.20 we will have multi-row selection in tables, and maybe we will also have implicit "tablecopy" action to copy selected rows in the client clipboard - but this is under discussion...

https://4js.com/techdocs/genero/fgl/devel/DocRoot/User/NewFeatures.html#MultiRowSelection

Seb
Tim S.
Posts: 26


« Reply #2 on: November 05, 2008, 03:28:38 pm »

Seb,

Thank you for the tablecopy sample as well as the answer to my next, unasked, question about multi-row selection.

  When do you expect 2.20 to be released?


I have used the frontCall style to create my own tablecopy action that is specific to the defined array.
That, in turn, leads to another question:

  Is there a way to go through the elements dynamically so that I do not have to hard-code the column names and so that I could possibly copy only the columns that are visible on the user's screen?

Thanks for your help,
Tim S
Reuben B.
Four Js
Posts: 1049


« Reply #3 on: November 05, 2008, 09:32:08 pm »

Tim,

The answer is yes.

A few years ago before I joined 4Js, I wrote such a routine so that every DISPLAY ARRAY and every INPUT ARRAY had a 'Copy Entire Table to Clipboard'  function that copied the array as the user saw it (i.e respected sort order, hidden columns, columns moved around).

The technique I used went something like this...

1. Replace END DISPLAY and END INPUT in the code with END_DISPLAY(array_variable) and END_INPUT_ARRAY(array_variable)

2. Define a pre-processor command like so ...

&define END_DISPLAY_ARRAY(p1) ON ACTION copy_entire_table_to_clipboard(base.TypeInfo.create(p1)) END DISPLAY
&define END_INPUT_ARRAY(p1) ON ACTION copy_entire_table_to_clipboard(base.TypeInfo.create(p1)) END INPUT

3. Create a function

FUNCTION copy_entire_table_to_clipboard(om)
DEFINE om.DomNode

4. Inside this function, what you have to do is build up the string buffer like in Sebs example but instead of having to refer to explicit column names, traverse the serialized version of the array variable aka the DomNode. If you ignore sorting, hidden columns etc, this is something like

DEFINE row, column om.DOmNode
DEFINE rowList, columnList om.NodeList
DEFINE sb base.StringBuffer

LET sb = base.StringBuffer.create()

LET rowlist = om.SelectByTagName("Record")
FOR i = 1 TO rowlist.getLength()
   LET row = rowlist.item(i)
   LET columnlist = row.SelectByTagName("Field")
   FOR j = 1 TO columnlist.getLength()
      LET column = columnlist.item(j)
      CALL sb.append(column.getAttribute("value"))
      CALL sb.append(ASCII(9))
   END FOR
   CALL sb.append(ASCII(10))
END FOR
CALL ui.Interface.FrontCall("standard","cbset",[sb.toString()]

5. Once you have that stage working then gradually add in the ability to cope with these things...

i) handle the case where the value you are copying has a TAB or CR character, you want to delimit or quote or do something to these values
ii) the user has sorted the array, the sortColumn and sortType are in the ui.Interface root node.  If there are ties, the tie-break rule is to use the index of the array
iii) the user has hidden the column, the hidden attribute of the column in the AUI tree will have value 1 or 2
iv) the user has moved the columns around, from memory look at the tabIndex attribute of the column in the AUI tree. 
v) add column headers which are again available in the AUI tree
vi) maybe add an interrupt flag to cope with very large arrays.

What I never figured out was a way to cope with the case where two or more columns had the same tab index value.  This was never a problem for me as our code standard was not to use TAB INDEX.
Also with combo-boxes the value will be the raw value, not the display value, you may want to interrogate the AUI tree to get the display value not the raw value.

Hope that helps, feel free to ask any questions and I'll see what I can remember, or I may have to ask my former colleagues to help fill in the gaps.

As Seb said, this topic is under consideration for inclusion in 2.20.  If anyone else wants this functionality then let us know.  The more that ask for a feature, the more it is likely to be included.

Reuben

Product Consultant (Asia Pacific)
Developer Relations Manager (Worldwide)
Author of https://4js.com/ask-reuben
Contributor to https://github.com/FourjsGenero
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines