The Now Platform® Washington DC release is live. Watch now!

Help
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Can you have different Process Flow Formatter for Projects

Andrew Payze
Kilo Guru

Hi,

is there a way to show different process flow (formatter) based on a specific field?

We have different types of projects with different types of phases, like construction, IT deployments.  These have different types of phases.  A the moment we have a field that defines the types of projects and fields for the different phases.....

we know how to create the different process flow in system UI->process flow.  Is there a UI / BR / CS that can determine which process flow to display based on a specific field?

Tx

Andrew

 

1 ACCEPTED SOLUTION

sayali udgave
Kilo Guru

Hi Andrew,

 

Use UI macro  for conditional process flow formatters. In below code change according to your conditions.

<?xml version="1.0" encoding="utf-8" ?>

 

<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">

 

      <link rel="stylesheet" type="text/css" href="styles/process_flow_formatter.cssx"></link>

 

      <tr>

 

              <td colspan="2" width="100%" nowrap="true">

 

                      <div>

 

                              <table width="100%" cellpadding="0" cellspacing="0">

 

                                      <tr>

 

                                              <g2:flow_formatter var="jvar_flows" table="$[__ref__.getRecordClass()]" current="$[__ref__]" />

 

                                              <g2:evaluate var="jvar_elements" jelly="true" object="true">

 

                                                      var afterCurrent = false;

 

                                                      var tableText = '';

 

                                                      var show = [];

 

                                                      var label = "";

 

                                                      var gr = new GlideRecord("sys_process_flow");

 

                                                      gr.addQuery("table", current.sys_class_name);

 

                                                      gr.orderBy("order");

 

                                                      gr.query();

 

                                                      while(gr.next()){

 

                                                              //Check to see if the record should be displayed.   If so add element to array.

 

                                                              //Array info

 

                                                              //     show[] -> Each element is a flow formatter record to display

 

                                                              //           show[].label -> Label for the flow formatter to display.

 

                                                              //           show[].state -> used to indicate the state of the flow formatter.

 

                                                              //                           Possible values: past, current, future

 

                                                              //           show[].next_state -> used to indicate the state of the next flow formatter.

 

                                                              //                           Possible values: past, current, future

 

                                                              if(GlideFilter.checkRecord(current, gr.u_view_condition)){

 

                                                                      var item = new Object();

 

                                                                      item.label = gr.getValue("label");

 

                                                                      //Check if this is the current flow that should be green/selected.

 

                                                                      if(GlideFilter.checkRecord(current, gr.condition)){

 

                                                                              item.state = "current";

 

                                                                              item.next_state = "future";

 

                                                                              //Once current is found update the previous element

 

                                                                              if(show.length > 1){

 

                                                                                      show[show.length - 1].next_state = "current";

 

                                                                              }

 

                                                                              afterCurrent = true;

 

                                                                      } else {

 

                                                                              if(afterCurrent){

 

                                                                                      item.state = "future";

 

                                                                                      item.next_state = "future";

 

                                                                              } else {

 

                                                                                      item.state = "past";

 

                                                                                      item.next_state = "past";

 

                                                                              }

 

                                                                      }

 

                                                                      show.push(item);

 

                                                              }

 

                                                      }

 

                                                      //clear the next_state element so that the process flow has a pointer at the end.

 

                                                      show[show.length - 1].next_state = "";

 

                                                      if(!afterCurrent){

 

                                                              show[show.length - 1].state = "future";

 

                                                      }

 

                                                      show;

 

                                              </g2:evaluate>

 

                                              <j2:forEach items="$[jvar_elements]" var="jvar_el">

 

                                                      <g2:evaluate jelly="true">

 

                                                              var label = jelly.jvar_el.label;

 

                                                              var state = jelly.jvar_el.state;

 

                                                              var next_state = jelly.jvar_el.next_state;

 

                                                      </g2:evaluate>

 

                                                      <td nowrap="nowrap" class="process_flow $[state]" title="$[label]">

 

                                                              $[label]

 

                                                      </td>

 

                                                      <td width="16" height="100%">

 

                                                              <img style="height: 24px; width: 21px; margin: 0px; padding: 0px;" src="images/chevron_$[state]_$[next_state].pngx" />

 

                                                      </td>

 

                                              </j2:forEach>

 

                                      </tr>

 

                              </table>

 

                      </div>

 

              </td>

 

      </tr>

 

</j:jelly>

 

 

View solution in original post

10 REPLIES 10

sayali udgave
Kilo Guru

Hi Andrew,

 

Use UI macro  for conditional process flow formatters. In below code change according to your conditions.

<?xml version="1.0" encoding="utf-8" ?>

 

<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">

 

      <link rel="stylesheet" type="text/css" href="styles/process_flow_formatter.cssx"></link>

 

      <tr>

 

              <td colspan="2" width="100%" nowrap="true">

 

                      <div>

 

                              <table width="100%" cellpadding="0" cellspacing="0">

 

                                      <tr>

 

                                              <g2:flow_formatter var="jvar_flows" table="$[__ref__.getRecordClass()]" current="$[__ref__]" />

 

                                              <g2:evaluate var="jvar_elements" jelly="true" object="true">

 

                                                      var afterCurrent = false;

 

                                                      var tableText = '';

 

                                                      var show = [];

 

                                                      var label = "";

 

                                                      var gr = new GlideRecord("sys_process_flow");

 

                                                      gr.addQuery("table", current.sys_class_name);

 

                                                      gr.orderBy("order");

 

                                                      gr.query();

 

                                                      while(gr.next()){

 

                                                              //Check to see if the record should be displayed.   If so add element to array.

 

                                                              //Array info

 

                                                              //     show[] -> Each element is a flow formatter record to display

 

                                                              //           show[].label -> Label for the flow formatter to display.

 

                                                              //           show[].state -> used to indicate the state of the flow formatter.

 

                                                              //                           Possible values: past, current, future

 

                                                              //           show[].next_state -> used to indicate the state of the next flow formatter.

 

                                                              //                           Possible values: past, current, future

 

                                                              if(GlideFilter.checkRecord(current, gr.u_view_condition)){

 

                                                                      var item = new Object();

 

                                                                      item.label = gr.getValue("label");

 

                                                                      //Check if this is the current flow that should be green/selected.

 

                                                                      if(GlideFilter.checkRecord(current, gr.condition)){

 

                                                                              item.state = "current";

 

                                                                              item.next_state = "future";

 

                                                                              //Once current is found update the previous element

 

                                                                              if(show.length > 1){

 

                                                                                      show[show.length - 1].next_state = "current";

 

                                                                              }

 

                                                                              afterCurrent = true;

 

                                                                      } else {

 

                                                                              if(afterCurrent){

 

                                                                                      item.state = "future";

 

                                                                                      item.next_state = "future";

 

                                                                              } else {

 

                                                                                      item.state = "past";

 

                                                                                      item.next_state = "past";

 

                                                                              }

 

                                                                      }

 

                                                                      show.push(item);

 

                                                              }

 

                                                      }

 

                                                      //clear the next_state element so that the process flow has a pointer at the end.

 

                                                      show[show.length - 1].next_state = "";

 

                                                      if(!afterCurrent){

 

                                                              show[show.length - 1].state = "future";

 

                                                      }

 

                                                      show;

 

                                              </g2:evaluate>

 

                                              <j2:forEach items="$[jvar_elements]" var="jvar_el">

 

                                                      <g2:evaluate jelly="true">

 

                                                              var label = jelly.jvar_el.label;

 

                                                              var state = jelly.jvar_el.state;

 

                                                              var next_state = jelly.jvar_el.next_state;

 

                                                      </g2:evaluate>

 

                                                      <td nowrap="nowrap" class="process_flow $[state]" title="$[label]">

 

                                                              $[label]

 

                                                      </td>

 

                                                      <td width="16" height="100%">

 

                                                              <img style="height: 24px; width: 21px; margin: 0px; padding: 0px;" src="images/chevron_$[state]_$[next_state].pngx" />

 

                                                      </td>

 

                                              </j2:forEach>

 

                                      </tr>

 

                              </table>

 

                      </div>

 

              </td>

 

      </tr>

 

</j:jelly>

 
 
64 Replies ( Latest reply 6mo ago by
SN Emy
)
 
 
 

Cool idea

 
 
 
 

Hi Drew, thanks for sharing that!

 
 
 
 

Hi Drew

Very good idea.I needed same requirement.I have tried but bad luck its not working for me.

Here are steps i followed.
1).I have updated process_flow ui macro with your code.
2).Added the field "u_view_condition" with a type of "conditions" to the sys_process_flow table and made dependent field with value "table"
Actually I needed the Process Flow formatter to show a Flow Formatter dynamically while on change of State field on form.

Whether i need to change anything..Please provide me detailed steps that i need to follow for success result.

Thanks in advance...

Best Regards,
NT


 
 
 
 

Hi Drew
You mean to say name field in sys_ui_formatter table right?
If yes i have unique name field value in sys_ui_formatter table..
Special thanks for quick response..

Thanks
NT

 
 
 
 

Hi Drew

Yes I'm able to see flow formatters on my form but it Shows from one sate to another after saving the form..Not happening in OnChange.

Thanks
NT

 
 
 
 

Hi Drew

I have implemented this for testing in "https://training1.service-now.com" for Enhancement Table(rm_enhancement).For records (rm_enhancement_list.do)

Please can you verify it that will be very helpful for me.

Thanks
NT

 
 
 
 

I guess I should have tested it a little bit more before posting it. Sorry to anyone that did not have this work for them.

 
 
 
 

I updated the code above to eliminate a quirk and also made changes so you do not have to make sure that the names are unique.

 
 
 
 

Nice! Thank you.

 
 
 
 

Added comments

 
 
 
 

Hey, this is exactly what I was looking for, thanks! I have a question though. I copied the existing process_flow ui macro and created a new one, process_flow2. Then i put the contents of your post above into the XML body of the new UI Macro. Then, under System UI -> Formatters, I created a new one called "Change Process Flow" so I could then add this to Change Request, without having to modify the existing UI Macro.

Whenever the page loads, i can see by the HTML that it works, however, it only puts HTML into the area where the process flow is, instead of the graphics and what not. Instead of the arrows with green/grey on them, I get the following:



I can tell by the pngx files that it is grabbing the correct ones, i'm just wondering why it is not rendering the HTML and instead simply is displaying the HTML itself?

Not Yet RequestedApproval RequestedApprovedComplete

 

 
 
 
 

I have updated the script to work in later releases as the package calls have been replaced ... Packages Call Replacement Script Objects - ServiceNow Enterprise Wiki


 


Code below...


 


<?xml version="1.0" encoding="utf-8" ?>


<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">


      <link rel="stylesheet" type="text/css" href="styles/process_flow_formatter.cssx"></link>


      <tr>


              <td colspan="2" width="100%" nowrap="true">


                      <div>


                              <table width="100%" cellpadding="0" cellspacing="0">


                                      <tr>


                                              <g2:flow_formatter var="jvar_flows" table="$[__ref__.getRecordClass()]" current="$[__ref__]" />


                                              <g2:evaluate var="jvar_table" jelly="true">


                                                      var afterCurrent = false;


                                                      var tableText = "";


                                                      var show = [];


                                                      var label = "";


                                                      var gr = new GlideRecord("sys_process_flow");


                                                      gr.addQuery("table", current.sys_class_name);


                                                      gr.orderBy("order");


                                                      gr.query();


                                                      while(gr.next()){


                                                              //If you do not do this you get the last value of gr.label in all elements, do not know why exactly.


                                                              label = new String(gr.label);


                                                              //Check to see if the record should be displayed.   If so add element to array.


                                                              //Array info


                                                              //     show[] -> Each element is a flow formatter record to display


                                                              //           show[][0] -> Label for the flow formatter to display.


                                                              //           show[][1] -> state: used to indicate the state of the flow formatter.


                                                              //                           Possible values: past, current, future


                                                              //           show[][2] -> next_state: used to indicate the state of the next flow formatter.


                                                              //                           Possible values: past, current, future


                                                              if(GlideFilter.checkRecord(current, gr.u_view_condition)){


                                                                      show.push(new Array(3));


                                                                      show[show.length - 1][0] = label;


                                                                      //Check if this is the current flow that should be green/selected.


                                                                      if(GlideFilter.checkRecord(current, gr.condition)){


                                                                              show[show.length - 1][1] = "current";


                                                                              show[show.length - 1][2] = "future";


                                                                              //Once current is found update the previous element


                                                                              if(show.length > 1){


                                                                                      show[show.length - 2][2] = "current";


                                                                              }


                                                                              afterCurrent = true;


                                                                      } else {


                                                                              if(afterCurrent){


                                                                                      show[show.length - 1][1] = "future";


                                                                                      show[show.length - 1][2] = "future";


                                                                              } else {


                                                                                      show[show.length - 1][1] = "past";


                                                                                      show[show.length - 1][2] = "past";


                                                                              }


                                                                      }


                                                              }


                                                      }


                                                      //clear the next_state element so that the process flow has a pointer at the end.


                                                      show[show.length - 1][2] = "";


                                                      if(!afterCurrent){


                                                          show[show.length - 1][1] = "future";


                                                      }


                                                      //Build the table


                                                      for(i in show){


                                                              tableText += '<td class="process_flow ' + show[i][1] + '" title="' + show[i][0] + '">';


                                                              tableText += show[i][0];


                                                              tableText += '</td>';


                                                              tableText += '<td width="16" height="100%">';


                                                              tableText += '<img onmouseover="" style="opacity:1; height: 24px; width: 21px; margin: 0px; padding: 0px;" src="images/chevron_' + show[i][1] + '_' + show[i][2] + '.pngx" />';


                                                              tableText += '</td>';


                                                      }


                                                      tableText;


                                              </g2:evaluate>


                                              $[jvar_table]


                                      </tr>


                              </table>


                      </div>


              </td>


      </tr>


</j:jelly>

 
 
 
 

Please note I have posted this to share at


ServiceNow Share


It is an updated and better version that does not require the changing of system properties and also no longer uses a package call.

 
 
 
 

For those of you how would like to use the updated version that I put on ServiceNow Share with out having to load the update set here is the updated UI Macro code.


 


<?xml version="1.0" encoding="utf-8" ?>


<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">


      <link rel="stylesheet" type="text/css" href="styles/process_flow_formatter.cssx"></link>


      <tr>


              <td colspan="2" width="100%" nowrap="true">


                      <div>


                              <table width="100%" cellpadding="0" cellspacing="0">


                                      <tr>


                                              <g2:flow_formatter var="jvar_flows" table="$[__ref__.getRecordClass()]" current="$[__ref__]" />


                                              <g2:evaluate var="jvar_elements" jelly="true" object="true">


                                                      var afterCurrent = false;


                                                      var tableText = '';


                                                      var show = [];


                                                      var label = "";


                                                      var gr = new GlideRecord("sys_process_flow");


                                                      gr.addQuery("table", current.sys_class_name);


                                                      gr.orderBy("order");


                                                      gr.query();


                                                      while(gr.next()){


                                                              //Check to see if the record should be displayed.   If so add element to array.


                                                              //Array info


                                                              //     show[] -> Each element is a flow formatter record to display


                                                              //           show[].label -> Label for the flow formatter to display.


                                                              //           show[].state -> used to indicate the state of the flow formatter.


                                                              //                           Possible values: past, current, future


                                                              //           show[].next_state -> used to indicate the state of the next flow formatter.


                                                              //                           Possible values: past, current, future


                                                              if(GlideFilter.checkRecord(current, gr.u_view_condition)){


                                                                      var item = new Object();


                                                                      item.label = gr.getValue("label");


                                                                      //Check if this is the current flow that should be green/selected.


                                                                      if(GlideFilter.checkRecord(current, gr.condition)){


                                                                              item.state = "current";


                                                                              item.next_state = "future";


                                                                              //Once current is found update the previous element


                                                                              if(show.length > 1){


                                                                                      show[show.length - 1].next_state = "current";


                                                                              }


                                                                              afterCurrent = true;


                                                                      } else {


                                                                              if(afterCurrent){


                                                                                      item.state = "future";


                                                                                      item.next_state = "future";


                                                                              } else {


                                                                                      item.state = "past";


                                                                                      item.next_state = "past";


                                                                              }


                                                                      }


                                                                      show.push(item);


                                                              }


                                                      }


                                                      //clear the next_state element so that the process flow has a pointer at the end.


                                                      show[show.length - 1].next_state = "";


                                                      if(!afterCurrent){


                                                              show[show.length - 1].state = "future";


                                                      }


                                                      show;


                                              </g2:evaluate>


                                              <j2:forEach items="$[jvar_elements]" var="jvar_el">


                                                      <g2:evaluate jelly="true">


                                                              var label = jelly.jvar_el.label;


                                                              var state = jelly.jvar_el.state;


                                                              var next_state = jelly.jvar_el.next_state;


                                                      </g2:evaluate>


                                                      <td nowrap="nowrap" class="process_flow $[state]" title="$[label]">


                                                              $[label]


                                                      </td>


                                                      <td width="16" height="100%">


                                                              <img style="height: 24px; width: 21px; margin: 0px; padding: 0px;" src="images/chevron_$[state]_$[next_state].pngx" />


                                                      </td>


                                              </j2:forEach>


                                      </tr>


                              </table>


                      </div>


              </td>


      </tr>


</j:jelly> 

I hope that it helped you!

Thanks

Sayali Anil Udgave

sayali udgave
Kilo Guru

Hi Andrew,

 

Use UI macro  for conditional process flow formatters. In below code change according to your conditions.

<?xml version="1.0" encoding="utf-8" ?>

 

<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">

 

      <link rel="stylesheet" type="text/css" href="styles/process_flow_formatter.cssx"></link>

 

      <tr>

 

              <td colspan="2" width="100%" nowrap="true">

 

                      <div>

 

                              <table width="100%" cellpadding="0" cellspacing="0">

 

                                      <tr>

 

                                              <g2:flow_formatter var="jvar_flows" table="$[__ref__.getRecordClass()]" current="$[__ref__]" />

 

                                              <g2:evaluate var="jvar_elements" jelly="true" object="true">

 

                                                      var afterCurrent = false;

 

                                                      var tableText = '';

 

                                                      var show = [];

 

                                                      var label = "";

 

                                                      var gr = new GlideRecord("sys_process_flow");

 

                                                      gr.addQuery("table", current.sys_class_name);

 

                                                      gr.orderBy("order");

 

                                                      gr.query();

 

                                                      while(gr.next()){

 

                                                              //Check to see if the record should be displayed.   If so add element to array.

 

                                                              //Array info

 

                                                              //     show[] -> Each element is a flow formatter record to display

 

                                                              //           show[].label -> Label for the flow formatter to display.

 

                                                              //           show[].state -> used to indicate the state of the flow formatter.

 

                                                              //                           Possible values: past, current, future

 

                                                              //           show[].next_state -> used to indicate the state of the next flow formatter.

 

                                                              //                           Possible values: past, current, future

 

                                                              if(GlideFilter.checkRecord(current, gr.u_view_condition)){

 

                                                                      var item = new Object();

 

                                                                      item.label = gr.getValue("label");

 

                                                                      //Check if this is the current flow that should be green/selected.

 

                                                                      if(GlideFilter.checkRecord(current, gr.condition)){

 

                                                                              item.state = "current";

 

                                                                              item.next_state = "future";

 

                                                                              //Once current is found update the previous element

 

                                                                              if(show.length > 1){

 

                                                                                      show[show.length - 1].next_state = "current";

 

                                                                              }

 

                                                                              afterCurrent = true;

 

                                                                      } else {

 

                                                                              if(afterCurrent){

 

                                                                                      item.state = "future";

 

                                                                                      item.next_state = "future";

 

                                                                              } else {

 

                                                                                      item.state = "past";

 

                                                                                      item.next_state = "past";

 

                                                                              }

 

                                                                      }

 

                                                                      show.push(item);

 

                                                              }

 

                                                      }

 

                                                      //clear the next_state element so that the process flow has a pointer at the end.

 

                                                      show[show.length - 1].next_state = "";

 

                                                      if(!afterCurrent){

 

                                                              show[show.length - 1].state = "future";

 

                                                      }

 

                                                      show;

 

                                              </g2:evaluate>

 

                                              <j2:forEach items="$[jvar_elements]" var="jvar_el">

 

                                                      <g2:evaluate jelly="true">

 

                                                              var label = jelly.jvar_el.label;

 

                                                              var state = jelly.jvar_el.state;

 

                                                              var next_state = jelly.jvar_el.next_state;

 

                                                      </g2:evaluate>

 

                                                      <td nowrap="nowrap" class="process_flow $[state]" title="$[label]">

 

                                                              $[label]

 

                                                      </td>

 

                                                      <td width="16" height="100%">

 

                                                              <img style="height: 24px; width: 21px; margin: 0px; padding: 0px;" src="images/chevron_$[state]_$[next_state].pngx" />

 

                                                      </td>

 

                                              </j2:forEach>

 

                                      </tr>

 

                              </table>

 

                      </div>

 

              </td>

 

      </tr>

 

</j:jelly>

 

 

Hi Sayali,

I am stuck in getting this to work ... help with a little more detail please?  Now nothing displays at the top of the record.  I created a new UI Macro, renamed the original one and named the new one to "process_flow"

I created a u_view_condition in sys_process_flow table.  See the first screen shot.  Then I updated records in the same table .... see second screenshot.  

Made sure a record in the project table had the same value as the condition.   

 

find_real_file.png

 

Adding criteria to sys_process_flow record

find_real_file.png