Home > Forum > Forms > How to access the current form data via javascript?

How to access the current form data via javascript?
0

MVP

I haven't found any documentation how to access the current form data.
What I know is, that all the formdata is kept in a json property called liteDate.liteModel as a json-object as you can see when calling /api/nav/db/{dbId}/app/{appId}/element/{wfdid}/desktop

I guess that this liteModel must be available via javascript.

I'm wondering, because there is this form from the offical 2021 release paper (see below) with the nicely presented workflow steps on top of it.
And I believe that this a Html-Field with some javascript.

Does anybody know how to get to this data?

MVP

Hi Markus,

I'm quite sure that you aren't referring to the data itself. :)
I would render the required data as Json or similar in an html field so that you can access it. Of course you could use some internal functions but since they are non public they may change.

If you want to achieve something similar you could refer to Kamils blog:
https://alterpaths.com/dynamics-crm-like-status-bar/

Best regards,
Daniel

MVP
In reply to: Daniel Krüger (Cosmo Consult)

The video has been officially published an the introduction of the html field starts around minute 42.
https://youtu.be/K9zX5YCqE_M

I'm not sure whether you can see enough to rebuild it.
My personal problem would be styling it. :)

The official video apparently has a bit different timing. Anyway, I tried recreate the HTML field as shown in the video but am missing the js part. Is there anyone from Webcon who can post the js script that generates divs in the body of the HTML (<body onload="GenerateDivs()">)? Thanks.

Hello guys,

the code presented on the webinar by Mike is located below (end of the post).
The final result is a compilation of few things. Please keep in mind that this is not a out of the box feature (it uses custom JS and HTML code delivered by implementing person).

You can use it but on "your own risk" ;-)

Answering first question - this feature does not get data from backend (it has static configuration inside). Foe the future development there is planned to deliver support for business rules avaiable for HTML Control usage.


Here we go with the code:
1. HTML attribute body (STAGES) / General tab

<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.stages {
padding: 10px;
border: 3px solid;
overflow: auto;
}

.prev {
color: grey !important;
font-weight: 300;
}

.curr {
color: white !important;
font-weight: 400;
}

.next {
color: lighgrey !important;
}

.stage {
width: 11%;
height: 50px;
background:#f0f0f0;
position: relative;
float:left;
text-align: center;
line-height: 47px;
font-family: Arial;
font-weight: 200;
color: lightgrey;
}

.triangle-right {
border-top: 25px solid transparent;
border-left: 15px solid #f0f0f0;
border-bottom: 25px solid transparent;
float:left;
}

</style>
</head>


<body onload="generateDivs()">
<div id = "root" class="stages">


</div>
</body>
</html>



2. Form Rule (Generate Stages)
var my_div = null;
var newDiv = null;

function addElement(p)
{
newDiv = document.createElement("div");
newDiv.innerHTML = items[p][0];
newDiv.className = "stage";
newDiv.setAttribute("id", "stage_"+items[p][1]);
document.getElementById("root").appendChild(newDiv);
}
function addSeparator(s)
{
nSep = document.createElement("div");
nSep.className = "triangle-right";
nSep.setAttribute("id", "sep_stage_"+items[s][1]);
node = document.getElementById("stage_"+items[s][1]);
node.parentNode.insertBefore(nSep, node.nextSibling);
}
var items = [
['Parametrizing', '0','#{ST:1163}#'],
['Drafting', '1','#{ST:1164}#'],
['Refinement', '2','#{ST:1166}#'],
['Counterparty', '3','#{ST:1165}#'],
['Legal', '4','#{ST:1167}#'],
['Business', '5','#{ST:1168}#'],
['CEO', '6','#{ST:1212}#'],
['Signing', '7','#{ST:1214}#']
];

function generateDivs(){
for (var i=0;i<items.length;i++){
addElement(i);
addSeparator(i);
}

}
function getIndex(currentStep){
var result;
var index;
for( var i = 0, len = items.length; i < len; i++ ) {
if( items[i][2] === currentStep ) {
result = items[i];
index= items.indexOf(result);
break;
}
}
return index;
}

function paintThemAll(){
//setCurrentStage
var currentindex = getIndex(GetPairID(G_WFSTEP));
for (var x=0;x<items.length;x++){
if (x==currentindex ){
document.getElementById("stage_"+currentindex).className += " curr";
document.getElementById("stage_"+currentindex).style.background = #{BRP:39}#;
document.getElementById("sep_stage_"+currentindex).style.borderLeftColor = #{BRP:39}#;
}
if (x<currentindex ){
document.getElementById("stage_"+x).className += " prev";
}
if (x>currentindex ){
document.getElementById("stage_"+x).className += " next";
}
}

}

generateDivs();
paintThemAll();
document.getElementById("root").style.borderColor = #{BRP:39}#;


/*
README
items - array that keeps names and StepsID (this are different for different process)
#{BRP:39}# - this is the parameter nested inside generate Stages rule, it is used durng form rule call
you can create any ule that delivers colors, or just switch to any static value


Whole rule execution has to be placed on workflow global form -> style & behaviour


to make this even more dynamic - you may try to run defaults / change value field action on path - to 'regenerate data ' for array items. With this way you can make it more dynamic - instead of static values nested.
*/

Have fun ;-)

MVP
In reply to: Bartłomiej Spyrka (WEBCON)

Hello guys,

the code presented on the webinar by Mike is located below (end of the post).
The final result is a compilation of few things. Please keep in mind that this is not a out of the box feature (it uses custom JS and HTML code delivered by implementing person).

You can use it but on "your own risk" ;-)

Answering first question - this feature does not get data from backend (it has static configuration inside). Foe the future development there is planned to deliver support for business rules avaiable for HTML Control usage.


Here we go with the code:
1. HTML attribute body (STAGES) / General tab

<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.stages {
padding: 10px;
border: 3px solid;
overflow: auto;
}

.prev {
color: grey !important;
font-weight: 300;
}

.curr {
color: white !important;
font-weight: 400;
}

.next {
color: lighgrey !important;
}

.stage {
width: 11%;
height: 50px;
background:#f0f0f0;
position: relative;
float:left;
text-align: center;
line-height: 47px;
font-family: Arial;
font-weight: 200;
color: lightgrey;
}

.triangle-right {
border-top: 25px solid transparent;
border-left: 15px solid #f0f0f0;
border-bottom: 25px solid transparent;
float:left;
}

</style>
</head>


<body onload="generateDivs()">
<div id = "root" class="stages">


</div>
</body>
</html>



2. Form Rule (Generate Stages)
var my_div = null;
var newDiv = null;

function addElement(p)
{
newDiv = document.createElement("div");
newDiv.innerHTML = items[p][0];
newDiv.className = "stage";
newDiv.setAttribute("id", "stage_"+items[p][1]);
document.getElementById("root").appendChild(newDiv);
}
function addSeparator(s)
{
nSep = document.createElement("div");
nSep.className = "triangle-right";
nSep.setAttribute("id", "sep_stage_"+items[s][1]);
node = document.getElementById("stage_"+items[s][1]);
node.parentNode.insertBefore(nSep, node.nextSibling);
}
var items = [
['Parametrizing', '0','#{ST:1163}#'],
['Drafting', '1','#{ST:1164}#'],
['Refinement', '2','#{ST:1166}#'],
['Counterparty', '3','#{ST:1165}#'],
['Legal', '4','#{ST:1167}#'],
['Business', '5','#{ST:1168}#'],
['CEO', '6','#{ST:1212}#'],
['Signing', '7','#{ST:1214}#']
];

function generateDivs(){
for (var i=0;i<items.length;i++){
addElement(i);
addSeparator(i);
}

}
function getIndex(currentStep){
var result;
var index;
for( var i = 0, len = items.length; i < len; i++ ) {
if( items[i][2] === currentStep ) {
result = items[i];
index= items.indexOf(result);
break;
}
}
return index;
}

function paintThemAll(){
//setCurrentStage
var currentindex = getIndex(GetPairID(G_WFSTEP));
for (var x=0;x<items.length;x++){
if (x==currentindex ){
document.getElementById("stage_"+currentindex).className += " curr";
document.getElementById("stage_"+currentindex).style.background = #{BRP:39}#;
document.getElementById("sep_stage_"+currentindex).style.borderLeftColor = #{BRP:39}#;
}
if (x<currentindex ){
document.getElementById("stage_"+x).className += " prev";
}
if (x>currentindex ){
document.getElementById("stage_"+x).className += " next";
}
}

}

generateDivs();
paintThemAll();
document.getElementById("root").style.borderColor = #{BRP:39}#;


/*
README
items - array that keeps names and StepsID (this are different for different process)
#{BRP:39}# - this is the parameter nested inside generate Stages rule, it is used durng form rule call
you can create any ule that delivers colors, or just switch to any static value


Whole rule execution has to be placed on workflow global form -> style & behaviour


to make this even more dynamic - you may try to run defaults / change value field action on path - to 'regenerate data ' for array items. With this way you can make it more dynamic - instead of static values nested.
*/

Have fun ;-)

Hi Bartłomiej,

thanks for the solution and pointing out, that you can't use business rules in html fields, yet. I wasn't aware of this. :)

@All
While this is not an option, I would either uses Kamils approach, which doesn't uses fixed values or I would use some jQuery to get the _translated_ step names from the form. The div with id 'stepInfos' contains all the details. I would generate the divs with these information.


Nevertheless, I won't use this approach because I don't want to add this to every form, which would be required to keep a consistent user experience.

Best gerads,
Daniel