Tutorials to .com

Tutorials to .com » Jsp » Tapestry-hivemind » tapestry Cart 4, the purchase of the amount of statistics

tapestry Cart 4, the purchase of the amount of statistics

Print View , by: iSee ,Total views: 5 ,Word Count: 4609 ,Date: Thu, 16 Apr 2009 Time: 4:57 AM

If the user intends to buy fruit, then click on the purchase, we will require the user to purchase the number of fruit recorded to statistics. Here, we will record the user's purchase information in the session.

OK, now we need to do something to change. First of all, the definition of a simple object to loaded VO users to buy the fruit:

   com.tapestry4; package com.tapestry4;    class FruitCart { public class FruitCart (            Fruit buyFruit; //  private int  buyMount; //  private double  payMoney; //  public  Fruit getBuyFruit() { private Fruit buyFruit; / / purchase of fruits private int buyMount; / / the purchase of the number of private double payMoney; / / the amount paid by public Fruit getBuyFruit () (                    buyFruit; return buyFruit;           )            void setBuyFruit(Fruit buyFruit) { public void setBuyFruit (Fruit buyFruit) (                   .buyFruit = buyFruit; this. buyFruit = buyFruit;           )           int  getBuyMount() { public int getBuyMount () (                    buyMount; return buyMount;           )            void setBuyMount( int  buyMount) { public void setBuyMount (int buyMount) (                   .buyMount = buyMount; this. buyMount = buyMount;           )           double  getPayMoney() { public double getPayMoney () (                    payMoney; return payMoney;           )            void setPayMoney( double  payMoney) { public void setPayMoney (double payMoney) (                   .payMoney = payMoney; this. payMoney = payMoney;           )   ) 

application documents and then the object inside the definition of Visit:

   value= "com.tapestry4.MyVisit" /> <meta key= "org.apache.tapestry.visit-class" value= "com.tapestry4.MyVisit" /> 

MyVisit and then create a new object:

Visit object is the application file a statement of the java file, Visit object is actually a common web application session object. In Tapestry4.0, use the Visit object to manage the session value is not elected, as from the bottom of hivemind as Tapestry, Hivemind So Tapestry4.0 elected to manage the use of session, we will see how to use Hivemind to manage the session.

Now we return to BuyFruit page, once the user enters the number to buy fruit, it will trigger monitor BuyFruit.java in buyFruitSubmit methods, we should make some corrections buyFruitSubmit monitor the original method, the number of users to buy fruit, the amount of information into the session:

           @SuppressWarnings( "deprecation" ) / / The purchase of fruits @ SuppressWarnings ( "deprecation")           String  buyFruitSubmit() { public String buyFruitSubmit () (                    FruitCart(); FruitCart fc = new FruitCart ();                   .getFruitId()); Fruit f = Products.findFruitById (this. GetFruitId ());                   fc.setBuyFruit (f);                   .getBuyMount()); fc.setBuyMount (this. getBuyMount ());                   .getBuyMount()); fc.setPayMoney (f.getPrice () * this. getBuyMount ());                   .getVisit(); MyVisit visit = (MyVisit) this. GetVisit ();                   List <FruitCart> list = visit.getFruitCartList ();                   (list == null ) { if (list == null) (                            ArrayList<FruitCart>(); list = new ArrayList <FruitCart> ();                   )                   list.add (fc);                   visit.setFruitCartList (list);                   "Cart" ; return "Cart";           ) 

In this method, we find fruitId corresponding Fruit object, according to the number of inputs required to pay the purchase amount, and the user store to buy fruit to Visit object, and finally Cart page Jump to the purchase of all users fruit displayed.

In order to obtain the form when submitted to fruitId, we put in the form of a Hidden components, will be stored in the client fruitId page:

  /> <span jwcid= "fruitIdHidden" />    type= "Hidden" > <component id= "fruitIdHidden" type= "Hidden">         value= "fruitId" /> <binding name= "value" value= "fruitId" />   </ component> 

Hidden in this Tapestry3 usage is frequently used. So, if we do not use Hidden, can also achieve the same page on the client data functions? The answer is yes, way easier.

First, we delete the Hidden components BuyFruit.page stated in a property:

  /> <property name= "fruitId" /> 

And then to group BuyFruit abstract abstract categories, and delete members of fruitId statement variables, and add:

   class BuyFruit extends  BasePage { public abstract class BuyFruit extends BasePage (           ) @ Persist ( "client")           Integer  getFruitId(); public abstract Integer getFruitId ();            void setFruitId( Integer  ig); public abstract void setFruitId (Integer ig);           ........   ) 

Oh, now run the project, we found that the use of @ Persist ( "client") the same effect with the Hidden. In fact, @ Persist ( "client") the role of powerful than Hidden. Careful after a friend running the page to see BuyFruit page in the browser's source code will discover, Tapestry4 added to the page content of the following:

   name= "state:BuyFruit"  value="BrO0ABXcOAAAAAQAAB2ZydWl0S <input type = "hidden" name = "state: BuyFruit" value = "BrO0ABXcOAAAAAQAAB2ZydWl0S   WRzcgARamF2YS5sYW5nLkludGVnZXIS4qCk94GHOAIAAUkABXZhbHVleHIAEGphdmE   ubGFuZy5OdW1iZXKGrJUdC5TgiwIAAHhwAAAAAQ =="/>    name= "reservedids"  value= "state:BuyFruit" /> <input type= "hidden" name= "reservedids" value= "state:BuyFruit" /> 

Hidden in the Form component can only form in use, and can only be access Form form. The @ Persist ( "client") to preserve the data page can be any method to get a monitor. For example, DirectLink, ActionLink and so on. Oh, very convenient.

Users in the purchase of fruits and calculated the amount of deposit Visit object, we need a page to show the purchase of fruits and Statistics:

  Cart.page   <page-specification>       /> <property name= "fruitCart" />        type= "Foreach" > <component id= "fruitListLoop" type= "Foreach">            value= "page.visit.fruitCartList" /> <binding name= "source" value= "page.visit.fruitCartList" />            value= "fruitCart" /> <binding name= "value" value= "fruitCart" />            value= "literal:tr" /> <binding name= "element" value= "literal:tr" />       </ component>        type= "Insert" > <component id= "fruitName" type= "Insert">            value= "fruitCart.buyFruit.name" /> <binding name= "value" value= "fruitCart.buyFruit.name" />       </ component>        type= "Insert" > <component id= "fruitPrice" type= "Insert">            value= "fruitCart.buyFruit.price" /> <binding name= "value" value= "fruitCart.buyFruit.price" />       </ component>            type= "Insert" > <component id= "fruitBuyMount" type= "Insert">            value= "fruitCart.buyMount" /> <binding name= "value" value= "fruitCart.buyMount" />       </ component>        type= "Insert" > <component id= "fruitPayMoney" type= "Insert">            value= "fruitCart.payMoney" /> <binding name= "value" value= "fruitCart.payMoney" />       </ component>        type= "PageLink" > <component id= "buyFruitAgain" type= "PageLink">            value= "literal:Shop" /> <binding name= "page" value= "literal:Shop" />       </ component>   </ page-specification> 
  Cart.html   <html>   <body>     border= "1" > <table width= "76%" border= "1">     > <tr align= "center">       fruit <td> name </ td>       <td> Price </ td>       the number of <td> purchase </ td>       <td> amount </ td>     </ tr>     > <tr jwcid= "fruitListLoop">       /></td> <td> <span jwcid= "fruitName" /> </ td>       /></td> <td> <span jwcid= "fruitPrice" /> </ td>       /></td> <td> <span jwcid= "fruitBuyMount" /> </ td>       /></td> <td> <span jwcid= "fruitPayMoney" /> </ td>     </ tr>   </ table>    jwcid= "buyFruitAgain" ></a> <a href= "#" jwcid= "buyFruitAgain"> continue to purchase fruits </ a>   </ body>   </ html> 

This is a very simple page, but this page does not correspond to Cart.java. Because we can remove the object from the Visit of the stored data.
Because we do not have a java category designated Cart page, it will call the default BasePage.java.

In addition, the final page, we added a PageLink, for return to Shop pages:

   type= "PageLink" > <component id= "buyFruitAgain" type= "PageLink">            value= "literal:Shop" /> <binding name= "page" value= "literal:Shop" />       </ component> 

PageLink use very simple components, only the page name should be available to parameters of the component's page will be generated on the page Jump to the specified link name.

OK, we purchase fruit page has been basically completed. However, we seem toeffectiveness because, since the number of fruits have inventory, if you buy more than the number of inventory, we should remind the user.

In order to achieve the purchase of fruits, number of well-tested, we have to try the new features T4: custom validator.
First, we create a category FruitMountValidator achieve org.apache.tapestry.form.validator.Validator interface:

Now, we look to modify the generated FruitMountValidator new categories:

   class FruitMountValidator implements  Validator { public class FruitMountValidator implements Validator (       Integer  fruitId; private Integer fruitId;        void validate(IFormComponent field, ValidationMessages message, public void validate (IFormComponent field, ValidationMessages message,                    object) throws  ValidatorException { Object object) throws ValidatorException (           .getFruitId()); Fruit fruit = Products.findFruitById (this. GetFruitId ());            n = ( Number )object; Number n = (Number) object;           (n.intValue()>fruit.getMount()){ if (n.intValue ()> fruit.getMount ()) (               ValidatorException( "" + fruit.getName() + "("  + fruit.getMount() throw new ValidatorException ( "the purchase is greater than the number of" + fruit.getName () + "of the inventory (" + fruit.getMount ()                                               , null ); + "), Please re-enter!", Null);           )       )       / **        * Whether the null value as a well-tested.  If you return true, do not enter any value will trigger the validate method, only the third Object parameter is the value of null.         * If the return is false, then enter the null does not trigger the validate method.         * /       boolean  getAcceptsNull() { public boolean getAcceptsNull () (           ; return false;       )       / **        * tapestry and will not use this method only for the convenience of their own logo.         * /       boolean  isRequired() { public boolean isRequired () (           ; return true;       )       / **        * This method can be used to place JavaScript.         * /        void renderContribution(IMarkupWriter arg0, IRequestCycle arg1, public void renderContribution (IMarkupWriter arg0, IRequestCycle arg1,           FormComponentContributorContext arg2, IFormComponent arg3) (       )       Integer  getFruitId() { public Integer getFruitId () (            fruitId; return fruitId;       )        void setFruitId( Integer  fruitId) { public void setFruitId (Integer fruitId) (           .fruitId = fruitId; this. fruitId = fruitId;       )   ) 

In line with our custom Validator function changed a bit for BuyFruit.page:

  <page-specification>        type= "Insert" > <component id= "fruitName" type= "Insert">            value= "fruitDetail.name" /> <binding name= "value" value= "fruitDetail.name" />       </ component>        type= "Insert" > <component id= "fruitPrice" type= "Insert">            value= "fruitDetail.price" /> <binding name= "value" value= "fruitDetail.price" />       </ component>        type= "Insert" > <component id= "fruitMount" type= "Insert">            value= "fruitDetail.mount" /> <binding name= "value" value= "fruitDetail.mount" />       </ component>        class= "com.tapestry4.FruitMountValidator" > <bean name= "fruitMountValidator" class= "com.tapestry4.FruitMountValidator">            value= "ognl:fruitId" /> <set name= "fruitId" value= "ognl:fruitId" />       </ bean>        class= "org.apache.tapestry.valid.ValidationDelegate" /> <bean name= "delegate" class= "org.apache.tapestry.valid.ValidationDelegate" />        type= "Form" > <component id= "buyFruitForm" type= "Form">            value= "beans.delegate" /> <binding name= "delegate" value= "beans.delegate" />            value= " true " /> <binding name= "clientValidationEnabled" value= "true" />       </ component>        type= "Delegator" > <component id= "error" type= "Delegator">            value= "beans.delegate.firstError" /> <binding name= "delegate" value= "beans.delegate.firstError" />       </ component>        type= "TextField" > <component id= "fruitBuyMount" type= "TextField">            value= "buyMount" /> <binding name= "value" value= "buyMount" />            value= "translator:number" /> <binding name= "translator" value= "translator:number" />            value= "bean:fruitMountValidator" /> <binding name= "validators" value= "bean:fruitMountValidator" />            value= "literal:" /> <binding name= "displayName" value= "literal:" />       </ component>        type= "Submit" > <component id= "buyFruitSubmit" type= "Submit">            value= "listener:buyFruitSubmit" /> <binding name= "listener" value= "listener:buyFruitSubmit" />       </ component>        type= "Submit" > <component id= "backShopSubmit" type= "Submit">            value= "listener:backShopSubmit" /> <binding name= "listener" value= "listener:backShopSubmit" />       </ component>   </ page-specification> 

Tinkering BuyFruit.html:

  <html>   > <body jwcid= "@Body">   ><span jwcid= "error" ></span></font></p> <p> <font color= "red"> <span jwcid= "error"> error message </ span> </ font> </ p>   > <form jwcid= "buyFruitForm">    border= "1" > <table width= "242" border= "1">     > <tr align= "center">       ></td> <td width= "121"> fruit name </ td>       ><span jwcid= "fruitName" ></span></td> <td width= "105"> <span jwcid= "fruitName"> name </ span> </ td>     </ tr>     > <tr align= "center">       <td> Price </ td>       >1.00</span></td> <td> <span jwcid= "fruitPrice"> 1.00 </ span> element </ td>     </ tr>     > <tr align= "center">       <td> stock </ td>       >20</span></td> <td> <span jwcid= "fruitMount"> 20 </ span> jin </ td>     </ tr>     > <tr align= "center">       the number of <td> purchase </ td>        jwcid= "fruitBuyMount"  size= "3"  length= "3" /></td> <td> <input type= "text" jwcid= "fruitBuyMount" size= "3" length= "3" /> jin </ td>     </ tr>     > <tr align= "center">        jwcid= "backShopSubmit"  value= "" /></td> <td> <input type= "submit" jwcid= "backShopSubmit" value= "" /> </ td>        jwcid= "buyFruitSubmit"  value= "" /></td> <td> <input type= "submit" jwcid= "buyFruitSubmit" value= "" /> </ td>     </ tr>   </ table>   </ form>   </ body>   </ html> 

BuyFruit.java of tinkering buyFruitSubmit () method to monitor:

           @SuppressWarnings( "deprecation" ) / / The purchase of fruits @ SuppressWarnings ( "deprecation")           String  buyFruitSubmit() { public String buyFruitSubmit () (                   .getBeans().getBean( "delegate" ); ValidationDelegate delegate = (ValidationDelegate) this. GetBeans (). GetBean ( "delegate");                   (delegate.getHasErrors()) { if (delegate.getHasErrors ()) (                           .getPage().getPageName(); return this. getPage (). getPageName ();                   )                    FruitCart(); FruitCart fc = new FruitCart ();                   .getFruitId()); Fruit f = Products.findFruitById (this. GetFruitId ());                   fc.setBuyFruit (f);                   .getBuyMount()); fc.setBuyMount (this. getBuyMount ());                   .getBuyMount()); fc.setPayMoney (f.getPrice () * this. getBuyMount ());                   .getVisit(); MyVisit visit = (MyVisit) this. GetVisit ();                   List <FruitCart> list = visit.getFruitCartList ();                   (list == null ) { if (list == null) (                            ArrayList<FruitCart>(); list = new ArrayList <FruitCart> ();                   )                   list.add (fc);                   visit.setFruitCartList (list);                   "Cart" ; return "Cart";           ) 

   class= "com.tapestry4.FruitMountValidator" > <bean name= "fruitMountValidator" class= "com.tapestry4.FruitMountValidator">            value= "ognl:fruitId" /> <set name= "fruitId" value= "ognl:fruitId" />       </ bean> 

The

   value= "ognl:fruitId" /> <set name= "fruitId" value= "ognl:fruitId" /> 

Will be the value of imported fruitId category FruitMountValidator. Therefore, we can validate the FruitMountValidator category for well-tested methods which, if the failure of well-tested, can be thrown out ValidatorException abnormal. However, abnormal ValidatorException out does not mean that the end of efficacy, Submit components will continue to monitor the corresponding trigger its way to the original so we buyFruitSubmit () method is modified:

  .getBeans().getBean( "delegate" ); ValidationDelegate delegate = (ValidationDelegate) this. GetBeans (). GetBean ( "delegate");   (delegate.getHasErrors()) { if (delegate.getHasErrors ()) ( 	  .getPage().getPageName(); return this. getPage (). getPageName ();   ) 

When the failure of well-tested, the Jump to the current page. And components:

   type= "Delegator" > <component id= "error" type= "Delegator">            value= "beans.delegate.firstError" /> <binding name= "delegate" value= "beans.delegate.firstError" />       </ component> 

Error message will print to the page.

Here, perhaps you will find Delegator component Validator class and mode of operation is very surprising. We do a preliminary understanding of: Delegator component Validator can be used as containers, display an error message (server-side well-tested). Agent (delegate) to have a hasErrors attribute, default to false, but when the validation agent found that there is an error page when the property is set to true. Form submitted monitoring methods at a time when the trigger is always asked about the attributes hasErrors agents. If the property is false, then the representative of input validation for security and to the next step. True if true, display an error message. In this example above, the certification agent to return a string: "(" to buy greater than the number of "+ fruit.getName () +" of the inventory ( "+ fruit.getMount () +"), please re-enter! " . In fact, these error messages can be more than just a string, and can be any object, or even HTML to show all types, not just images, javascript pop-up windows, links, formating ----- any HTML. for custom applications to provide custom validator's "wrong target." agents in order to facilitate authentication, contains a firstError attributes, as a performance target, when the first error occurred when the field was passed to the Delegator, Delegator decision error information display.

OK, now, the whole shopping cart, we basically have been completed I bet, you must be confused now, huh, huh, indeed, a small shopping car example, we can fully expect it to introduce the framework of the Ministry of Tapestry technology? Therefore, the revolution is still a long road, with an initial impression, we still come to more in-depth look at the Tapestry application.


tapestry & hivemind Articles


Can't Find What You're Looking For?


Rating: Not yet rated

Comments

No comments posted.