FoxInCloud
Error when drawing a grid
Gravatar is a globally recognized avatar based on your email address. Error when drawing a grid
  Paul
  All
  Jan 16, 2019 @ 03:28am

Hi,

I have a form with an "empty" grid in it (no recordsource or columns) and at runtime I programatically configure the grid - set the recordsource, add the columns etc etc.

The code that does this works correctly, but after the code exits and it is being turned into HTML I receive this error :

Form stockcontrolcheckarea : AWAJAX.CRESULTADD - awajax.lSuccess(.f.): Error detected at code line #15,193 of method 'awajax.propchangedhtml_grid'
"Method or procedure gethtml_grd_aw_cscript_events_cols(): error #1924 ("COLUMNS is not an object") at code line #12,856 (source code N/A)"
FoxInCloud Application Server will attempt to re-instantiate form 'stockcontrolcheckarea' and retry the user request.

I see that awgrd has a wlContentDynamic property, but not a wlContentChanged property; I set wlContentDynamic = .T., but the error still occurs so I don't know if I need to do that or not.

Any ideas?

Thanks Paul

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Vincent H.
  Paul
  Jan 16, 2019 @ 10:23am

Hi Paul,

Forgot a dodefaut () ?

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Jan 16, 2019 @ 01:49pm

Because digging into the grid members is faster than regenerating HTML for a container's members, we've omitted .wlContentChanged

To my knowledge, this error happens only when use in (.recordSource) without prior setting .recordSource = ''.

If that helps, you have a sample form using .wlContentDynamic: MODIFY FORM home(1) + "tools\ab\aw\samples\fic\fictuto\progs\forms\dataupdate.scx"

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Jan 24, 2019 @ 08:09pm

The answer was to put some code in the this.wlInitFirst section of the form's Init() :
...use the view nodata
Grid.wlContentDynamic = .T. Grid.RecordSource = "alias of the view"
...configure the grid and its columns

It is not enough to have that code executed later in response to a user event, it appears that the columns must be defined during wlinitFirst.

Paul

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Jan 25, 2019 @ 01:31am

Thanks for the follow up; we'll try to reproduce and find a workaround

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Jan 30, 2019 @ 02:29pm

Actually I was wrong, my code change did not fix the problem (I was accidentally not creating any columns).

So I have gone back to the original code pattern, where the grid is initially unconfigured (.recordsource = "") and I only set things up in the user event.

I am still trying different things to make this work, but in the meantime here are some things I have noticed :

  • I can see 2 instances of the form being created by FiC when I navigate to the form - is this normal?
    At the moment I am calling the form by :
  1. logging in using a login form
  2. displaying a menu form
  3. navigating to index.htm and running my form from there, as the menu form isn't working yet
  4. note that form.wlPrivate = .F.
  • In the user event (textbox.Valid) I set up the grid. When I add a column via grid.AddObject() it runs the FiC code and it crashes because I have grid.wlContentDynamic = .T.
    This is the FiC code :
if lProperty(m.this, 'wlContentDynamic') and m.this.wlContentDynamic   && Si wlContentDynamic, tout le HTML contenu est régénéré à chaque requête  
this.wlContentChanged = .T.  
...

The problem is that a grid does not have a wlContentChanged property.

.

Incidentally, I have observed another strange problem while testing that form.
In the Load of the form I open view A and in the Init of the form, inside the wlInitFirst section, I open view B.
FiC has created 2 instances when the form is requested, as I mentioned above, with DataSessionID's of 16 and 18 - I'll refer to them as 16 and 18.
I see the Load of 16 and 18 executed once each - view A is open in each
I see the Init of 16 executed once, with wlInitFirst = .T. - views A & B are now open in 16
I see the Init of 18 executed once, with wlInitFirst = .T. - views A & B are now open in 18 and when I look at 16 I see that view B is no longer open in that datasession!!
I see the Init of 16 executed again, with wlInitFirst = .F. - view A is open and view B is not
Looking at 18, views A & B are open

Wow, really confused. Sure, I could open each view in the Load and requery later on (they are parameterised), but ... do I have to?

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  Paul
  Jan 30, 2019 @ 08:50pm

I notice in your FiCTuto example, the columns are defined in the Init of the grid and the grid.recordsource and column.controlsource is not set until the Init of the form, after the this.wlInitFirst section.

Is this the timing that must occur for a grid that is built at runtime?
Do the columns have to be defined prior to the form's Init?
When is the HTML for a (.wlContentDynamic = .T.) grid and its columns actually generated?

Thanks
Paul

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Jan 31, 2019 @ 01:50am

I could open each view in the Load and requery later on (they are parameterised), but ... do I have to?

Definitely YES; All views and CAD must be USEd before calling dodefault() in form.load()
(notice the name of the fake parameter to this method inherited from awFrm.Load(): reminder_in_your_subclass_call_DoDefault_after_opening_all_views_and_cursorAdapters -- generally speaking, please take some time to review the aw*.method code when implemented, it often contains useful documentation).

Here is the call stack:

yourForm.Load()
yourFormClass.Load()
awForm.Load()
  …
  this.AddObject('wColView', m.this.wColViewClass) && by default awColView of aw.vcx
awColView.Init()
  this.wSaveAll(@m.result)
    this.wSave() && stores a view definition object as a member of the collection

FoxInCloud automatically closes views that were not identified at awForm.Load():

procedure awColView.wRestoreAll

…
for iView = 1 to m.nView && unused views
	cView = m.aView[m.iView]
	success = !wlAppHost(@m.oAppHost) or m.oAppHost.AliasRecordSourceClear(thisForm.DataSessionID, m.cView) && always returns .T.
	use in (m.cView) && here it is…
endfor

This behavior explains this:

when I look at 16 I see that view B is no longer open in that datasession!!

Not sure why we implemented that back in 2015, probably after a thorough analysis… we could add a property to work around this behavior, however it could only be applied to non-parameterized views as views need be registered in .wColView to get an automatic requery() when restoring datasession for the user.

Only one rule: USE view NODATA in dataEnvironment or form.Load(), call dodefault(), .wViewParmSet() in form.Init() after the this.wlInitFirst section, and/or in any user event method, and/or .Refresh_().

This obeys the standard VFP coding pattern where all data are made available before member objects get instantiated to let them set their .*Source on the USEd data.

FiC has created 2 instances when the form is requested

Not sure why… maybe you could post the content of the goWCserver.oAppHost.aForms array like illustrated here (from the debugger locals window):

The problem is that a grid does not have a wlContentChanged property

Typo on our side because we generate the code of all classes having .wlContentDynamic using the same method; maybe you could:

modify class awGrd of aw method addObject

&& replace
this.wlContentChanged = .T.

&& by
this.addProperty('wlContentChanged', .T.)

Is this the timing that must occur for a grid that is built at runtime? Do the columns have to be defined prior to the form's Init?

Not intended so…

We paid more attention to your original post and noticed the error occurs during a user event, while refreshing the grid, as opposed to initial HTML/CSS/JS generation:

Error detected at code line #15,193 of method 'awajax.propchangedhtml_grid'
awajax.*() run only in response to a user event, or form.Init().

Looking at the code in Method gethtml_grd_aw_cscript_events_cols() where error occurs, there is a mismatch between .columnCount and actual .columns.count. This happens generally when closing (.recordSource) without prior .recordSource='': VFP destroys the columns without changing .columnCount

Just a trail to look into, not exactly sure.

At some point you may need the full version (with source code) to run in debug mode and be able to see all the variables and properties when error occurs.

When is the HTML for a (.wlContentDynamic = .T.) grid and its columns actually generated?

Initially, at .wlInitFirst, and upon each user request in case of a change.

If grid.wlContentDynamic, as it's difficult and maybe impossible to update the structure of the ActiveWidget grid, FoxInCloud compares the XML describing the grid before / after the event (stored in a record labeled GRIDRS in the form state table) and, in case of any structural change, re-generates everything (actually JavaScript as ActiveWidget only works in JS).

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Feb 1, 2019 @ 08:35am

Next week we’ll create a ‘dynamic grid’ sample in FoxinCloud Live Tutorial.

Hopefully you’ll find in it answers to your issues.

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  Paul
  FoxInCloud Support - Thierry N.
  Feb 10, 2019 @ 06:16pm

FiC creates 2 instances of the form stockcontrolcheckarea.
stockcontrolcheckarea has this class hierarchy :
form, awfrm, sficfrm, standardfrom, privatedataform, mfgprivatedataform, shopfloorbaseform, stockcontrolbaseform, stockcontrolcheckarea Instance 1

Instance 2

After instance 2, here is _screen.forms (note the duplicates) :
Note that it appears that maybe the first instance of stockcontrolcheckarea was created before the instance of its parent class, stockcontrolbaseform, just looking at the order of the forms here.

And yet, stockcontrolcheckarea only occurs once in the aforms array :

Still playing with the grid, trying to make it work.
So far I can confirm that by the time my grid initialisation code finishes, the grid contains 8 columns and grid.ColumnCount = 8.

Gravatar is a globally recognized avatar based on your email address. re: Error when drawing a grid
  FoxInCloud Support - Thierry N.
  Paul
  Feb 10, 2019 @ 11:54pm

Hi Paul,

Yes, FoxInCloud instantiates each class during the HTML generation process, to assign the CSS properties to the right class level (see awDefault*.css).

There might be another way using pemStatus() however we could not make it work so far.

Late on the 'dynamic grid' sample, we'll work on that this week.

© 1996-2019