Package loading (cloud kernel) and code embedding (local kernel) revisited:
An APIfunction loads a package in the cloud by including CloudGet[Cloudobject[package]] in the pure function argument. So a form should work in just the same way.
A form consists of a form, and when submitted a reply. We need a navigation bar on the form and on the reply page. I created a package that generates a simple navigation bar.
Because of the "form" and the "reply" page are in the cloud processed by different kernels we need to load the package 2 times.
It is my intention to link the code and not embed it into the cloud object. Therefore it is necessary to make sure the 2 CloudGet[CloudObject[]] commands are NOT evaluated by the local kernel.
If this would happen the package would load in the local kernel, the context is added to $Contextpath, resulting in a --second-- CloudDeploy evaluation with embedded code.
The CloudGet[CloudObject["rkc.wl"]] in the FormFunction does not seem to be the problem. The contents of ()& is not evaluated by the local kernel.
The second CloudGet[CloudObject["rkc.wl"]] in the rhs of the FormLayOutFunction is a problem because it is evaluated by the local kernel. Because the package gets loaded rkc is put on the
contextpath and the --second-- clouddeploy evaluation results in all code embedded in the cloudobject.
The question is "how to load a package by the cloudkernel in the form submit side."
I tried a few things like RuleDelayed, a Delayed on the CloudGet, and changing Function[] in (( )&) but no luck.
Here is the form code
tst = CloudDeploy[
FormFunction[
FormObject[
<| {"firstname", "First Name:"} -> "String",
{"lastname", "Last Name:"} -> "String",
{"wlexperience", "WL experience"} -> <|
"Interpreter" -> Restricted["Number", {1, 10}],
"Hint" -> "min is 1 and max is 10"|>
|>,
AppearanceRules -> <|
"SubmitLabel" -> "go to database"|>
],
(CloudGet[CloudObject["rkc.wl"]];
(*URL database fetchremoved *)
ExportString[
StringJoin["<center>",
ExportString[
Grid[{
{rkc`inav["a_adddata"]},
{Style["Your record has been added", 22]}}],
"HTMLFragment"
], "</center>"]
, "HTMLFragment", "FullDocument" -> True]
) &,
"HTML",
FormLayoutFunction ->
Function[
CloudGet[CloudObject["rkc.wl"]];
Grid[{
{Style["Please enter data", 28], SpanFromLeft},
{rkc`inav["adddata"] , SpanFromLeft},
{#["firstname", "Label"], #["firstname", "Control"]},
{#["lastname", "Label"], #["lastname", "Control"]},
{#["wlexperience", "Label"], #["wlexperience", "Control"]}
}, Alignment -> Center]
],
FormTheme -> "Blue"],
"/adddata", Permissions -> "Public"]
check the ContextPath to find rkc on it.
Main Problem : rkc is now visable! When you evaluate the CloudDeploy for a second time this results in unwanted embedding of code. (use CloudImport to check).
CloudImport[tst, "Text"]
Here is the package. The function inav[] is used in the CloudDeploy. rkc`inav["adddata"] results in 2 buttons with Home and Query labels on the buttons plus a timestamp.
rkc`inav["adddata"] (*to test package *)
Put this in a package and copy it to the cloud with :
CopyFile["e:\folder\rkc.wl", CloudObject["rkc.wl"]];
BeginPackage["rkc`"]
Unprotect[inav];
inav::usage = "inav[pagename] pure expression returned"
Begin["`Private`"]
inav[pagename_] :=
Row[mkb[#] & /@
Transpose[{nb[pagename], Lookup[lbl, #] & /@ nb[pagename]}]]
mkb[{lnk_String, lbl_String}] :=
Hyperlink[
Graphics[{EdgeForm[{Thin, Gray}],
LightBlue,
Rectangle[{0, 0}, {4, 1}], Black,
Text[Style[lbl, 11, Black], {0.5, .5}, {Left, Center}]},
PlotRangePadding -> None, ImagePadding -> 0,
ImageSize -> {120, 30}], lnk]
dd := DateString[{"Time"}]
nb := <|"splash" -> {"rkcform1", "rkcform2"},
"adddata" -> {"splash1", "readdata1"},
"a_adddata" -> {"splash1", "adddata1", "readdata1"},
"readdata" -> {"splash", "adddata"},
"a_readdata" -> {"splash", "adddata", "readdata"}|>
lbl := <|"login" -> "enter" <> dd, "splash1" -> "Home" <> dd,
"adddata1" -> "Add" <> dd, "a_adddata1" -> "Add result" <> dd,
"readdata1" -> "Query" <> dd, "a_readdata1" -> "Q result" <> dd|>
End[]
EndPackage[]
Note : when investigating a solution make sure your browser is not caching anything. This will trick you into thinking it worked but it served you old data. (in chrome ctrl - shft - I then rightclick the reload button)
finally the message above is not scrambled ...