I have a web app whi开发者_JS百科ch has 3 page views.
1.an index
page where all Item
s in db are listed ,and details of only the Item
with latest creationDate
are shown.
2.An itemDetails
page where details of a selected item are shown.This page also lists all the items in db.
Clicking on a listed item will bring up the itemDetails page.
(These two pages also contain a text input field ,where user can enter a word to search for items matching names.)
3.A search
results page,which shows a listing of items that match a search query.
I implemented the the first two pages and created the static public functions.Now,I want to implement the search.I created the function and a results page which lists the search results.
My problem is that ,if I click on an item from search results,it will bring up the itemDetails page which shows details of that item and a listing of all items in db
,since that is how the itemDetails function was implemented.I would rather have the click take me to a page, which shows the details of item and items which were results of the search query
. I know it is not possible in the above implementaion since state is not retained between two requests.
So,how should I do this?I cannot think clearly about this.Can you shed some light?
The code is like
package controllers;
...
public class Application extends Controller {
...
public static void index() {
//all items
List<Item> items = Item.find("order by creationDate desc").fetch();
//the latest created item
Item item = items.get(0);
render(items,item);
}
public static void itemDetails(Long id) {
//selected item
Item item = Item.findById(id);
//all items
List<item> items = Item.find("order by creationDate desc").fetch();
render(items,item);
}
public static void search(String keyword) {
String kw = keyword.trim();
String pattern = "%"+kw+"%";
String query="select distinct item from Item item where item.name like :pattern";
List<Item> items = Item.find(query).bind("pattern", pattern).fetch();
render(items);
}
...
}
index.html page is
#{extends 'main.html' /}
#{set title:'Home' /}
#{if item}
//show the details of item
#{/if}
#{if items.size()>0}
#{list items:items, as:'item'}
<a href="@{Application.itemDetails(item.id)}">${item.name}</a>
#{/list}
#{/if}
#{else}
There are currently no items
#{/else}
#{form @Application.search(keyword)}
<input type="text" name="keyword" id="keyword" size="18" value=""/>
<input type="submit" value="search"/>
#{/form}
itemDetails.html page:
is similar to the index page ..for the time being I have copied all the contents of index page .
search page:
#{extends 'main.html' /}
#{set title:'search results' /}
#{if items.size()>0}
#{list items:items, as:'item'}
<a href="@{Application.itemDetails(item.id)}">${item.name}</a>
#{/list}
#{/if}
#{else}
<div class="empty">
could not find items with matching name here.
</div>
#{/else}
I see a couple possibilities. First you could add a new public static void itemSearchDetails(Long id, String keyword)
action to your controller. Then add a new itemSearchDetails.html page. Finally change the link in the search.html page to <a href="@{Application.itemSearchDetails(item.id)}">${item.name}</a>
Here is the approach I would take. Modify the itemDetails() method to include a keyword parameter.
public static void itemDetails(Long id, String keyword) {
//selected item
Item item = Item.findById(id);
List<item> items;
if (StringUtils.isNotBlank(keyword) ) {
String query="select distinct item from Item item where item.name like :pattern";
items = Item.find(query).bind("pattern", pattern).fetch();
} else {
items = Item.find("order by creationDate desc").fetch();
}
render(items,item);
}
Then change the corresponding calls in the HTML files.
精彩评论