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
>