CAFA with dynamics

Starting from version 1.201.1, GoErp allows to make json modifications more flexible, like predefined json, connecting json parts from another request and many more.

Let’s take CAFA as an example, as it will use most of the modification options.

<h1>Dynamic CAFA</h1>
<form method="post">

  <!-- Defining variables to get rid of very long value definitions in the inputs -->
  {{ $putConfBody := .Data.CaFaApi.Api.Requests.putConf.Json }}
  {{ $getConfStateResp := .Data.CaFaApi.Api.Requests.getConfState.Response.Get "0" }}
  
  <!-- 1. Load initial state of the configuration -->
  <input type="hidden" name="CaFaApi.Api.Get.getConfState" value="configuration" data-preset-val="configuration">
  
  <!-- 2. provide query parameters for the configuration entry -->
  <input type="hidden" name="CaFaApi.Api.QueryBulk.getConfState.url" value="application=my-app&level=Company&name=dynamic-sample"
         data-preset-val="application=my-app&level=Company&name=dynamic-sample">

  <!-- 3. Create save call with initial json payload -->
  <input type="hidden" name="CaFaApi.Api.Put.putConf|1" value="v3/configuration">
  {{ if $getConfStateResp.Exists }}
  <input type="hidden" name="CaFaApi.Api.Json.putConf.json.<-@{order(1)}"
         value="getConfState.Response.0">
  {{ else }}
  <input type="hidden" name="CaFaApi.Api.Json.putConf.json.@{order(1)}"
         value='{"application":"my-app","level":"Company","name":"dynamic-sample","value":{}}'>
  {{ end }}

  <!-- 4. Optionally, check updated state of the entry. -->
  <input type="hidden" name="CaFaApi.Api.Get.getConfFinal|2" value="v3/configuration/{id}">
  <input type="hidden" name="CaFaApi.Api.Path.getConfFinal.<-id" value="putConf.Response.id">

  <!-- 5. Modify section, use same approach to as many fields as needed -->
  <br/>Cat Murka age: 
  <input type="text" 
         name="CaFaApi.Api.Json.putConf.number.value.pets.murka.age"
         value='{{ if $putConfBody.Exists }}{{ $putConfBody.Get "value.pets.murka.age" }}{{ else}}{{ $getConfStateResp.Get "value.pets.murka.age" }}{{ end }}'>

  <button type="submit">Submit</button>
</form>

<h2>Before update</h2>
Murka age: {{ .Data.CaFaApi.Api.Requests.getConfState.Response.Get "0.value.pets.murka.age" }}

<h2>After update</h2>
Murka age: {{ .Data.CaFaApi.Api.Requests.getConfFinal.Response.Get "0.value.pets.murka.age" }}
  1. Firstly, we need to have current state of the configuration, so we are loading it from the api with getConfState request. Later we can use it for the “first page loading” event to display current state.
  2. Here, with QueryBulk parameter type we are preparing a bunch of static query parameters to get specific configuration entry, based on application, level and name.
  3. This part of the code allows as to prepare initial body of the json payload. We are getting the payload from getConfState if it is available, or generating totally new one otherwise. Also, we are using input functions feature to define the order for json input parameters. By default, GoErp receives all parameters in a chaotic order. But we need to be sure that initial structure assignment goes always first, so we are defining order by setting it to 1. Additionally, we need to assign the payload to body as a root object. To do that, just omit key definition after the dot (with key: .json.key, and without: .json.).
  4. Optionally, we are defining request getConfFinal to retrieve configuration updated state, just to see that configuration was changed. In most cases it is not needed in real applications.
  5. In this section we are making modifications to the configuration object and making sure that UI displays correct value for each case: 1) first load of the page and 2) after update event. We know, that if json body of the put request is available, then we came to this page right after save, otherwise it is first loading. Variables were defined just to make input value look smaller.

The final working example with a couple more fields after removing all unnecessary stuff:

<!-- Vars section -->
{{ $putConfBody := .Data.CaFaApi.Api.Requests.putConf.Json }}
{{ $getConfStateResp := .Data.CaFaApi.Api.Requests.getConfState.Response.Get "0" }}

<h1>Dynamic CAFA</h1>
<form method="post">
    <input type="hidden" name="CaFaApi.Api.Get.getConfState" value="configuration" data-preset-val="configuration">
    <input type="hidden" name="CaFaApi.Api.QueryBulk.getConfState.url" value="application=my-app&level=Company&name=dynamic-sample" data-preset-val="application=my-app&level=Company&name=dynamic-sample">

    <input type="hidden" name="CaFaApi.Api.Put.putConf|1" value="v3/configuration">
    {{ if $getConfStateResp.Exists }}
    <input type="hidden" name="CaFaApi.Api.Json.putConf.json.<-@{order(1)}" value="getConfState.Response.0">
    {{ else }}
    <input type="hidden" name="CaFaApi.Api.Json.putConf.json.@{order(1)}" value='{"application":"my-app","level":"Company","name":"dynamic-sample","value":{}}'>
    {{ end }}

    <input type="hidden" name="CaFaApi.Api.Get.getConfFinal|2" value="v3/configuration/{id}">
    <input type="hidden" name="CaFaApi.Api.Path.getConfFinal.<-id" value="putConf.Response.id">

    <!-- Modify section -->
    <br/>Cat Murka age: <input type="text" name="CaFaApi.Api.Json.putConf.number.value.pets.murka.age"
        value='{{ if $putConfBody.Exists }}{{ ($putConfBody.Get "value.pets.murka.age").String }}{{ else}}{{ ($getConfStateResp.Get "value.pets.murka.age").String }}{{ end }}'>
    <br/>Cat Murka breed: <input type="text" name="CaFaApi.Api.Json.putConf.string.value.pets.murka.breed"
        value='{{ if $putConfBody.Exists }}{{ ($putConfBody.Get "value.pets.murka.breed").String }}{{ else}}{{ ($getConfStateResp.Get "value.pets.murka.breed").String }}{{ end }}'>
    <br/>Cat Murka kind: <input type="text" name="CaFaApi.Api.Json.putConf.string.value.pets.murka.kind"
        value='{{ if $putConfBody.Exists }}{{ ($putConfBody.Get "value.pets.murka.kind").String }}{{ else}}{{ ($getConfStateResp.Get "value.pets.murka.kind").String }}{{ end }}'>


    <br/><button type="submit">Submit </button>
</form>