Form Decoration Examples
Since you can add JavaScript to the Decoration-HTML, various ideas that enhance business efficiency can be realized. Accelerate your Workflow!!

Code Examples using JavaScript Selectors API or jQuery for UI developers.
The Decoration feature is available with Professional edition.
NOTE: No updates or support. Decoration is at your own risk.


Overwrite Number

Input/Output

  • Referrer:
    • NUMERIC form: “q_Total
  • Target:
    • NUMERIC form: “q_Tax10” (update)

Example of DESCRIPTION setting

vanilla JavaScript (click to open)
※複数税率が適用されている場合は必須<br>
Click to overwrite: 
<button type='button' onclick='user_set_Tax10_calc10110()'>取引金額 * 10/110</button>
<button type='button' onclick='user_set_Tax10_zero()'>0</button>
<script>
function user_set_Tax10_calc10110(){
  let bigTotal = qbpms.form.get( "q_Total" );
  let bigTax10 = bigTotal.times(10).div(110);
  qbpms.form.set( "q_Tax10", bigTax10 );
}
function user_set_Tax10_zero(){
  qbpms.form.set( "q_Tax10", 0 );
}
</script>

Capture

Frequent calculations. No calculator needed.

Frequent calculations. No calculator needed.


Overwrite String

Input/Output

  • Target:
    • STRING form: “q_JournalAccount” (update)

Example of DESCRIPTION setting

vanilla JavaScript (click to open)
Click to overwrite: 
<button type='button' class='user_JournalAccount'>広告宣伝費</button>
<button type='button' class='user_JournalAccount'>旅費交通費</button>
<button type='button' class='user_JournalAccount'>会議費</button>
<button type='button' class='user_JournalAccount'>備品・消耗品費</button>
<button type='button' class='user_JournalAccount'>租税公課</button>
<button type='button' class='user_JournalAccount'>通信費</button>
<button type='button' class='user_JournalAccount'>旅費交通費(製)</button>
<button type='button' class='user_JournalAccount'>会議費(製)</button>
<button type='button' class='user_JournalAccount'>備品・消耗品費(製)</button>
<button type='button' class='user_JournalAccount'>租税公課(製)</button>
<button type='button' class='user_JournalAccount'>通信費(製)</button>
<button type='button' class='user_JournalAccount'>(不明)</button>
<script>
document.querySelectorAll('.user_JournalAccount').forEach( btn => {
  btn.addEventListener('click', () => {
    const strClicked  = btn.textContent;
    qbpms.form.set( "q_JournalAccount", strClicked );
  });
});
</script>

Capture

Click input. Prevent typos.

Click input. Prevent typos.


Preview HTML Code

Input/Output

  • Referrer:
    • Multiline STRING form: “q_HtmlCode
  • Target:
    • (new window)

Example of DESCRIPTION setting

vanilla JavaScript (click to open)
<button type='button' onclick='user_preview_Html()'>Open Window to Preview HTML</button>
<script>
function user_preview_Html() {
  let str_HtmlCode = qbpms.form.get("q_HtmlCode");
  if( str_HtmlCode === "" ){
    throw new Error('No String in this Textarea');
  }
  let blob = new Blob([ str_HtmlCode ], { type: 'text/html' });
  let strUrl = URL.createObjectURL(blob);
  window.open( strUrl, "_Blank" );
}
</script>

Capture

HTML Code Previewer. Display the HTML text stored in the String type in another window.

HTML Code Previewer. Display the HTML text stored in the String type in another window.


Export Text as UTF8B-File

Input/Output

  • Referrer:
    • Multiline STRING form
  • Target:
    • (download)
<div class="form-data-item-wrapper column column-1 " data-pdd-number="0" data-type="STRING" data-sub-type=""
 data-form-type="TEXTAREA" data-var-name="q_Multiline_String" data-accessibility="READWRITE" data-field-name="data[0].input">
  <div class="item  "><label class="item-label">Multiline String</label><!--文字列型-->
  <textarea name="data[0].input" rows="15" placeholder="" style="resize: both;" class="fit">I am a cat.
As yet I have no name. I've no idea where I was born.
All I remember is that I was miaowing in a dampish dark place when, for the first time, I saw a human being.
  </textarea>
  </div>
</div>

Example of DESCRIPTION setting

vanilla JavaScript (click to open)
<button type='button' onclick='user_exportTextAsFile0()'>Save as Text File</button>
<script>
function user_exportTextAsFile0(){
  let str_Multiline_String = qbpms.form.get("q_Multiline_String");
  let bom  = new Uint8Array([0xEF, 0xBB, 0xBF]);
  let blob = new Blob([bom, str_Multiline_String], {type: 'text/plain'});
  let url = (window.URL || window.webkitURL).createObjectURL(blob);
  let link = document.createElement('a');
  link.download = 'download.txt';
  link.href = url;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}
</script>

Capture

Convert string data to a text file.

Convert string data to a text file.


Check Form History via REST API

Input / Output

  • Referrer:
    • (/API/OR/ProcessInstance/list)
  • Target:
    • span “user_Result8
    • Singleline STRING form, “q_string8

Example of DESCRIPTION setting

vanilla JavaScript (click to open)
<button onclick="user_getHistory8()" type="button" class="user_Search">Sample Search →</button>
<span id="user_Result8"></span>
<script>
document.addEventListener("click", function (e) {
  console.log( " DocumentElement clicked: " + e.target.textContent );
  if (e.target.classList.contains("user_Appender")) {
    qbpms.form.set( "q_string8", e.target.value );                   ///EDIT///
  }
});
function user_getHistory8() {
  let numTARGETID      = 8;                                          ///EDIT///
  let numLIMITSIZE     = 10;                                         ///EDIT///
  let numWORKFLOWAPPID = 1883;                                       ///EDIT///
  let strSearchWord    = qbpms.form.get( "q_string8" );              ///EDIT///
  let elResultSpan     = document.querySelector("#user_Result8");    ///EDIT///

  let objCriteria = {}; // JSON criteria: (BPMS v13.3~)
      // https://questetra.zendesk.com/hc/ja/articles/4415341995289
      // https://questetra.zendesk.com/hc/en-us/articles/4415341995289
      objCriteria.processModelInfoId = numWORKFLOWAPPID;
      objCriteria.processInstanceState = [];
      objCriteria.processInstanceState[0] = "ENDED"; // only completed instances
      if ( strSearchWord !== "" ) {
        objCriteria.data = [];
        objCriteria.data[0] = {};
        objCriteria.data[0].type   = "string";
        objCriteria.data[0].number = numTARGETID;
        objCriteria.data[0].method = "contains";
        objCriteria.data[0].value  = strSearchWord;
      }
      objCriteria.fields = [];
      objCriteria.fields[0] = {};
      objCriteria.fields[0].type   = "string";
      objCriteria.fields[0].number = numTARGETID;
  let xhr = new XMLHttpRequest();
      xhr.open( "GET", "/API/OR/ProcessInstance/list?limit=" + numLIMITSIZE +
                       "&criteria=" + encodeURIComponent(JSON.stringify(objCriteria)) );
      xhr.responseType = 'json';
      xhr.send();
      xhr.onload = function() {
        if (xhr.status != 200) {
          console.error(`Error ${xhr.status}: ${xhr.statusText}`); // e.g. "404: Not Found"
        } else { // show the result
          let objResponse = xhr.response;
          console.log( " Decoration XHR: Found PastData " + objResponse.processInstances.length + 
                       "/" + objResponse.count  );
          elResultSpan.innerHTML = ""; // clear
          for (let i = 0; i < objResponse.processInstances.length; i++ ) {
            let elNewAnchor = document.createElement("a");
                elNewAnchor.href      = "/OR/ProcessInstance/view?processInstanceId=" + 
                                        objResponse.processInstances[i].processInstanceId;
                elNewAnchor.target    = "_blank";
                elNewAnchor.innerText = "p" + objResponse.processInstances[i].processInstanceId;
            let elNewButton = document.createElement("button");
                elNewButton.type = "button";
                elNewButton.classList.add("user_Appender");
                if ( objResponse.processInstances[i].data[numTARGETID].value === null ){
                  elNewButton.value     = "";
                  elNewButton.innerHTML = "∅";
                }else{
                  elNewButton.value     = objResponse.processInstances[i].data[numTARGETID].value;
                  elNewButton.innerText = objResponse.processInstances[i].data[numTARGETID].value;
                }
            // "<a>p123</a>=<button>消耗品費</button>"
            elResultSpan.append( " ", elNewAnchor,"=" );
            elResultSpan.append( elNewButton );
          }
        }
        console.log( " Decoration XHR: finished " );
      };
      xhr.onerror = function() {
        alert("Request failed");
      };
}
</script>
<style type="text/css">
button.user_Appender {
    border          : 0;
    line-height     : 1.2;
    padding         : 3px 8px;
    font-size       : 0.9rem;
    text-align      : center;
    color           : #fff;
    text-shadow     : 1px 1px 1px #000;
    border-radius   : 10px;
    background-color: #050505;
}
button.user_Appender:hover {
    background-color: #00bb00;
}
button.user_Appender:active {
    box-shadow      : inset -2px -2px 3px rgba(255, 255, 255, .6),
                      inset 2px 2px 3px rgba(0, 0, 0, .6);
}

button.user_Search {
  display       : inline-block;
  border-radius : 5%;
  font-size     : 1rem;
  text-align    : center;
  cursor        : pointer;
  padding       : 5px 20px;
  background    : #009900;
  color         : #ffffff;
  line-height   : 1em;
  transition    : .3s;
  box-shadow    : 2px 2px 3px #666666;
  border        : 2px solid #009900;
}
button.user_Search:hover {
  box-shadow    : none;
  color         : #009900;
  background    : #ffffff;
}
</style>

Capture

Searches to past data via “Questetra Workflow API” (completed process instance only), then Shows 10 samples. Note that it depends on the user’s privileges and history.


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: