Background Information
The attached notebook provides examples of how to stylize for a FormFunction[] of CloudDeploy[].
The deployed function is HERE on the Wolfram cloud.
The attached notebook specifically demonstrates the following by example:
How to nicely format numbers having large exponents in input fields;
How to nicely format numbers having large exponents in results;
How to adjust the size of an input field;
How to get subscripts within FormFunction text;
How to get overbars on characters within FormFunction text;
How to stylize elements inside the FormFunction[ ];
How to do a layout within FormFunction[ ], including embedding the result and avoid a submit button (the FormPage[ ] function is much less controllable, so its functionality is reproduced within the FormFunction[ ] approach used herein);
How to display equations in a visually appealing way in vector graphics.
The attached notebook also answers my questions previously posted here.
Set Up: Options
Allow any member of the public to use the FormFunction's (i.e., does not require log in through Wolfram community)
cloudDeployOptions = {Permissions -> "Public"}
Out[]= {Permissions -> "Public"}
Width of InputField in the deployed FormFunction's
inputFieldSize = 25
Out[]= 25
Precision of numbers in the Input (i.e., InputField's) in the deployed FormFunction's
inputPrecision = 6
Out[]=6
Precision of numbers in the Output of the deployed FormFunction's
outputPrecision = 6
Out[]=6
Set Up: Functions
Formatting Expressions
Convert numbers to FortranForm (e.g., for InputField's). Avoid long numbers with many decimals points by using SetPrecision within ToString.
toFormForInputField[value : _Missing] := ""
(* 1. How to nicely format numbers having large exponents in input fields *)
toFormForInputField[value : _?NumberQ] :=
ToString[SetPrecision[value, inputPrecision], FortranForm]
Show either as '0.0025' for exponents of 4 and smaller or in superscript form of '2.5 10^-6' for larger exponents. This function is basically a customized version of NumberForm.
(* 2. How to nicely format numbers having large exponents in results *)
toFormForOutput[value : _] :=
Module[
{mantissaExponent, mantissa, exponent,
numericalValue = SetPrecision[N[value], outputPrecision]},
CompoundExpression[
mantissaExponent = MantissaExponent[numericalValue],
mantissa = 10 First@mantissaExponent,
exponent = Last@mantissaExponent - 1,
If[
(*if*)
-4 <= exponent <= 4,
StringTemplate["`1`"][numericalValue],
(*else*)
StringTemplate["`1` \[Times] 10<sup>`2`</sup>"][mantissa, exponent]
]
]
]
Input Fields
See FormObject[] and Interpreter[] (e.g., tied also to "Control" for something fancy like an 'Image' in 'guide/InterpretingStrings').
inputField[deployVariable : _String, label : _String | _Style,
initialInput : _String | _Missing,
interpreter : _ : Restricted["Real", {0, Infinity}]] :=
deployVariable ->
<|
"Label" -> label,
(* 3. How to adjust the size of an input field [I picked up this hint on the forums] *)
"Control" -> Function[InputField[##, FieldSize -> inputFieldSize]],
"Input" -> initialInput,
"Interpreter" -> interpreter (* declared default if omitted: Restricted[
"Real",{0,Infinity}] *)
|>
HTML templates
Basic elements of bold, italics, superscript, and subscript
CompoundExpression[
(* 4. How to get subscripts within FormFunction text (i.e., mix in HTML coding such as <sub>character</sub>)*)
(* 5. How to get overbars on characters within FormFunction text (i.e., mix in CSS coding such as "<span style=\"text-decoration:overline\">character</span>")*)
htmlBoldTemplate=StringTemplate["<b>`1`</b>"] (* [expression] *),
htmlItalicsTemplate=StringTemplate["<i>`1`</i>"] (* [expression] *),
htmlSubscriptTemplate=StringTemplate["<sub>`1`</sub>"] (* [expression] *),
htmlSuperscriptTemplate=StringTemplate["<sup>`1`</sup>"] (* [expression] *)
];
Assembled elements - level 1
htmlSubscriptItalicsTemplate=StringTemplate["<* htmlItalicsTemplate[#1] *><* htmlSubscriptTemplate[#2] *>"]
(* [symbol, subscript] *) ;
htmlSuperscriptItalicsTemplate=StringTemplate["<* htmlItalicsTemplate[#1] *><* htmlSuperscriptTemplate[#2] *>"]
(* [symbol, subscript] *) ;
Assembled elements - level 2
htmlTermListTemplate=StringTemplate["<* htmlSubscriptItalicsTemplate[#1,#2] *>, `3`"]
(* [symbol, subscript, name] *);
htmlInputLabelTemplate=StringTemplate["<* htmlSubscriptItalicsTemplate[#1,#2] *> (<* StringRiffle[#3] *>)"]
(* [symbol, subscript, {units}] *);
htmlResultTemplate=StringTemplate["<* htmlSubscriptItalicsTemplate[#1,#2] *> = `3` <* StringRiffle[#4] *>"]
(* [symbol, subscript, result, {units}] *);
HTML functions with styles included
For term list:
htmlTermList[name:_String,symbol:_String,symbolSubscript:_String]:=
Style[htmlTermListTemplate[name,symbol,symbolSubscript],termStyle]
For label on input field:
htmlInputLabel[symbol:_String,symbolSubscript:_String:""]:=
Style[htmlSubscriptItalicsTemplate[symbol,symbolSubscript],inputLabelStyle]
htmlInputLabel[symbol:_String,symbolSubscript:_String,units:_List]:=
Style[htmlInputLabelTemplate[symbol,symbolSubscript,units],inputLabelStyle]
For formatting output:
htmlResult[symbol:_String,symbolSubscript:_String,result:_?NumberQ,units:_List]:=
Style[htmlResultTemplate[symbol,symbolSubscript,toFormForOutput@result,units],outputStyle]
htmlResult["P",result:_?NumberQ]:=htmlResult["P","",result,units["P"]]
Styles
(* 6. How to stylize elements inside the FormFunction[] *)
CompoundExpression[
baseFontFamily="Arial",
titleStyle={FontWeight->Bold,FontColor->Orange,FontSize->18,FontFamily->baseFontFamily},
sectionStyle={FontWeight->Bold,FontColor->Black,FontSize->14,FontFamily->baseFontFamily},
textStyle={FontWeight->Plain,FontColor->Black,FontSize->12,FontFamily->baseFontFamily},
termStyle=textStyle,
outputStyle=textStyle,
inputLabelStyle=textStyle,
equationStyle=textStyle
];
Fixed Strings
Commonly used HTML components
inverseCubicMeter=StringTemplate["m<* htmlSuperscriptTemplate[\"-3\"] *>"] [];
Text["..."]
Use 'sectionStyle'.
(* 6 cont'd. How to stylize elements inside the FormFunction[] *)
CompoundExpression[
text["Equation"]=Style["Equation",sectionStyle],
text["Input"]=Style["Input",sectionStyle],
text["Output"]=Style["Output",sectionStyle],
text["TermList"]=Style["Term List",sectionStyle],
text["Reference"]=Style["Reference",sectionStyle]
];
Use 'textStyle'.
text["EnterAllValues"]=Style["Adjust values in input fields and hit ENTER",textStyle]
Adjust values in input fields and hit ENTER
Units List
CompoundExpression[
units["Ng"]={inverseCubicMeter},
units["P"]={"Pa"},
units["T"]={"K"}
];
Input Labels
Function 'htmlInputLabel' applies 'inputLabelStyle'
CompoundExpression[
input["Ng"]=htmlInputLabel["N","g",units["Ng"]],
input["T"]=htmlInputLabel["T","",units["T"]]
];
Term List
Function 'htmlTermList' applies 'termStyle'
CompoundExpression[
term["k"]=htmlTermList["k","","Boltzmann Constant"],
term["Ng"]=htmlTermList["N","g","Molecular Number Concentration"],
term["P"]=htmlTermList["P","","Pressure"],
term["T"]=htmlTermList["T","","Temperature"]
];
CloudDeploy[] the FormFunction[]
formObject
This function constructs the interface, including present values of the inputs and the solved quantity (by calling on FormSolver[ ]).
formObject[temperature:_,numberConcentration:_]:=
With[
{
(* input fields on form including present values *)
function1InputField=inputField["temperature",input["T"],toFormForInputField[temperature]],
function2InputField=inputField["numberConcentration",input["Ng"],toFormForInputField[numberConcentration]]
},
With[
{
formSpecification=
{
(* START FORM *)
(* 7. How to do a layout within FormFunction[],including embedding the result and avoid a submit button: SEE BELOW *)
(* Title *)
Style["Gas Pressure",titleStyle],text["NewLine"],text["NewLine"],
(* Equation *)
(* 8. How to display equations in a visually appealing way in vector graphics: use ExportString as SVG [I picked up this hint on the forums] *)
text["Equation"],text["NewLine"],ExportString[Style["P = kTSubscript[N, g]",equationStyle],"SVG"],text["NewLine"],text["NewLine"],
(* Input *)
text["Input"],text["NewLine"],text["EnterAllValues"],text["NewLine"],function1InputField,
function2InputField,text["NewLine"],
(* Output *)
text["Output"],text["NewLine"],
formSolver[temperature,numberConcentration],text["NewLine"],text["NewLine"],
(* Term List *)
text["TermList"],text["NewLine"],term["P"],text["NewLine"],term["k"],text["NewLine"],term["T"],text["NewLine"],term["Ng"],text["NewLine"],text["NewLine"],
(* Reference *)
text["Reference"],text["NewLine"],
Style["Equation 2-43 of W. Kauzmann, <i>Kinetic Theory of Gases</i>, Benjamin: New York, 1966.",textStyle],text["NewLine"],text["NewLine"]
(* END FORM *)
}
},
FormObject[formSpecification,AppearanceRules->{"SubmitLabel"->None}]
]
]
formSolver
This function provides the target quantity based on the missing input (Missing["NoInput"]).
With[
{boltzmannConstant=1.38 10^-23},
formSolver[temperature:_,numberConcentration:_]:=
htmlResult["P",boltzmannConstant temperature numberConcentration]
]
formFunction
Here the FormFunction is defined as an interface of 'formObject' and call back to itself, i.e., to update solved quantity and its value based on input quantities and values.
formFunction[temperature:_,numberConcentration:_]:=
FormFunction[
(* interface construction *)
formObject[temperature,numberConcentration],
(* function to execute, i.e., a call back to itself *)
formFunction[#temperature,#numberConcentration]&
]
Deploy to Cloud
Deploy the FormFunction to the Wolfram Cloud.
CloudDeploy[
(* function to deploy, including initial values *)
formFunction[293.15,2.50347*^25],
(* location to deploy *)
"PressureDemo",
(* options, such as public permissions *)
Sequence@@cloudDeployOptions
]
Please see the attached notebook for a convenient code summary.
Attachments: