title: Xforms submit error with multiple submissions : submission-in-progress
body: <p>We are developing an app with xforms (with XSLTForms client) and BaseX, to manage historical entities (actors) and conduct network analysis. In one of our forms, we fill the relations between an actor and his relatives, and we'd like, when submitting the form, to create and submit a pre-filled instance for each relative…</p>
  
  <p>…but we have issues with the multiple submissions.</p>
  
  <p>Basically, we have 3 instances : </p>
  
  <p><code>instance('entity')</code>, for the main form</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;xf:instance id="entity"&gt;
      &lt;entity xmlns=""&gt;
          &lt;name&gt;John Doe&lt;/name&gt;
          &lt;age&gt;35&lt;/age&gt;
          &lt;address&gt;North Cap&lt;/address&gt;
          &lt;relations&gt;
              &lt;relation ref="" type="sibling"&gt;Elisa Doe&lt;/relation&gt;
              &lt;relation ref="" type="parent"&gt;Richard Doe&lt;/relation&gt;
          &lt;/relations&gt;
      &lt;/entity&gt;
  &lt;/xf:instance&gt;
  </code></pre>
  
  <p><code>instance('newEntity')</code>, filled and sent successively for each <code>relation</code> in <code>instance('entity')</code>(for the example we just copy the name value)</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;xf:instance id="newEntity"&gt;
      &lt;entity xmlns=""&gt;
          &lt;name/&gt;
          &lt;age/&gt;
          &lt;address/&gt;
          &lt;relations&gt;
              &lt;relation ref="" type=""/&gt;
          &lt;/relations&gt;
      &lt;/entity&gt;
  &lt;/xf:instance&gt;
  </code></pre>
  
  <p><code>instance('iterate')</code>, for looping the submissions of <code>instance('newEntity')</code> (when instance('iterate') = 1, we process <code>relation[position() = 1]</code>, etc</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;xf:instance id="iterate"&gt;
      &lt;iterate xmlns=""/&gt;
  &lt;/xf:instance&gt;
  </code></pre>
  
  <p>And here is our submit process :</p>
  
  <p>First, we initiate the loop with a trigger, while there is more <code>relation</code> than the value of <code>instance('iterate')</code>we submit the <code>instance('newEntity')</code> ; and when all the relations have been sent, we submit the main form.</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;xf:trigger&gt;
      &lt;xf:label&gt;submit&lt;/xf:label&gt;
      &lt;xf:action ev:event="DOMActivate"&gt;
          &lt;xf:setvalue ref="instance('iterate')" value="1"/&gt;
          &lt;xf:setvalue ref="instance('newEntity')/name" value="instance('entity')/relations/relation[position() = instance('iterate')]"/&gt;
          &lt;xf:action while="count(//relation) &amp;gt;= instance('iterate')"&gt;
              &lt;xf:send submission="submitNewEntity"/&gt;
              &lt;xf:action if="count(//relation) &amp;lt; instance('iterate')"&gt;
                  &lt;xf:send submission="submitEntity"/&gt;
              &lt;/xf:action&gt;
          &lt;/xf:action&gt;
      &lt;/xf:action&gt;
  &lt;/xf:trigger&gt;
  </code></pre>
  
  <p>Then we have the submission for the "new entities". Nothing special here, when the submit is done, we set the value of <code>relation/@ref</code> corresponding to the last submission thanks to the response of the server, then we add "+1" to the <code>instance('iterate')</code>for the loop.</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;xf:submission ref="instance('newEntity')" id="submitNewEntity" resource="/test/form/put" method="put" replace="none"&gt;
      &lt;xf:action ev:event="xforms-submit-done"&gt;
          &lt;xf:message level="modal"&gt;
              OK 
              Status : &lt;xf:output value="event('response-status-code')"/&gt;; 
              URI : &lt;xf:output value="event('resource-uri')"/&gt;; 
              Headers : &lt;xf:output value="event('response-headers')"/&gt;; 
              Reason : &lt;xf:output value="event('response-reason-phrase')"/&gt;;
              Body : &lt;xf:output value="event('response-body')"/&gt;.
          &lt;/xf:message&gt;
          &lt;xf:setvalue value="event('response-body')//*:id" ref="instance('entity')//relation[position() = instance('iterate')]/@ref"/&gt;
          &lt;xf:setvalue ref="instance('iterate')" value="instance('iterate') + 1"/&gt;
      &lt;xf:setvalue ref="instance('newEntity')/name" value="instance('entity')/relations/relation[position() = instance('iterate')]"/&gt;
      &lt;/xf:action&gt;
      &lt;xf:action ev:event="xforms-submit-error"&gt;
          &lt;xf:message level="modal"&gt;
              Error : &lt;xf:output value="event('error-type')"/&gt;; 
              Status : &lt;xf:output value="event('response-status-code')"/&gt;; 
              URI : &lt;xf:output value="event('resource-uri')"/&gt;; 
              Headers : &lt;xf:output value="event('response-headers')"/&gt;; 
              Reason : &lt;xf:output value="event('response-reason-phrase')"/&gt; 
              Body : &lt;xf:output value="event('response-body')"/&gt;.
          &lt;/xf:message&gt;
      &lt;/xf:action&gt;
  &lt;/xf:submission&gt;
  </code></pre>
  
  <p>And finally we are submitting the main form when all the relations have been saved</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;xf:submission ref="instance('entity')" id="submitEntity" resource="/test/form/put" method="put" replace="none"&gt;
      &lt;xf:action ev:event="xforms-submit-done"&gt;
          &lt;xf:message level="modal"&gt;
              OK ! 
              Status : &lt;xf:output value="event('response-status-code')"/&gt;; 
              URI : &lt;xf:output value="event('resource-uri')"/&gt;; 
              Headers : &lt;xf:output value="event('response-headers')"/&gt;; 
              Reason : &lt;xf:output value="event('response-reason-phrase')"/&gt;;
              Body : &lt;xf:output value="event('response-body')"/&gt;.
          &lt;/xf:message&gt;
      &lt;/xf:action&gt;
      &lt;xf:action ev:event="xforms-submit-error"&gt;
          &lt;xf:message level="modal"&gt;
              Error : &lt;xf:output value="event('error-type')"/&gt;; 
              Status : &lt;xf:output value="event('response-status-code')"/&gt;; 
              URI : &lt;xf:output value="event('resource-uri')"/&gt;; 
              Headers : &lt;xf:output value="event('response-headers')"/&gt;; 
              Reason : &lt;xf:output value="event('response-reason-phrase')"/&gt; 
              Body : &lt;xf:output value="event('response-body')"/&gt;.
          &lt;/xf:message&gt;
      &lt;/xf:action&gt;
  &lt;/xf:submission&gt;
  </code></pre>
  
  <p>Everything is working great except that before each submission of  <code>instance('newEntity')</code>, we have a submission error with an error message : "submission-in-progress".</p>
  
  <p>In fact with this example, and I don't know why, we have 5 submissions instead of 3 : </p>
  
  <ul>
  <li>2 for the relation 'Elisa Doe' (the first fails, the second is OK)</li>
  <li>2 for the relation 'Richard Doe' (the first fails, the second is OK)</li>
  <li>1 for John Doe (the "main" form)</li>
  </ul>
  
  <p>We don't know how to avoid that and we are asking for some help, if someone has an idea ?</p>
  
  <p>Below are the two complete files.</p>
  
  <p>The form :</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:ev="http://www.w3.org/2001/xml-events"&gt;
      &lt;head&gt;
          &lt;title&gt;Submission&lt;/title&gt;
          &lt;xf:model&gt;
              &lt;xf:instance id="entity"&gt;
                  &lt;entity xmlns=""&gt;
                      &lt;name&gt;John Doe&lt;/name&gt;
                      &lt;age&gt;35&lt;/age&gt;
                      &lt;address&gt;North Cap&lt;/address&gt;
                      &lt;relations&gt;
                          &lt;relation ref="" type="sibling"&gt;Elisa Doe&lt;/relation&gt;
                          &lt;relation ref="" type="parent"&gt;Richard Doe&lt;/relation&gt;
                      &lt;/relations&gt;
                  &lt;/entity&gt;
              &lt;/xf:instance&gt;
  
              &lt;xf:instance id="newEntity"&gt;
                  &lt;entity xmlns=""&gt;
                      &lt;name/&gt;
                      &lt;age/&gt;
                      &lt;address/&gt;
                      &lt;relations&gt;
                          &lt;relation ref="" type=""/&gt;
                      &lt;/relations&gt;
                  &lt;/entity&gt;
              &lt;/xf:instance&gt;
  
              &lt;xf:instance id="iterate"&gt;
                  &lt;iterate xmlns=""/&gt;
              &lt;/xf:instance&gt;
  
              &lt;xf:submission ref="instance('entity')" id="submitEntity" resource="/test/form/put" method="put" replace="none"&gt;
                  &lt;xf:action ev:event="xforms-submit-done"&gt;
                      &lt;xf:message level="modal"&gt;
                          OK ! 
                          Status : &lt;xf:output value="event('response-status-code')"/&gt;; 
                          URI : &lt;xf:output value="event('resource-uri')"/&gt;; 
                          Headers : &lt;xf:output value="event('response-headers')"/&gt;; 
                          Reason : &lt;xf:output value="event('response-reason-phrase')"/&gt;;
                          Body : &lt;xf:output value="event('response-body')"/&gt;.
                      &lt;/xf:message&gt;
                  &lt;/xf:action&gt;
                  &lt;xf:action ev:event="xforms-submit-error"&gt;
                      &lt;xf:message level="modal"&gt;
                          Error : &lt;xf:output value="event('error-type')"/&gt;; 
                          Status : &lt;xf:output value="event('response-status-code')"/&gt;; 
                          URI : &lt;xf:output value="event('resource-uri')"/&gt;; 
                          Headers : &lt;xf:output value="event('response-headers')"/&gt;; 
                          Reason : &lt;xf:output value="event('response-reason-phrase')"/&gt; 
                          Body : &lt;xf:output value="event('response-body')"/&gt;.
                      &lt;/xf:message&gt;
                  &lt;/xf:action&gt;
              &lt;/xf:submission&gt;
  
              &lt;xf:submission ref="instance('newEntity')" id="submitNewEntity" resource="/test/form/put" method="put" replace="none"&gt;
                  &lt;xf:action ev:event="xforms-submit-done"&gt;
                      &lt;xf:message level="modal"&gt;
                          OK 
                          Status : &lt;xf:output value="event('response-status-code')"/&gt;; 
                          URI : &lt;xf:output value="event('resource-uri')"/&gt;; 
                          Headers : &lt;xf:output value="event('response-headers')"/&gt;; 
                          Reason : &lt;xf:output value="event('response-reason-phrase')"/&gt;;
                          Body : &lt;xf:output value="event('response-body')"/&gt;.
                      &lt;/xf:message&gt;
                      &lt;xf:setvalue value="event('response-body')//*:id" ref="instance('entity')//relation[position() = instance('iterate')]/@ref"/&gt;
                      &lt;xf:setvalue ref="instance('iterate')" value="instance('iterate') + 1"/&gt;
                  &lt;/xf:action&gt;
                  &lt;xf:action ev:event="xforms-submit-error"&gt;
                      &lt;xf:message level="modal"&gt;
                          Error : &lt;xf:output value="event('error-type')"/&gt;; 
                          Status : &lt;xf:output value="event('response-status-code')"/&gt;; 
                          URI : &lt;xf:output value="event('resource-uri')"/&gt;; 
                          Headers : &lt;xf:output value="event('response-headers')"/&gt;; 
                          Reason : &lt;xf:output value="event('response-reason-phrase')"/&gt; 
                          Body : &lt;xf:output value="event('response-body')"/&gt;.
                      &lt;/xf:message&gt;
                  &lt;/xf:action&gt;
              &lt;/xf:submission&gt;
  
          &lt;/xf:model&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;xf:input ref="name"&gt;
              &lt;xf:label&gt;name : &lt;/xf:label&gt;
          &lt;/xf:input&gt;
          &lt;br /&gt;
          &lt;xf:input ref="age"&gt;
              &lt;xf:label&gt;age : &lt;/xf:label&gt;
          &lt;/xf:input&gt;
          &lt;br /&gt;
          &lt;xf:input ref="address"&gt;
              &lt;xf:label&gt;address : &lt;/xf:label&gt;
          &lt;/xf:input&gt;
          &lt;br /&gt;
          &lt;xf:repeat nodeset="relations/relation" id="repeatRelation"&gt;
              &lt;xf:input ref="."&gt;
                  &lt;xf:label&gt;Name : &lt;/xf:label&gt;
              &lt;/xf:input&gt;
              &lt;xf:select1 ref="@type"&gt;
                  &lt;xf:item&gt;
                      &lt;xf:label&gt;parent&lt;/xf:label&gt;
                      &lt;xf:value&gt;parent&lt;/xf:value&gt;
                  &lt;/xf:item&gt;
                  &lt;xf:item&gt;
                      &lt;xf:label&gt;sibling&lt;/xf:label&gt;
                      &lt;xf:value&gt;sibling&lt;/xf:value&gt;
                  &lt;/xf:item&gt;
              &lt;/xf:select1&gt;
              &lt;xf:trigger&gt;
                  &lt;xf:label&gt;X&lt;/xf:label&gt;
                  &lt;xf:action ev:event="DOMActivate"&gt;
                      &lt;xf:delete ref="." at="1" if="count(//relation) &gt; 1"/&gt;
                  &lt;/xf:action&gt;
              &lt;/xf:trigger&gt;
          &lt;/xf:repeat&gt;
          &lt;xf:trigger&gt;
              &lt;xf:label&gt;Add relation&lt;/xf:label&gt;
              &lt;xf:action ev:event="DOMActivate"&gt;
                  &lt;xf:insert nodeset="relations/relation" at="last()"/&gt;
                  &lt;xf:setvalue ref="relations/relation[index('repeatRelation')] | relations/relation[index('repeatRelation')]/@*"/&gt;
              &lt;/xf:action&gt;
          &lt;/xf:trigger&gt;
          &lt;br/&gt;
          &lt;xf:trigger&gt;
              &lt;xf:label&gt;submit&lt;/xf:label&gt;
              &lt;xf:action ev:event="DOMActivate"&gt;
                  &lt;xf:setvalue ref="instance('iterate')" value="1"/&gt;
                  &lt;xf:setvalue ref="instance('newEntity')/name" value="instance('entity')/relations/relation[position() = instance('iterate')]"/&gt;
                  &lt;xf:action while="count(//relation) &amp;gt;= instance('iterate')"&gt;
                      &lt;xf:send submission="submitNewEntity"/&gt;
                      &lt;xf:action if="count(//relation) &amp;lt; instance('iterate')"&gt;
                          &lt;xf:send submission="submitEntity"/&gt;
                      &lt;/xf:action&gt;
                  &lt;/xf:action&gt;
              &lt;/xf:action&gt;
          &lt;/xf:trigger&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>The Xquery requests for BaseX</p>
  
  <pre><code>xquery version "3.0";
  module namespace test = "test";
  
  declare namespace rest = "http://exquery.org/ns/restxq";
  declare namespace file = "http://expath.org/ns/file";
  declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
  declare namespace web = "http://basex.org/modules/web";
  declare namespace update = "http://basex.org/modules/update";
  declare namespace db = "http://basex.org/modules/db";
  
  declare namespace xf = "http://www.w3.org/2002/xforms";
  declare namespace ev = "http://www.w3.org/2001/xml-events";
  
  declare default element namespace "test";
  declare default function namespace "test";
  
  declare default collation "http://basex.org/collation?lang=fr";
  
  declare variable $test:xsltFormsPath := "/test/files/xsltforms/xsltforms.xsl";
  
  
  (:~
   : this function defines a static files directory for the app
   :
   : @param $file file or unknown path
   : @return binary file
   :)
  declare
  %rest:path('test/files/{$file=.+}')
  function test:file($file as xs:string) as item()+ {
      let $path := file:base-dir() || 'files/' || $file
      return
          (
          web:response-header( map {'media-type' : web:content-type($path)}),
          file:read-binary($path)
          )
  };
  
  (:~
   : install db
   : @return create the db
   :
   : @todo create the prosopo db
   :)
  declare 
    %rest:path("/test/install")
    %output:method("xml")
    %updating
  function install() {
    if (db:exists("test")) 
      then (
        update:output("db 'test' already exists !")
       )
      else (
        update:output("db 'test' has been created"),
        db:create( "test", &lt;root/&gt;, "test.xml")
        )
  };
  
  
  (:~
   : This function returns db "test"
   :
   :)
  declare
    %rest:path("/test")
    %output:method("xml")
  function opendb() {
    db:open('test')
  };
  
  
  (:~
   : This function returns the entity form
   :
   :)
  declare
    %rest:path("test/form")
    %output:method("xml")
  function test() {
    fn:doc('files/submission.xml')
  };
  
  (:~
   : This function sends entity instance to db "test"
   : an @xml:id is created and sent to the form as http response
   : @param $param content
   :)
  
   declare
  %rest:path("test/form/put")
  %output:method("xml")
  %rest:header-param("Referer", "{$referer}", "none")
  %rest:PUT("{$param}")
  %updating
  function entityPut($param, $referer) {
    let $db := db:open("test")
    return 
      let $id := 'person' || fn:format-integer(fn:count($db/*:root/*:entity) + 1, '0000')
      let $param :=
        copy $d := $param
        modify insert node attribute xml:id {$id} into $d/*
        return $d
      return (
        insert node $param into $db/*:root,
        update:output(
           (
            &lt;rest:response&gt;
              &lt;http:response status="200" message=""&gt;
                &lt;http:header name="Content-Language" value="fr"/&gt;
                &lt;http:header name="Content-Type" value="text/plain; charset=utf-8"/&gt;
              &lt;/http:response&gt;
            &lt;/rest:response&gt;,
            &lt;result&gt;
              &lt;id&gt;{$id}&lt;/id&gt;
            &lt;/result&gt;
           )
         )
      )
  };
  </code></pre>
  
  <p>Thanks a lot for your help !!</p>