Use parts on repeated elements

Posted by Tom.

The basics

Hobo’s part mechanism makes it very easy to have parts of the page updates “ajax” style. All you do is add the part attribute to a tag somewhere:

<div part="my-part">
  ... this section can be updated without reloading the page
</div>

Then use the update attribute, which is supported by various Rapid tags, invcluding <form>

<form update="my-part"> ... <submit label="Go!"/></form>

The presence of the update tells Rapid to generate an ajax form. When the use clicks that “Go!” button, the form is submitted in the background, the content “my-part” is re-rendered on the server, and the new content is placed onto the page.

The problem

What if you want to have a part in a repeated section of the page? The following will not work:

<ul>
  <li repeat>
    <div part="foo"> ... </div>
    <form update="foo"> ... <submit label="Go!"/></form>
  </li>
</ul>

That makes sense, after all, which of the <div> elements should be updated.

Some points to understand about the part mechanism:

- The part name is a global and static name, much like the name of a Rails partial

- The string you pass to the update attribute is actually not a part name, it is a DOM ID.

- By default, a tag with part="foo" is automatically given id="foo". (that’s why the first example in this recipe works - if you view-source you will see that the <div> has been given id="my-part")

That should clarify why the second example doesn’t work. There are multiple tags <div id="my-part"> in the output, which is invalid.

The solution

To override the part-name becoming the tags ID, just give an explicit id attribute. The typed_id helper is a handy way to generate a unique ID based on the model-name and ID of this. The working version of the second example is:

<ul>
  <li repeat>
    <div part="foo" id="foo-#{typed_id}"> ... </div>
    <form update="foo-#{typed_id}"> ... <submit label="Go!"/></form>
  </li>
</ul>

One more tip

If it makes sense in your page to have the <form> inside the part, you can just say update="self":

<ul>
  <li repeat>
    <div part="foo" id="foo-#{typed_id}">
      ...
      <form update="self"> ... <submit label="Go!"/></form>
    </div>
  </li>
</ul>

This is particularly useful in reusable tags that contain an updatable part

User contributed notes

  • On October 25, 2008 kevinpfromnm said:

    Can you use the normal form tag attributes to direct where the form action goes? Also, does the action need to return any particular information or is it handled by a separate call?