Michael Prescott-2 wrote:
> 
> We've got a couple of forms where users can edit a list of items, and
> also add new items to the bottom.  We're currently doing this by sending
> preset number of hidden rows, revealed as necessary by Javascript -
> although this is a little lame.

This is one of those things that used to bug me with Tap4, but it's actually
very, very easy to work around the whole "can't instantiate components on
the fly" problem.  The way to do it is to create a JavaScript object on the
client side that's updated to the state of your fields, which you can create
dynamically.  Then onSubmit, you convert your JS Object into a JSON
transport string and populate a hidden form field with the results, which
are then submitted.  You then just have to re-instantiate the Object into a
Java HashMap.  Read up on  http://www.json.org/java/index.html JSON .

Here's an egregiously simple example that should get you started...

In your .page:
  <component id="addNamesForm" type="Form">
    <binding name="success" value="listener:doSubmit"/>
  </component>

  <component id="bigListoNames" type="Hidden">
    <binding name="value" value="ognl:namesList"/>
  </component>

  <component id="nameField" type="TextField">
    <binding name="value" value="ognl:theName"/>
  </component>

In your .java:
  public abstract String getTheName();
  public abstract void setTheName(String theName);

  public abstract String getNamesList();
  public abstract void setTheNamesList(String theNamesList);

  public IPage doSubmit(IRequestCycle cycle) {
    JSONObject namesList;
    HashMap<Integer, String> allNamesMap = new HashMap<Integer, String>();
    try {
      namesList = new JSONObject(getNamesList());
      for (Iterator aName = namesList.keys(); aName.hasNext();) {
        String keyStr = (String) aName.next();
        Integer key = Integer.parseInt(keyStr);
        allNamesMap.put(key, namesList.get(keyStr).toString());
      }
    } catch (JSONException e) {
      log.info("Failed: ", e.getMessage());
      return null;
    }
    // Now iterate through your allNamesMap and save them however you see
fit.
    return this;
  }

In your .html:
  <form jwcid="addNamesForm">
    <span jwcid="bigListoNames" id="bigListoNames" />
    <div id="namesDiv">
        <input jwcid="nameField" id="name_0" onchange="Names.update(this.id,
this.value);"/>
    </div>
     # Add another name. 
    <input type="button" id="save" value="Save"
onclick="document.getElementById('bigListoNames').value = 'S' +
Names.generateJSON(); Tapestry.submit_form(addNamesForm, this.id); />
  </form>

  <script type="text/javascript">
    function newName() {
      Names.add();
      var newInput = "<input id=\"name_" + Names.GUID + "\" />";
      var targetDiv = document.getElementById("namesDiv");
      targetDiv.innerHTML = targetDiv.innerHTML + newInput;
      document.getElementById("name_" + Names.GUID).onchange = function() {
        Names.update(this.id, this.value);
      }
    }

    Names = {
      elements: {},
      GUID: 0;
      update: function(id, value) {
        var realId = parseInt(id.split("_")[1], 10);
        Names.elements[realId] = value;
      },
      add: function() {
        Names.GUID++;
        Names.elements[Names.GUID] = null;
      },
      generateJSON: function() {
        return (Names.elements).toJSONString();
      }
    }
  </script>

There might be some typos in there, but that's the basic form.  You can make
your JS objects as complicated or simple as you like (this one, for
instance, is just one level deep, but it's perfectly cromulant to make
nested objects... it just takes more code to go back to a POJO when you
submit).  The JSON code is (I believe) straight from the link I gave above. 
The JavaScript JSON methods are very, very simple (naturally) and can be
downloaded  http://www.json.org/json.js here .
-- 
View this message in context: 
http://www.nabble.com/Variable-numbers-of-rows-tf3255330.html#a9075214
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to