title: Building form with dynamic rows
body: <p>How can I make flutter widget equivalent to my below html5 widget?</p>
  <p>In my html I've a form in the form of table where only first row appear, then the user can add whatever rows he want, (and can delete any row he want, unless it is the only row in the form) as show:</p>
  <p><a href="https://i.stack.imgur.com/s4uSa.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/s4uSa.gif" alt="enter image description here" /></a></p>
  <p>The code I'm using is:</p>
  <pre class="lang-js prettyprint-override"><code>&lt;script&gt;
    function deleteRow(row) {
      var i = row.parentNode.parentNode.rowIndex - 1; // this -&gt; td -&gt; tr // -1 because the first row is used for header
      var tbl = document.querySelector('#dataTable');
      if(tbl &amp;&amp; tbl.rows.length &gt; 1) {
        tbl.deleteRow(i); 
        Array.from(tbl.rows).forEach((row, index) =&gt; {
          row.cells[0].innerHTML = index + 1;
        });
      }
    } 
  
    function insRow(row) {
      var i = row.parentNode.parentNode.rowIndex - 1; // this -&gt; td -&gt; tr // -2 because the first row is used for header
      var tbl = document.querySelector('#dataTable');
      var row = document.createElement('tr');
      row.innerHTML=`
        &lt;th&gt;&lt;/th&gt;
        &lt;td&gt;&lt;input size=25 type=&quot;text&quot; name=&quot;color1&quot; /&gt;&lt;/td&gt;
        &lt;td&gt;&lt;input size=25 type=&quot;text&quot; name=&quot;color2&quot; &gt;&lt;/td&gt;
        &lt;td&gt;&lt;i class=&quot;fas fa-edit&quot; onclick=&quot;insRow(this)&quot;&gt;&lt;/i&gt;&lt;/td&gt;
        &lt;td&gt;&lt;i class=&quot;fas fa-eraser&quot; onclick=&quot;deleteRow(this)&quot;&gt;&lt;/i&gt;&lt;/td&gt;
      `;
      var len = tbl.rows.length;
      row.cells[0].innerHTML = len + 1;
      tbl.insertBefore(row, tbl.children[i+1]);
      Array.from(tbl.rows).forEach((row, index) =&gt; {
        row.cells[0].innerHTML = index + 1;
      });
      //tbl.appendChild(row);
    }
  &lt;/script&gt;
  </code></pre>
  <p>And the form itself is made with the follwoing html</p>
  <pre class="lang-html prettyprint-override"><code>&lt;form method=&quot;POST&quot;&gt;
    &lt;fieldset&gt;
      &lt;legend&gt;توزيع مبلغ البيان على طلبات الشراء&lt;/legend&gt;
      &lt;table&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;th&gt;التسلسل&lt;/td&gt;
            &lt;th&gt;رقم طلب الشراء&lt;/td&gt;
            &lt;th&gt;قيمة فاتورة طلب الشراء&lt;/td&gt;
            &lt;th colspan=&quot;2&quot;&gt;إضافه/حذف&lt;/td&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody id=&quot;dataTable&quot;&gt;
          &lt;tr&gt;
            &lt;th&gt;1&lt;/th&gt;
            &lt;td&gt;&lt;input size=25 type=&quot;text&quot; name=&quot;color1&quot; /&gt;&lt;/td&gt;
            &lt;td&gt;&lt;input size=25 type=&quot;text&quot; name=&quot;color2&quot; /&gt;&lt;/td&gt;
            &lt;td colspan=&quot;2&quot;&gt;&lt;i class=&quot;fas fa-edit&quot; onclick=&quot;insRow(this)&quot;&gt;&lt;/i&gt;&lt;/td&gt;
          &lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
    &lt;/fieldset&gt;
    &lt;br/&gt;
     &lt;input dir=&quot;ltr&quot; type=&quot;submit&quot; value=&quot;SEND إرسال&quot;&gt;
  &lt;/form&gt;
  </code></pre>
  <p>The form is executed from a GO code as:</p>
  <pre class="lang-golang prettyprint-override"><code>// ContactDetails ...
  type ContactDetails struct {
      Email   string
      Subject string
      Message string
      Color1  []string
      Color2  []string
  }
  
  // ReturnedResult ...
  type ReturnedResult struct {
      Result  bool   `json:&quot;result&quot;`
      Message string `json:&quot;message&quot;`
  }
  
  func index(w http.ResponseWriter, r *http.Request) {
      tmpl := template.Must(template.ParseFiles(fmt.Sprintf(&quot;%v&quot;, &quot;formen.html&quot;))) // index.html
      if r.Method != http.MethodPost {
          tmpl.Execute(w, nil)
          return
      }
  
      r.ParseForm()
      fmt.Println(r.Form) // print information on server side.
      fmt.Println(&quot;path&quot;, r.URL.Path)
      fmt.Println(&quot;scheme&quot;, r.URL.Scheme)
  
      for k, v := range r.Form {
          fmt.Println(&quot;key:&quot;, k)
          fmt.Println(&quot;val:&quot;, v)
      }
      details := ContactDetails{
          Email:   r.FormValue(&quot;email&quot;),
          Subject: r.FormValue(&quot;subject&quot;),
          Message: r.FormValue(&quot;message&quot;),
          Color1:  r.Form[&quot;color1&quot;],
          Color2:  r.Form[&quot;color2&quot;],
      }
      fmt.Printf(&quot;Post from website! r.PostFrom = %v\n&quot;, r.PostForm)
      fmt.Printf(&quot;Details = %v\n&quot;, details)
  
      //r.FormValue(&quot;username&quot;)
      fmt.Println()
      // do something with details
      sheetID := &quot;AKfycbxfMucXOzX15tfU4errRSAa9IzuTRbHzvUdRxzzeYnNA8Ynz8LJuBuaMA/exec&quot;
      url := &quot;https://script.google.com/macros/s/&quot; + sheetID + &quot;/exec&quot;
      bytesRepresentation, err := json.Marshal(details)
      if err != nil {
          log.Fatalln(err)
      }
      resp, err := http.Post(url, &quot;application/json&quot;, bytes.NewBuffer(bytesRepresentation))
      if err != nil {
          log.Fatalln(err)
      }
      // read all response body
      data, _ := ioutil.ReadAll(resp.Body)
  
      // close response body
      resp.Body.Close()
  
      webReturn := ReturnedResult{}
      if err := json.Unmarshal([]byte(data), &amp;webReturn); err != nil {
          panic(err)
      }
      fmt.Println(webReturn.Message)
  
      webReturn.Message = strings.ReplaceAll(webReturn.Message, &quot;&amp;export=download&quot;, &quot;&quot;)
      //tmpl.Execute(w, struct{ Success bool }{webReturn.Result})
      tmpl.Execute(w, webReturn)
  
  }
  </code></pre>