Edit contents of field displayed in a datagrid form

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
Simon Knight
Posts: 916
Joined: Wed Nov 04, 2009 11:41 am

Edit contents of field displayed in a datagrid form

Post by Simon Knight » Sun Oct 08, 2023 9:09 am

Some of you may remember that despite using RunRev/Livecode for rather to long I have generally avoided datagrids due to their complexity and their ability, when used by me, to produce difficult to trap errors. Well o.k. its not the datagrid's fault. Anyway yesterday I decided that it was time that I tried to use one of these new fangled datagrid forms (introduced circa 2009!).

My design is simple : each row of the form displays a thumbnail image and a text field respectively named "Thumbnail" and "Title". The datagrid form is populated by setting the dgdata and both controls are populated as expected. So far so good. I am presently falling "flat on my face" when trying to enable editing of the text displayed in the field "Title". I am trying to follow the lesson published here https://lessons.livecode.com/m/datagrid ... -grid-form but without any success.

Generally I am happy with the concept of a second hidden field being placed over the target field to allow editing as I have used similar techniques in my own custom controls but I am finding the messages triggered difficult to understand.

First, though, please confirm that I do have to add extra code to edit text? I ask just to make sure I have not made a school boy error.

I have added the following handlers to the behavior script. These are straight copies from the lesson.

Code: Select all

## The following handlers are copied from a lesson which makes little sense at the moment
 
on mouseDown pBtnNum
   if pBtnNum is 1 then
      ## Did the user click on the Title field?
      if the short name of the target is "Title" then
         put "Title" into theKey
         put the dgHilitedIndex of me into theIndex
         EditKeyOfIndex theKey, theIndex
      end if
   end if
end mouseDown

on EditValue pKey
   ## Example of opening a field editor for the field displaying the value for pKey
   ## Since I'm passing in parameters 2 and 3 any changes will automatically be saved to the dgData.
   ## 'me' is the Data Grid in this case.
   EditFieldText the long id of field pKey of me, the dgHilitedIndex of me, pKey
 end EditValue
 
 on CloseFieldEditor pFieldEditor
   ## 'me' is the row control
   put the dgIndex of me into theIndex
   put the dgDataOfIndex[theIndex] of the dgControl of me into theDataA
   put the text of pFieldEditor into theDataA[the dgColumn of me]
   set the dgDataOfIndex[theIndex] of the dgControl of me to theDataA
 end CloseFieldEditor
The first handler is clear until the line
EditFieldText the long id of field pKey of me, the dgHilitedIndex of me, pKey
the dictionary describes as
Same as EditKey but uses an index rather than a line number to located the line to edit.
and edit key as
Sends the EditValue pKey message to the row control for line pLineNo.
. So this sort of explains how EditValue is called.

Now I partially dispute the following
## Since I'm passing in parameters 2 and 3 any changes will automatically be saved to the dgData.
Firstly what and/or where are parameters 2 and 3 ? Secondly, yes data is saved back as long as I disable the CloseFieldEditor handler beforehand. When enabled, as above, the field editor is displayed in the first row no matter which row I click on and any edits are not saved.

The tutorial instructs readers to read up on several commands including the "editFieldText" . Unfortunately the dictionary entry is written in the style of a 1940s mathematics text book. Here is the description in full for you to enjoy.
This command will dynamically create an editable field for editing the contents of pField (pass in the long id of a field for pField). Calling EditFieldText will trigger additional messages related to field editing. Scenario 1: Pass in one parameter If you just pass in pField and leave pIndex and pKey empty then the data grid behaves as follows:

Creates field editor
Assign text of pField to field editor
Sends preOpenFieldEditor pFieldEditor to pField.
pFieldEditor is the long id of the field editor created in step 1. When editing stops (focus leaves field, user presses escape key, etc.) the message DeleteFieldEditor is sent to the data grid. This in turn sends CloseFieldEditor pFieldEditor to pField if the user changed the content or ExitFieldEditor pFieldEditor if no change was made. You can use these messages to save any changes the user made in pFieldEditor. Scenario 2: Pass in all three parameters If you pass in all three parameters (pField, pIndex, pKey) then the data grid will automatically save any changes made while editing. The new value will be assigned to the key pKey for index pIndex in the dgData array of the data grid. In this scenarios CloseFieldEditor pFieldEditor and ExitFieldEditor pFieldEditor are still sent. The difference is that after CloseFieldEditor is sent to pField the contents of pFieldEditor are saved in the dgData. If for any reason you do not want the data to be saved then you can return "cancel" from CloseFieldEditor. Note: If the user presses the tab key while editing and the autotab property of pField is true then the message OpenNextFieldEditor pDirection is sent to pField. If you don't handle this message and the data grid is a table then the data grid automatically opens the next cell for editing. For data grid forms you can handle this message in order to open another field for editing. You could call EditKeyOfIndex for Example. Note 2: The default behavior for

pFieldEditor is located in button "Field Editor" of stack "revDataGridLibrary". If you want to override this behavior then you can assign the behavior of pFieldEditor to another button in the preOpenFieldEditor message.
As a native English speaker I feel I need half a day to unpick the gems that are hidden in the description quoted above. There has to be a better description somewhere.

Would someone be so kind as to put me out of my misery and tell me what handlers I need to add to enable the editing of the data via a single text field ?

I enclose my work so far in the form of a zipped stack file for you to weep over. The stack requires a folder of jpeg images to work on.
CSV-Generator.livecode.zip
datagrid form on stack
(13.54 KiB) Downloaded 73 times
best wishes and thanks for getting this far,

Simon
best wishes
Skids

Simon Knight
Posts: 916
Joined: Wed Nov 04, 2009 11:41 am

Re: Edit contents of field displayed in a datagrid form

Post by Simon Knight » Sun Oct 08, 2023 9:50 am

I think that the lesson contains errors. For example the lines

Code: Select all

put the dgHilitedLine of me into theLineNo
and

Code: Select all

put the dgHilitedLine of me into theLineNo
return the value of 1 when they are in the behavior of the row template, as per the instructions
## Placed in script of row template behavior
. This makes sense as the behavior script refers to a single row.

So the code needs moving to the group script or possibly the "of me" needs replacing with "of my parent". I will try both.
best wishes
Skids

Simon Knight
Posts: 916
Joined: Wed Nov 04, 2009 11:41 am

Re: Edit contents of field displayed in a datagrid form

Post by Simon Knight » Sun Oct 08, 2023 10:49 am

Spotted my first error : The text should be a label type field and not a normal field. A normal field has its own editing internals and these suppress some messages including mouse double up. These internals collide with the field editor of the datagrid.
best wishes
Skids

Simon Knight
Posts: 916
Joined: Wed Nov 04, 2009 11:41 am

Re: Edit contents of field displayed in a datagrid form

Post by Simon Knight » Sun Oct 08, 2023 11:22 am

Hmmm talk about a suckers gap......

I think I have it working. I read some of the comments that follow the lesson and Elanor wrote this :
If you have a look at the script for the row in a new Data Grid form you will see that there is a mouseDoubleUp handler which checks the target and calls EditFieldText.
This led me to the discovery that I should not be using a normal edit field and also that the message watcher does not list mouse ups, or at least mine does not.

The boiler plate code that Elanor refers to works but the script does not include a CloseFieldHandler. I guess that one is included in the datagrid stack and that it is designed to work with the table form of datagrid. I also suspect that it was copy and pasted into the tutorial where it caused me some confusion.

After some head scratching my revised CloseFieldHandler looks like this:

Code: Select all

on CloseFieldEditor pFieldEditor
   ## 'me' is the row control
   put the dgIndex of me into theIndex
   put the text of pFieldEditor  into tNewText
   --put the dgColumn of me into tColumn
   
   ##put "The dgIndex is : " & theIndex & cr into field "debug" of card 1 of stack "CSV-Generator"
   ##put "The text is : " & tNewText & cr after field "debug" of card 1 of stack "CSV-Generator"
   ##put "The dgColumn is : " & tColumn & cr after field "debug" of card 1 of stack "CSV-Generator"
   
   put the dgDataOfIndex[theIndex] of the dgControl of me into theDataA
   put the text of pFieldEditor into theDataA["Title"]
   
   set the dgDataOfIndex[theIndex] of the dgControl of me to theDataA
end CloseFieldEditor
I have deliberately left my debug code in as it is needed for debugging as the IDE gets its knickers in a twist when break points are added. I may rename "theDataA" to "tRowRecordA" which is a better description.

Reviewing the variable "theDataA" in the IDE showed a ghost value as the very first item in the list and shows the updated text:
Screenshot 2023-10-08 at 10.58.34.png
ScreenShot of IDE

The new text is listed first in the list of Array keys but does not exist inside the array.

Datagrids are indeed strange and complex!

I am sure my code can be improved and I have no idea of the point of the tutorial which confused me.

As all ways I welcome your comments.
S
best wishes
Skids

Simon Knight
Posts: 916
Joined: Wed Nov 04, 2009 11:41 am

Re: Edit contents of field displayed in a datagrid form

Post by Simon Knight » Sun Oct 08, 2023 11:31 am

I have just remembered a question. The mouse double up handler is

Code: Select all

if pMouseBtnNum is 1 then
      if the dgProps["allow editing"] of the dgControl of me then
         put the short name of the target into tShortName
         switch the short name of the target
            case "Title"
               put "Title 1" into theKey
               put the long ID of the target into tLongID
               put the dgIndex of me into tdgIndex
               EditFieldText the long ID of the target, the dgIndex of me, theKey
               break                 
         end switch
      end if
   end if
   pass mouseDoubleUp
Why is the figure 1 required in the variable theKey, why isn't the key just "Title" which is the name of the field and the array key in dgdata ?
best wishes
Skids

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”