How to render a template from controller within template -- Java, Play 2.1 - scala

Is it possible to call a controller method to render a template within a template?
Or is that totally the wrong aproach?
In the div container there is only a sting displayed but not the redered html from my productTable template.
The displayed string inside the <div class="products">:
SimpleResult(200, Map(Content-Type -> text/html; charset=utf-8))
Template:
#categories.map {cat =>
<div>some html</div>
<div class="products">#controller.Products.getByCatergoyId(cat.id)</div>
}
Controller:
public static Result getByCatergoyId(Long catId) {
List<Product> products = Product.find.where().eq("category.id", catId).findList();
return ok(views.html.display.productTable.render(products));
}

If you want to get the code from the productTable view your method shouldn't return a Result but just a String containing rendered code.... aaaannnyyyyway , there is definitely much better way for rendering sub-templates in Play, check the Tags section of the documentation it does exactly what you want directly from the view, of course you will need to pass a product object to it.
Just create tags package in your view package and add there your sub-template (responsible for rendering only pat of page) it behaves exactly the same as common template.

Related

Accordion dropdown filtering through ion search bar

Hi I just created the ionic accordion dropdowns by following a tutorial blog link which used widgets for creating an accordion dropdowns, Below is the link of that blog.
http://masteringionic.com/blog/2019-01-27-creating-a-simple-accordion-widget-in-ionic-4/
updated: here is the my project demo link https://stackblitz.com/github/dSaif/search-accordion
Everything is working perfect, but i want to add Ion-searchbar at the top of the accordions sothat the dropdowns gets filter by inputing text.
please assist me how can i do that. Thank you.
You are going to have to create a variable in your homepage to store your filtered results. Then you need to have a filter function that will take the input from the search bar and filter your master list. Keep in mind you should not set the new variable to the master list, this could cause issues due to object referencing.
So you should have something like
in your html
<ion-searchbar placeholder="Search a name." [(ngModel)]="searchValue" (ionChange)="filterList()"></ion-searchbar>
In your ts file
searchValue: string = '';
filteredList: Array<{ name: string, description: string, image: string }> = this.technologies;
// function called in the html whenever you change the ion searchbar value
private filterList(){
//Make a variable so as to avoid any flashing on the screen if you set it to an empty array
const localFilteredList = []
this.technologies.forEach(currentItem => {
//here goes your search criteria, in the if statement
if(currentItem.name && currentItem.name.toLowerCase().includes(this.searchValue.toLowerCase())) {
localFilteredList.push(currentItem);
}
});
//finally set the global filter list to your newly filtered list
this.filteredList = localFilteredList;
}
You also need to make sure to reference the filterList variable instead of the current one you are referencing.

Dynamically assigning different templates based on data - using helper or custom tag

I render a jsrender template in template object.
var colorTmpl = {
"color": jQuery.templates("<span>{{:~val}}</span>"),
}
var jsrendertmpl = {};
jQuery.extend(jsrendertmpl, colorTmpl);
If I access the jsrendertmpl.colorTmpl.render() it will render the color template. If I include this tmpl template tag within other template like this
{colorArr: ["white", "blue", "black"]}
{{for colorArr tmpl="jsrendertmpl.colorTmpl"/}}
It will not include that subtemplate into parent template. So I add a custom tag to include this subtemplate within object
includetmpl: function(tmplname){
return Template.render(tmplVal, jObj);
},
If I include the subtemplate in parent template {{:~val}} cannot be recognised
Parent Template with customised include tag
{{for colorArr itemVar='~val'}}
{{includetmpl "color"}}
{{/for}}
Parent template without subtemplate (It works fine)
{{for colorArr itemVar='~val'}}
<span>{{:~val}}</span>
{{/for}}
Is there any way to access that value. I used a {{setvar}} and {{:~getvar}} for workaround but need a permanent solution.
Thanks in advance.
There are a few ways you can implement that scenario - i.e. to provide different templates based on a data parameter that you pass in.
For example you can pass in the template as a helper:
$.views.helpers("myTemplates", {
color: $.templates("<span>{{:}}</span>"),
colorVal: $.templates("<span>{{:~val}}</span>")
});
And use it as in
{{for colorArr tmpl=~myTemplates.color/}}
or if tmplVar is your chosen template: "color"
{{for colorArr tmpl=~myTemplates[tmplVar]/}}
You can also create a custom tag, as you suggest, in either of the following ways:
$.views.tags("includetmpl", {
init: function(tagCtx) {
this.template = myTemplates[tagCtx.props.template];
}
});
or
$.views.tags("includetmpl2", {
render: function(val) {
return myTemplates[this.tagCtx.props.template].render(val, this.ctx);
}
});
(Note how I pass the context also to my render function, in the second version, so that ~val will be available...)
Then use it as in the following:
{{for colorArr}}{{includetmpl template="color"/}}{{/for}}
or
{{for colorArr itemVar="~val"}}{{includetmpl template="colorVal"/}}{{/for}}
See https://jsfiddle.net/BorisMoore/coezx8xj/ for all of the above...
I will change the title of your question to make it clearer.

how to create a repeating list of links inside a li tag using apache wicket?

In Apache Wicket I would like to create a repeating list of links from code. I am not sure what the template should be to get to an html result that looks like this:
<li>link1</li>
<li>link2</li>
<li>link3</li>
so after much testing this worked for me. HTML should look like:
<ul>
<ui wicket:id="LinkList"><a wicket:id="Link"><span wicket:id="Text"/></a></ui>
</ul>
and then the repeating view code will be:
RepeatingView view = new RepeatingView("LinkList");
add(view);
WebMarkupContainer list = new WebMarkupContainer(view.newChildId());
ExternalLink externalLink = new ExternalLink("Link", "http://www.google.com");
externalLink.add(new Label("Text","Google"));
list.add(externalLink);
view.add(list);
You can use ListView to create a repeating list of links from code. A ListView is a repeater that makes it easy to display/work with Lists. A ListView holds ListItem children. Items can be re-ordered and deleted, either one at a time or many at a time.
Example:
<tbody>
<tr wicket:id="rows" class="even">
<td><span wicket:id="id">Test ID</span></td>
...
Though this example is about a HTML table, ListView is not at all limited to HTML tables. Any kind of list can be rendered using ListView.
The related Java code:
add(new ListView<UserDetails>("rows", listData)
{
public void populateItem(final ListItem<UserDetails> item)
{
final UserDetails user = item.getModelObject();
item.add(new Link("id", user.getId()));
}
});
Where listData contains the id of every link.
There are many choices in how to implement this sort of thing, but they all use some sort of repeater.
See wicket repeater examples for many examples of this.

GWT - Two Question on Hyperlink - Manage its History token parameter + insert it in a span

I need to manage a Hyperlink object in GWT. What i need is :
1 - add it into a span (like InlineLabel)
I tried Hyperlink affitta_3_span_1=new Hyperlink(result.get(i)[0], "");, but it create somethings like this :
<div class="affitta_3_span_1">
t1
</div>
in fact i need this :
<span class="affitta_3_span_1">
t1
</span>
2 - manage Hyperlink History token
I put my internal links such Hyperlink affitta_3_span_1=new Hyperlink(result.get(i)[1], "article/"+result.get(i)[0]) but i don't know how to get the parameter on token when they call the onValueChange() function. How can I do it?
Cheers
Use an Anchor. The output is just an <a> tag that has no <div> or <span> around it, but if you need a <span> you can add it with an HTML panel.
To set a URL that history can access, just put a # at the beginning. Something like
myAnchor.setText(result.get(i)[1]);
myAnchor.setUrl("#article/"+result.get(i)[0]);
Now, when you click myAnchor, onValueChange will be passed the token "article/whatever". The unfortunate side effect is that your urls look like http://example.com/#article/whatever, but that's the only way to get the token to the History object with just GWT.
For the first question, use an Anchor since it's inlined.
For the second one, you need to 'listen' to history change events by extending ValueChangeHandler and calling History.addValueChangeHandler(this); in your class. For example,
class MyClass implements ValueChangeHandler<String> {
public MyClass {
...
History.addValueChangeHandler(this);
}
#Override
public void onValueChange(ValueChangeEvent<String> event) {
String token = event.getValue();
if (token.equals("foo")) {
// go to one page
} else if token.equals("bar")) {
// go to another page
}
}
}
If you only need a ClickHandler on your link and no history support, you can use the Anchor widget, which is based on an <a> tag that has display: inline by default.

Submit PartialView

I have a masterpage that render's the following PartialView:
<% Html.RenderPartial("AddPage); %>
AddPage Controller looks like this:
public class PagController : Controller
{
[HttpGet]
public PartialViewResult AddPage()
{
return PartialView();
}
[HttpPost]
public PartialViewResult AddPage(FormCollection forms)
{
//some logic here
// some view data here
return PartialView();
}
}
And the view looks like this:
<% using (Html.BeginForm("AddPage", "Page", FormMethod.Post, new { ID = "PageManager" })){%>
<%= Html.TextBox("txtAddPage") %>
<input type="submit" value="AddPage" />
<%} %>
My issue is, that when i hit submit i get redirect to : http://localhost:1234/Page/AddPage, when instead i just want the partialview to be submitted, and return some basic view data if needed, as well as stay on the same page.
Am i having a blonde moment here? cause i know i have done this before
EDIT - This partial view is rendered in multiple pages, not just one.
Fullpage postback solution
This is a bit tricky since you have to know where to go back. I suggest you change your view and add two additional hidden fields (or one and parse its value - as you wish) and store current controller/action values in it.
You can then use this data in POST action to return a RedirectResult like:
return RedirectToAction("action_from_field", "controller_from_field");
Ajax postback solution
You can always submit your data using Ajax in which case your postback URL can be anything you want. In your case it should be to the current page URL. Edit: And Ajax would be the preferred solution in your particular case.
If you want to submit and only reload part of your page, you'll need to use AJAX. The most basic way to do this would be to render the partial view in an UpdatePanel.