Hi Dan, The important bit is Context.renderTemplate which takes a template and model and passes it to Velocity to render.
http://click.apache.org/docs/click-api/org/apache/click/Context.html#renderTemplate%28java.lang.String,%20java.util.Map%29 So you can also do: public ActionResult onMyPageAction() { String templatePath = "/path/to/template.htm"; Map model = new HashMap(); model.put("date", new Date()); String html = getContext.renderTemplate(templatePath, model); return new ActionResult(html, ActionResult.HTML); } Kind regards Bob On Tue, May 14, 2013 at 7:57 AM, Malcolm Edgar <[email protected]>wrote: > I would recommend using a Velocity template for the the AJAX content > > Below is some example custom Title control with its own Velocity template. > > import java.util.Map; > > import org.apache.click.Context; > import org.apache.click.Page; > import org.apache.click.control.AbstractContainer; > import org.apache.click.dataprovider.DataProvider; > import org.apache.click.util.ClickUtils; > import org.apache.click.util.HtmlStringBuffer; > > /** > * Provides a Tile List control. > */ > @SuppressWarnings("rawtypes") > public class TileList extends AbstractContainer { > > private static final long serialVersionUID = 1L; > > // The tile data provider. > private DataProvider dataProvider; > > // The tile data provider. > private String tileTemplate; > > // Constructor > ------------------------------------------------------------ > > public TileList(String name) { > setName(name); > } > > // Public Methods > --------------------------------------------------------- > > public DataProvider getDataProvider() { > return dataProvider; > } > > public void setDataProvider(DataProvider dataProvider) { > this.dataProvider = dataProvider; > } > > public String getTileTemplate() { > return tileTemplate; > } > > public void setTileTemplate(String tileTemplate) { > this.tileTemplate = tileTemplate; > } > > @Override > public String getTag() { > return "div"; > } > > @Override > public void render(HtmlStringBuffer buffer) { > > if (tileTemplate == null) { > throw new RuntimeException("No tileTemplate has been defined"); > } > > Context context = getContext(); > Page page = getPage(); > > Map<String, Object> model = ClickUtils.createTemplateModel(page, > context); > > Iterable itemList = getDataProvider().getData(); > model.put("itemList", itemList); > > String content = context.renderTemplate(getTileTemplate(), model); > > buffer.append(content); > } > > } > > *The page code looks like this:* > > import java.util.ArrayList; > import java.util.List; > > import javax.servlet.http.HttpServletRequest; > > import net.sf.click.ajax4click.MultiActionResult; > import net.sf.click.ajax4click.control.AjaxForm; > import net.sf.click.ajax4click.jquery.JQBehavior; > import net.sf.click.ajax4click.jquery.JQEvent; > > import org.apache.click.ActionResult; > import org.apache.click.Control; > import org.apache.click.control.Submit; > import org.apache.click.control.TextField; > import org.apache.click.dataprovider.DataProvider; > import org.apache.click.element.Element; > import org.apache.click.element.JsImport; > > import com.avoka.fc.core.entity.Form; > import com.avoka.fc.portal.control.SearchField; > import com.avoka.fc.portal.control.TileList; > import com.avoka.fc.portal.tile.FormTile; > import com.avoka.fc.portal.util.PageUtils; > > /** > * Page that provides form discovery and searching capabilities. > */ > public class FindFormPage extends AccountPage { > > private static final long serialVersionUID = 1L; > > private AjaxForm form = new AjaxForm("form"); > private TileList tileList = new TileList("tileList"); > private TextField searchField = new SearchField(); > > // Constructor > ------------------------------------------------------------ > > public FindFormPage() { > buildSearchForm(); > buildTileList(); > > addModel("noRecordsMsg", "No Forms found."); > } > > @Override > public List<Element> getHeadElements() { > if (headElements == null) { > headElements = super.getHeadElements(); > headElements.add(new > JsImport("/resources/js/findFormPage.js")); > } > > return headElements; > } > > // Private Methods > -------------------------------------------------------- > > private void buildSearchForm() { > > addControl(form); > > form.setColumns(2); > form.addStyleClass("form-search"); > > form.add(searchField); > searchField.getAttributes().put("placeholder", "Search"); > searchField.getAttributes().remove("style"); > searchField.addStyleClass("percentageWidth"); > searchField.setSize(20); > > Submit submit = new Submit("go"); > > submit.addStyleClass("btn"); > submit.addStyleClass("btn-primary"); > > PageUtils.addPrimaryButtonClass(this, submit); > submit.addBehavior(new JQBehavior() { > @Override > public ActionResult onAction(Control source, JQEvent > eventType) { > return new MultiActionResult(tileList); > } > }); > form.add(submit); > } > > private void buildTileList() { > addControl(tileList); > > > tileList.setTileTemplate("/resources/includes/account/tile-form.html"); > > tileList.setDataProvider(new DataProvider<FormTile>() { > private static final long serialVersionUID = 1L; > @Override > public Iterable<FormTile> getData() { > // Create form tile list > String keyword = searchField.getValue(); > HttpServletRequest request = getContext().getRequest(); > > List<Form> formList = > getFormPortalService().getFormListForKeywordAndPortal(keyword, request, > getPortal()); > > List<FormTile> tileList = new ArrayList<FormTile>(); > for (Form form : formList) { > tileList.add(new FormTile(form, getPortal())); > } > > return tileList; > } > }); > } > > } > > *The title template looks like this:* > > <div id="wrapper" class="tileList"> > #foreach ($item in $itemList) > > > <div class="clearBox clearfix well"> > <span > onclick="jQuery('#descTruncR1${velocityCount}').toggle('fast');jQuery('#descDetailedR1${velocityCount}').toggle('fast');jQuery('#descDetailedR2${velocityCount}').toggle('fast');" > class="infocell" id="span-${velocityCount}"> > <i class="small-icon ${item.tileImgSrc} floatleft"></i> > <div class="margin-small-icon"> > #if ($item.primaryActionLabel) > <p> > <b>${item.tileTitle}</b> > </p> > #end > #if ($item.tileDescription) > <p id="descDetailedR1${velocityCount}" style="display:none;"> > ${item.tileDescription}</br> > </p> > #end > #if ($item.tileDescription) > <p id="descTruncR1${velocityCount}" class="description truncated"> > $format.limitLength(${item.tileDescription}, 100, "...")</br> > </p> > #else > <p> </p> > #end > <p id="descDetailedR2${velocityCount}" style="display:none;"> > Organization: <b>${item.form.client.clientName}</b> > </p> > </div> > </span> > > <span class="buttoncell floatright"> > <a type="submit" > class="btn btn-primary floatright tileButton" > > onclick="javascript:document.location.href='${item.primaryActionLink}';cancelEventPropagation(event > || window.event);" ${item.primaryActionTarget} > ${item.primaryActionOnclick}><i class="icon-folder-white > hidden-desktop"></i> > <span class="visible-desktop">$item.primaryActionLabel</span> > </a> > </span> > > </div> > > #end > > > #if ($itemList.isEmpty()) > <div class="alert alert-info"> > <div class="row"> > <div class="span9"> > <p> > ${noRecordsMsg} > </p> > </div> > </div> > </div> > #end > > </div> > > regards Malcolm Edgar > > > On Tue, May 14, 2013 at 3:29 PM, Daniel Ingalla <[email protected]>wrote: > >> Developers, >> >> First off- great work! I wish I would of found this framework earlier- >> it is by far the quickest, easiest server-side java web framework I have >> worked with thus far (Vaadin, Spring MVC and Struts included). I never >> thought I could get a lightning fast dynamic web site up within a few hours >> of reading the click tutorial... simply amazing and concise. >> >> My question is this: is there any way to leverage html & velocity >> templates when responding to an Ajax request... I really do not wish to do >> this: >> >> public ActionResult onMyPageAction(){ >> >> StringBuilder html = new StringBuilder(); >> html.append( >> " <p>Some really long html with tags and such.. etc, >> etc...</p>"); >> return new ActionResult(html.toString(), ActionResult.HTML); >> } >> >> I suppose it would be nice to programmatically load an html template, set >> some model objects, run it through the velocity parser, and then return >> that html output in the call. >> >> Regards, >> Dan >> > >
