Orchard module development full contact 4: in-depth transformation front-end

Source: Internet
Author: User

Here, we need to do some things, which means in-depth transformation of the front-end:

1: add the product to the shopping cart button and click it to implement the function;

2: Goods sorting;

3: preview the shopping cart and add the settlement button;

4: an explicit shopping cart contains * Item widgets;

 

1. Add to shopping cart button

ModifyViews/parts/product. cshtml:

@{
VaR price = (decimal) model. price;
VaR SKU = (string) model. SKU;
}
<Article>
Price: @ price <br/>
SKU: @ SKU
<Footer>
<Button> Add to shoppingcart </button>
</Footer>
</Article>

Now, this button is available on the product list:

This button is also available on the product details page.

1.1 questions

The problem arises. We found that this button is in the product introduction. If we want to put it below, what should we do?

1.2 modify the display method.

Protected override driverresult display (productpart part, string displaytype, dynamic shapehelper)
{
// Return contentshape ("parts_product", () => shapehelper. parts_product (
// Price: part. unitprice,
// SKU: part. SKU
//));
Return combined (

// Shape 1: parts_product
Contentshape ("parts_product", () => shapehelper. parts_product (
Price: part. unitprice,
SKU: part. SKU
)),

// Shape 2: parts_product_addbutton
Contentshape ("parts_product_addbutton", () => shapehelper. parts_product_addbutton ())
);
}

In the modified method, we create a new shape called parts_product_addbutton. At the same time, we use the combined method to return driverresult, But it combines two shapes.

At this time, we know that we need to createViews/parts/product. addbutton. cshtmlFile:

<Button> @ T ("add to shoppingcart") </button>

Of course, we have to restore the code in the original product. cshtml.

Then, modify placement.info:

<Placement>
<Place parts_product_edit = "content: 1"/>
<Place parts_product = "content: 0"/>
<Place parts_product_addbutton = "content: After"/>
</Placement>

Then, we can see the following differences:

 

Ii. Add to shopping cart

2.1 prerequisites

First, we create the folder controllers, and then the controller:

Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;
Using system. Threading. tasks;
Using system. Web. MVC;

Namespace tminji. Shop. Controllers
{
Public class shoppingcartcontroller: Controller
{

[Httppost]
Public actionresult add (int id)
{
Return redirecttoaction ("Index ");
}
}

}

Then, modifyViews/parts/product. addbutton. cshtml:,

@ Using (html. beginform ("add", "shoppingcart", new {id =-1 }))
{
<Button type = "Submit"> @ T ("add to shoppingcart") </button>
}

Turn it into a form and point to the add method.

Note that the ID passed here is-1, so we still need to do one thing, that is, pass the real product ID to add the product.

Therefore, we should first pass the ID to the shape and modify it. Our display method is as follows:

Protected override driverresult display (productpart part, string displaytype, dynamic shapehelper)
{
// Return contentshape ("parts_product", () => shapehelper. parts_product (
// Price: part. unitprice,
// SKU: part. SKU
//));
Return combined (

// Shape 1: parts_product
Contentshape ("parts_product", () => shapehelper. parts_product (
Price: part. unitprice,
SKU: part. SKU
)),

// Shape 2: parts_product_addbutton
Contentshape ("parts_product_addbutton", () => shapehelper. parts_product_addbutton (
Productid: part. ID ))
);
}

Then, the front-endViews/parts/product. addbutton. cshtmlAs follows:

@{
VaR productid = (INT) model. productid;
}
@ Using (html. beginform ("add", "shoppingcart", new {id = productid }))
{
<Button type = "Submit"> @ T ("add to shoppingcart") </button>
}

Now we can pass the value to the Controller. Now, we need to implement the business logic section.

 

2.2 orchard service of business logic

In the models directory, add the shoppingcartitem object class:

[Serializable]
Public sealed class shoppingcartitem
{
Public int productid {Get; private set ;}

Private int _ quantity;
Public int quantity
{
Get {return _ quantity ;}
Set
{
If (value <0)
Throw new indexoutofrangeexception ();

_ Quantity = value;
}
}

Public shoppingcartitem ()
{
}

Public shoppingcartitem (INT productid, int quantity = 1)
{
Productid = productid;
Quantity = quantity;
}
}

CreateServicesFolder, and then create the ishoppingcart interface,

Public interface ishoppingcart: idependency
{
Ienumerable <shoppingcartitem> items {Get ;}
Void add (INT productid, int quantity = 1 );
Void remove (INT productid );
Productpart getproduct (INT productid );
Decimal subtotal ();
Decimal VAT ();
Decimal total ();
Int itemcount ();
Void updateitems ();
}

Then, its implementation class:

Using orchard;
Using orchard. contentmanagement;
Using system;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;
Using system. Threading. tasks;
Using system. Web;
Using tminji. Shop. models;

Namespace tminji. Shop. Services
{
Public class shoppingcart: ishoppingcart
{
Private readonly iworkcontextaccessor _ workcontextaccessor;
Private readonly icontentmanager _ contentmanager;
Public ienumerable <shoppingcartitem> items {get {return itemsinternal. asreadonly ();}}

Private httpcontextbase httpcontext
{
Get {return _ workcontextaccessor. getcontext (). httpcontext ;}
}

Private list <shoppingcartitem> itemsinternal
{
Get
{
VaR items = (list <shoppingcartitem>) httpcontext. session ["shoppingcart"];

If (items = NULL)
{
Items = new list <shoppingcartitem> ();
Httpcontext. session ["shoppingcart"] = items;
}

Return items;
}
}

Public shoppingcart (iworkcontextaccessor workcontextaccessor, icontentmanager contentmanager)
{
_ Workcontextaccessor = workcontextaccessor;
_ Contentmanager = contentmanager;
}

Public void add (INT productid, int quantity = 1)
{
VaR item = items. singleordefault (x => X. productid = productid );

If (item = NULL)
{
Item = new shoppingcartitem (productid, quantity );
Itemsinternal. Add (item );
}
Else
{
Item. Quantity + = quantity;
}
}

Public void remove (INT productid)
{
VaR item = items. singleordefault (x => X. productid = productid );

If (item = NULL)
Return;

Itemsinternal. Remove (item );
}

Public productpart getproduct (INT productid)
{
Return _ contentmanager. Get <productpart> (productid );
}

Public void updateitems ()
{
Itemsinternal. removeall (x => X. Quantity = 0 );
}

Public decimal subtotal ()
{
Return items. Select (x => getproduct (X. productid). unitprice * X. Quantity). sum ();
}

Public decimal VAT ()
{
Return subtotal () *. 19 m;
}

Public decimal total ()
{
Return subtotal () + VAT ();
}

Public int itemcount ()
{
Return items. sum (x => X. Quantity );
}

Private void clear ()
{
Itemsinternal. Clear ();
Updateitems ();
}
}
}

The above code will not be explained one by one. I believe you can understand it. Then, modify the Controller accordingly:

Using orchard;
Using system;
Using orchard. MVC;
Using system. Collections. Generic;
Using system. LINQ;
Using system. text;
Using system. Threading. tasks;
Using system. Web. MVC;
Using tminji. Shop. Services;

Namespace tminji. Shop. Controllers
{
Public class shoppingcartcontroller: Controller
{

Private readonly ishoppingcart _ shoppingcart;
Private readonly iorchardservices _ services;

Public shoppingcartcontroller (ishoppingcart shoppingcart, iorchardservices Services)
{
_ Shoppingcart = shoppingcart;
_ Services = services;
}

[Httppost]
Public actionresult add (int id)
{

// Add the specified Content ID to the shopping cart with a quantity of 1.
_ Shoppingcart. Add (ID, 1 );

// Redirect the user to the index action (yet to be created)
Return redirecttoaction ("Index ");
}

Public actionresult index ()
{

// Create a new shape using the "new" Property of iorchardservices.
VaR shape = _ Services. New. shoppingcart ();

// Return a shaperesult
Return new shaperesult (this, shape );
}

}
}

In the controller, we see three changes:

1: The constructor accepts two objects, which are injected, which will be completed by orchard;

2: The add method can add items to the shopping cart;

3: added an index method. We can see that in this method,We created another shape named shoppingcart. Note: It is different from creating a shape on the background.(Remember, in the display method), this shape indicates that the cshtml file isViews/shoppingcart. cshtml:

Todo: display our shopping cart contents!

If we run the code at this time, we will find that after clicking Add to the shopping cart, it will become 404. This is because we didn't add an area to the route. What is it? It is the module name. orchard routes the area to the Controller in the module. Therefore, we should modifyViews/parts/product. addbutton. cshtml:

@{
VaR productid = (INT) model. productid;
}
@ Using (html. beginform ("add", "shoppingcart", new {id = productid, Area = "tminji. Shop "}))
{
<Button type = "Submit"> @ T ("add to shoppingcart") </button>
}

Now, continue to run the code. Now, we get the error:

The required anti-forgery form field "_ requestverificationtoken" is not present.

Of course, we are familiar with MVC and know how to modify this error. Modify it:

@{
VaR productid = (INT) model. productid;
}
@ Using (html. beginformantiforgerypost (URL. Action ("add", "shoppingcart", new {id = productid, Area = "tminji. Shop "})))
{
<Button type = "Submit"> @ T ("add to shoppingcart") </button>
}

Run again:

We can see that this page does not contain the current theme master page. Return to the Controller and add themedattries (of course, we have to using orchard. themes;), as shown below:

[Themed]
Public actionresult index ()
{
// Create a new shape using the "new" Property of iorchardservices.
VaR shape = _ Services. New. shoppingcart ();

// Return a shaperesult
Return new shaperesult (this, shape );
}

At this time, the system runs again and achieves the following ideal results:

 

 

Summary

1: the front-end display is mainly implemented through the MVC controller, while the back-end bypasses the Controller;

2: The service mechanism is used for business logic, rather than the class and logic we write blindly (of course, we can also), but the service mechanism looks more orchard;

3: The method for creating shape in the front and back is different.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.