Persist the values of the fields in the CartOrder instance

NEW TO SITEFINITY?

To persist the get the values of the custom fields, you have to use the EcommerceCheckoutPageChanging event. It occurs every time the user navigates between the steps of the Checkout widget. In the handler for this event you can get instances of the UI controls for the fields and their values. You subscribe to this event in the Global.asax file. For more information about how to subscribe to this event and its event arguments, see the For development: IEcommerceCheckoutPageChanging event article.

The code for getting and persisting the values of the custom fields, is going to be placed in the handler for the EcommerceCheckoutPageChanging event.To get the values of the fields and persist them in the CartOrder instance, perform the following:

  1. Check if the shopping cart is empty.
    The EcommerceCheckoutPageChanging event could be raised after the shopping cart was destroyed. Because of this, you have to make sure that the shopping cart exists. To do this simply check whether the ShoppingCartId value of the arguments is different form null or Guid.Empty.
  2. Check the index of the current step.
    To check the index, use the CurrentStepIndex value of the arguments. In this example you need the steps “Shipping Information” and “Preview”. Their indexes are respectively 0 and 3.

    NOTE:  Ensure to look for the respective field control only in the corresponding checkout step. It is important to perform this check because of the way the checkout pages are constructed. In some cases you may be able to find the control in a step even when it is actually in another step. In this case you may end up retrieving the wrong value from the control and thus persisting wrong data. Therefore, it is safest to verify the step whenever you save data from a control.

  3. Persist the value of the newsletter subscription field.
    This is done in the Sipping Information step. To persist the value of the field, you must perform the following:
    1. Get an instance of UI control for the field.
      To get an instance of the UI control for the field, you must use the GenericContainer instance stored in the Container property of the event arguments. Call its GetControl method and pass the id of the control. As generic argument pass the class of the UI control, in this case System.Web.UI.WebControls.CheckBox.

      NOTE: The second argument accepted by the GetControl method is of type boolean and indicates whether the control should be treated as required or not. If the control is required and cannot be found, the method will throw an exception. If the control is not required and it does not exist, the method will return null.

    2. Get the value of the field.
      Get the value stored in the UI control. In this case you need the value of the Checked property of the CheckBox control.
    3. Get the orders manager.
      Get an instance of the OrdersManager object.
    4. Get the current cart order.
      To get an instance of the current cart order, call the GetCartOrder method of the orders manager. The ID of the current cart order is stored in the CartOrderId property of the event arguments.
    5. Get the properties for the cart order instance.
      To get all properties and their values for the cart order instance, call the GetProperties static method of the TypeDescriptor class. As an argument pass the instance of the cart order.
    6. Get the Newsletter field.
      From all the properties, get the one you need. In this case it is the one named Newsletter. To get it, use its name as a key. When getting the field, use the same name that you used during its creation.

      NOTE: Information about creating this property can be found in the For developers: Create the custom fields for the CartOrder and Order classes article.

    7. Cast the object to MetafieldPropertyDescriptor.
      Cast the instance of the PropertyDescriptor class that represents the field, to MetafieldPropertyDescriptor.
    8. Set the value of the Newsletter field.
      To set the value of the field, call the SetValue method of the MetafieldPropertyDescriptor instance. As arguments pass the instance of the cart order and the new value.
    9. Save the changes.
      Save the changes to the orders manager.
  4. Persist the value of the gift message field.
    This is done in the Preview step. Repeat the same sub-steps as in step 3, but for the gift message field.

Use the following code sample:

using System;
using System.ComponentModel;
using System.Web.UI.WebControls;
using Telerik.Sitefinity;
using Telerik.Sitefinity.Abstractions;
using Telerik.Sitefinity.Data.Metadata;
using Telerik.Sitefinity.Ecommerce.Orders.Model;
using Telerik.Sitefinity.Modules.Ecommerce.Events;
using Telerik.Sitefinity.Modules.Ecommerce.Orders;
using Telerik.Sitefinity.Services;
namespace SitefinityWebApp
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Bootstrapper.Bootstrapped += Bootstrapper_Bootstrapped;
}
private void Bootstrapper_Bootstrapped(object sender, EventArgs e)
{
EventHub.Subscribe<IEcommerceCheckoutPageChangingEvent>(OnEcommerceCheckoutPageChanging);
this.CreateCustomOrderFields();
}
public void OnEcommerceCheckoutPageChanging(IEcommerceCheckoutPageChangingEvent evt)
{
// This event could be raised after the shopping cart was destroyed so make sure you return when the ShoppingCartId is empty or null.
if (evt.ShoppingCartId == Guid.Empty || evt.ShoppingCartId == null)
{
return;
}
// Check that you are in the Shipping Information step.
if (evt.CurrentStepIndex == 0)
{
SaveCustomBillingAndShippingFields(evt);
}
// Shipping (current step index = 1)
// Payment Information (current step index = 2)
// Check that you are in the Preview step (current step index = 3)
if (evt.CurrentStepIndex == 3)
{
SaveCustomPreviewFields(evt);
}
}
private void CreateCustomOrderFields()
{
// You need an instance of the MetadataMananger in order to add the new meta field to the tables.
MetadataManager metaManager = MetadataManager.GetManager();
// Check if the Order table has already been modified to contain meta fields
if (metaManager.GetMetaType(typeof(Order)) == null)
{
// Create the metatype for the order class.
metaManager.CreateMetaType(typeof(Order));
// Save the changes
metaManager.SaveChanges();
}
// Add a new meta field to the Order table
App.WorkWith()
.DynamicData()
.Type(typeof(Order))
.Field()
.TryCreateNew("NewsLetter", typeof(string))
.SaveChanges();
// Add a new meta field to the Order table
App.WorkWith()
.DynamicData()
.Type(typeof(Order))
.Field()
.TryCreateNew("GiftMessage", typeof(string))
.SaveChanges();
// Check if the CartOrder table has already been modified to contain meta fields
if (metaManager.GetMetaType(typeof(CartOrder)) == null)
{
// Create the metatype for the CartOrder class.
metaManager.CreateMetaType(typeof(CartOrder));
//Save the changes.
metaManager.SaveChanges();
}
// Add a new meta field to the CartOrder table
App.WorkWith()
.DynamicData()
.Type(typeof(CartOrder))
.Field()
.TryCreateNew("NewsLetter", typeof(string))
.SaveChanges();
// Add a new meta field to the CartOrder table
App.WorkWith()
.DynamicData()
.Type(typeof(CartOrder))
.Field()
.TryCreateNew("GiftMessage", typeof(string))
.SaveChanges();
}
private void SaveCustomPreviewFields(IEcommerceCheckoutPageChangingEvent evt)
{
// Find the custom control on the current page using the evt.Container object's GetControl method.
TextBox giftMessageTextBox = evt.Container.GetControl<TextBox>("giftMessage", false);
// Check to see that you have actually found the textbox control that you were looking for on the page
if (giftMessageTextBox != null)
{
// Get the value of the textbox.
string giftMessage = giftMessageTextBox.Text;
OrdersManager ordersManager = OrdersManager.GetManager();
// Get a copy of the shopping cart order based on the evt.ShoppingCartId.
CartOrder cartOrder = ordersManager.GetCartOrder(evt.ShoppingCartId);
if (cartOrder != null)
{
// Get all properties of the cartOrder object.
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(cartOrder);
// Get the meta property with the name used when creating the field in the CreateCustomOrderFields() method.
PropertyDescriptor property = properties["GiftMessage"];
MetafieldPropertyDescriptor metaProperty = property as MetafieldPropertyDescriptor;
// Safety check to make sure you have found the appropriately named property in the cartOrder object.
if (metaProperty != null)
{
// Set the meta property of the cartOrder object using the value from the checkbox control.
metaProperty.SetValue(cartOrder, giftMessage);
// Save the new value to the database.
ordersManager.SaveChanges();
}
}
}
}
private void SaveCustomBillingAndShippingFields(IEcommerceCheckoutPageChangingEvent evt)
{
// Find the custom control on the current page using the container object's GetControl method.
CheckBox newsletterCheckbox = evt.Container.GetControl<CheckBox>("newsletter", false);
// Check to see that you have actually found the checkbox control that you were looking for on the page.
if (newsletterCheckbox != null)
{
// Get the value of the checkbox control.
bool newsLetter = newsletterCheckbox.Checked;
OrdersManager ordersManager = OrdersManager.GetManager();
// Get an instance of the shopping cart order based on the evt.ShoppingCartId.
CartOrder cartOrder = ordersManager.GetCartOrder(evt.ShoppingCartId);
if (cartOrder != null)
{
// Get all properties of the cartOrder object.
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(cartOrder);
// Get the meta property with the name used when creating the field in the CreateCustomOrderFields() method.
PropertyDescriptor property = properties["NewsLetter"];
MetafieldPropertyDescriptor metaProperty = property as MetafieldPropertyDescriptor;
// Safety check to make sure you have found the appropriately named property in the cartOrder object.
if (metaProperty != null)
{
// Set the meta property of the cartOrder object using the value from the checkbox control.
metaProperty.SetValue(cartOrder, newsLetter.ToString());
// Save the new value to the database.
ordersManager.SaveChanges();
}
}
}
}
}
}

NOTE: The code snippet above also contains the code form the previous article – For developers: Create the custom fields for the CartOrder and Order classes.

Want to learn more?

Increase your Sitefinity skills by signing up for our free trainings. Get Sitefinity-certified at Progress Education Community to boost your credentials.

Get started with Integration Hub | Sitefinity Cloud | Sitefinity SaaS

This free lesson teaches administrators, marketers, and other business professionals how to use the Integration hub service to create automated workflows between Sitefinity and other business systems.

Web Security for Sitefinity Administrators

This free lesson teaches administrators the basics about protecting yor Sitefinity instance and its sites from external threats. Configure HTTPS, SSL, allow lists for trusted sites, and cookie security, among others.

Foundations of Sitefinity ASP.NET Core Development

The free on-demand video course teaches developers how to use Sitefinity .NET Core and leverage its decoupled architecture and new way of coding against the platform.

Was this article helpful?