Possible to force acceptance of Terms and Conditions before adding a product type to cart?
Hi,
I have a product type that requires the acceptance for terms and conditions before it is added to the cart. I can modify the single item template and add a check box control and javascript validation but how would I go about showing the control for only one specific product type?
Thanks--Steve
Hey Steve,
There are 2 ways to go about this - the client proof and the developer proof :)
I've just glanced at the product properties and it doesn't seem possible to simply display/extract the product type with JavaScript.
You could always go with the code behind and mapping an external option but if you want to keep it simple perhaps it's easier when creating a custom product-type to add an dynamic Boolean field "Should accept terms" and have the JavaScript check the value of that field.
J.
Hi Jochem,
Thanks for the suggestions. I tried mapping the the single item template to an external custom control using the info in Josh's blog. I originally tried option 1 but SF kept restoring the TemplateKey Guid and rather than fight it went with the less friendly option 2. From codebehind I can get the product type and hide/unhide the "I accept the terms" checkbox. So far so good.
From here I have 2 options in terms of forcing the user to accept the terms before they can add an item to the cart:
A. Hook into the ValidationGroup (addToCart) using a CustomValidator and handle the OnServerValidate event and set the args.IsValid property to true or false depending on the checkbox checked state.
B. Set the Add to cart button's enabled state based on the checked state of the checkbox.
I'd prefer to use option A as option B is far less user friendly in my opinion.
So, far I have been unable to catch any of the validation using any validator controls. I tried adding a dummy textbox and a RequiredFieldValidator to the template control and setting its ControlToValidate property to the id of the dummy textbox and setting its ValidationGroup to match that of the "addToCartButton" and the "quantity" controls but SF seems to ignore any validator controls other than those that are part of the "AddToCartWidget".
Thinking I might get better control over validation, I created a custom control that inherits from "AddToCartWidget". Unfortunately, I'm now running into the following error:
"Microsoft JScript runtime error: Object doesn't support property or method 'fancybox'"
I have tried including the Telerik.Sitefinity.Resources.Themes.Basic.Styles.fancybox.css and JQueryFancyBox JavaScriptLibrary resources a number of different ways all to no avail.
After a day of trying to get this to work I've made little measureable progress--pretty frustrating for something that should be pretty easy to do.
--Steve
Hey Steve,
Sorry to hear you lost a full day, unfortunately I know how it feels...
Hi Jochem,
Sorry for the late reply. I spent some more time on this today and decided to scrap the custom control. I ended creating a new template based on Product Detail Template. I took your advice and was able to get client validation working properly without having to resort to disabling the Add to Cart button. Overall it works well but there are a couple of downsides worth noting:
As you noted, there doesn't appear to be a way to determine the product type using client side scripting. This is a pain because my product types have Custom Fields. Normally, I'd let SF deal with displaying the Custom Field values on its own but there's a bug in the current version that results in the custom field values being displayed without their associated labels. So to get that working I need to use Eval statements to grab the custom fiels data. Ugly things happen when you try to get custom fields that don't exist in a particular product type. So in the end I wound up using the "Different template for each product type..." option.
Here's the code just in case someone else needs to do something similar:
<%@ Control Language=
"C#"
%>
<%@ Import Namespace=
"System.ComponentModel"
%>
<%@ Import Namespace=
"Telerik.Sitefinity.Ecommerce.Catalog.Model"
%>
<%@ Register Assembly=
"Telerik.Sitefinity"
Namespace=
"Telerik.Sitefinity.Modules.Ecommerce.Orders.Web.UI"
TagPrefix=
"sfOrders"
%>
<%@ Register Assembly=
"Telerik.Sitefinity"
Namespace=
"Telerik.Sitefinity.Modules.Ecommerce.Catalog.Web.UI.Fields"
TagPrefix=
"sfCatalog"
%>
<%@ Register TagPrefix=
"sf"
Namespace=
"Telerik.Sitefinity.Web.UI.ContentUI"
Assembly=
"Telerik.Sitefinity"
%>
<%@ Register TagPrefix=
"sf"
Namespace=
"Telerik.Sitefinity.Web.UI"
Assembly=
"Telerik.Sitefinity"
%>
<%@ Register TagPrefix=
"sf"
Namespace=
"Telerik.Sitefinity.Web.UI.PublicControls.BrowseAndEdit"
Assembly=
"Telerik.Sitefinity"
%>
<%@ Register TagPrefix=
"telerik"
Namespace=
"Telerik.Web.UI"
Assembly=
"Telerik.Web.UI"
%>
<%@ Register TagPrefix=
"sf"
Namespace=
"Telerik.Sitefinity.Modules.Ecommerce.Catalog.Web.UI"
Assembly=
"Telerik.Sitefinity"
%>
<%@ Register Assembly=
"SitefinityWebApp"
Namespace=
"SitefinityWebApp.CustomControls"
TagPrefix=
"nlg"
%>
<sf:resourcelinks id=
"resourcesLinks"
runat=
"server"
>
<sf:ResourceFile JavaScriptLibrary=
"JQueryFancyBox"
/>
</sf:resourcelinks>
<sf:resourcelinks id=
"resourcesLinks2"
runat=
"server"
useembeddedthemes=
"true"
theme=
"Default"
>
<sf:ResourceFile Name=
"Telerik.Sitefinity.Resources.Themes.Basic.Styles.fancybox.css"
Static=
"true"
/>
</sf:resourcelinks>
<div id=
"widgetStatus"
runat=
"server"
visible=
"false"
class
=
"sfErrorSummary sfTopMsg"
>
<asp:Label ID=
"widgetStatusMessage"
runat=
"server"
/>
</div>
<sf:conditionaltemplatecontainer id=
"conditionalTemplate"
runat=
"server"
>
<Templates>
<sf:ConditionalTemplate Left=
"IsActive"
Operator=
"Equal"
Right=
"false"
runat=
"server"
>
<asp:Literal ID=
"Literal1"
runat=
"server"
Text=
"<%$Resources:OrdersResources, ProductNotAvailable %>"
/>
</sf:ConditionalTemplate>
<sf:ConditionalTemplate Left=
"IsActive"
Operator=
"Equal"
Right=
"true"
runat=
"server"
>
<telerik:RadListView ID=
"SingleItemContainer"
ItemPlaceholderID=
"ItemContainer"
AllowPaging=
"False"
runat=
"server"
EnableEmbeddedSkins=
"false"
EnableEmbeddedBaseStylesheet=
"false"
>
<LayoutTemplate>
<div
class
=
"sfproductDetails sfClearfix"
>
<asp:PlaceHolder ID=
"ItemContainer"
runat=
"server"
/>
</div>
</LayoutTemplate>
<ItemTemplate>
<div
class
=
"sfproductImgsWrp"
>
<div
class
=
"sfproductMainImgWrp"
>
<%-- This
is
so that we can have the rel=
"fancybox"
without resorting to an Attributes.Add() call --%>
<a href=
'<%# Eval("PrimaryImageUrl") %>'
rel=
"fancybox"
>
<img src=
'<%# Eval("Thumbnail.Url") %>'
alt=
'<%# Eval("ThumbnailAlternativeText") %>'
/>
</a>
</div>
<div
class
=
"sfproductImgsListWrp"
>
<ul
class
=
"sfproductImgsList"
>
<asp:Repeater ID=
"Repeater1"
runat=
"server"
DataSource=
'<%# new BindingList<ProductImage>(((IEnumerable<ProductImage>)Eval("Images")).Skip(1).ToList()) %>'
>
<ItemTemplate>
<li
class
=
"sfproductImgWrp"
>
<a href=
'<%# DataBinder.Eval(Container.DataItem, "Url") %>'
rel=
"fancybox"
class
=
"sfproductImgLnk"
>
<asp:Image ID=
"Image1"
CssClass=
"sfproductImg"
runat=
"server"
ImageUrl=
'<%# DataBinder.Eval(Container.DataItem, "ThumbnailUrl") %>'
Width=
'<%# (int)DataBinder.Eval(Container.DataItem, "ThumbnailWidth") %>'
Height=
'<%# (int)DataBinder.Eval(Container.DataItem, "ThumbnailHeight") %>'
/>
</a>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
</div>
</div>
<div
class
=
"sfproductInfoWrp"
>
<div
class
=
"sfproductTitle"
>
<%# Eval(
"Title"
) %>
</div>
<div
class
=
"sfproductPrice"
>
<sfCatalog:DisplayPriceField ID=
"DisplayPriceField1"
runat=
"server"
ObjectType=
"Product"
ObjectId=
'<%# Eval("Id") %>'
/>
</div>
<div
class
=
"sfproductDescription"
>
<%# Eval(
"Description"
) %>
</div>
<!-- Begin Custom Fields from Video-On-Demand Product Type. Workaround
for
SF showing the Custom Field value and skipping the label -->
<div
class
=
"nlgProductsCustomItemWrp"
>
<div
class
=
"nlgProductsCustomItemWrp runningTime"
>
Running Time: <sitefinity:TextField ID=
"TextField1"
runat=
"server"
DisplayMode=
"Read"
Value=
'<%# Eval("Length")%>'
CssClass=
"nlgProductsCustomItem"
/>
</div>
<div
class
=
"nlgProductsCustomItemWrp ceuCredits"
>
CEUs: <sitefinity:TextField ID=
"TextField2"
runat=
"server"
DisplayMode=
"Read"
Value=
'<%# Eval("CEUs")%>'
CssClass=
"nlgProductsCustomItem"
/>
</div>
</div>
<!-- End Custom Fields from Video-On-Demand Product Type -->
<div
class
=
"sfproductOptions"
>
<sf:ProductOptionsControl id=
"productOptionsControl"
ProductItem=
'<%# Page.GetDataItem() %>'
runat=
"server"
/>
</div>
<div
class
=
"nlgTermsAndConditions"
>
<asp:Label ID=
"TermsOfUseCaption"
runat=
"server"
Text=
"Label"
CssClass=
"nlgTermsOfUseCaption"
>
On-line Content Terms of Use:
</asp:Label>
<asp:Label ID=
"TermsOfUse"
runat=
"server"
Text=
"Label"
CssClass=
"nlgTermsOfUse"
>
All content and information
is
provided
for
informational purposes only and a professional should be consulted prior to relying on subject matter of
this
site.
</asp:Label>
<asp:CheckBox ID=
"TermsChkBox"
runat=
"server"
ClientIDMode=
"Static"
CssClass=
"nlgTermsChkBox"
Text=
" I Agree"
TextAlign=
"Right"
/>
<asp:customvalidator id=
"TermsValidator"
runat=
"server"
clientvalidationfunction=
"ValidateTermsOfUse"
enableclientscript=
"True"
ValidationGroup=
"addToCart"
Display=
"Dynamic"
>
<span
class
=
"sfError"
>
<asp:Literal runat=
"server"
ID=
"TermsValidationMsg"
Text=
"You must accept the On-line Content Terms of Use before this item can be added to your cart."
/>
</span>
</asp:customvalidator>
</div>
<sfOrders:AddToCartWidget ID=
"addToCartWidget"
ProductId=
'<%# Eval("Id") %>'
runat=
"server"
/>
</div>
</ItemTemplate>
</telerik:RadListView>
</sf:ConditionalTemplate>
</Templates>
</sf:conditionaltemplatecontainer>
<script language=
"javascript"
type=
"text/javascript"
>
function ValidateTermsOfUse( sender, args )
var chkBox = document.getElementById(
'TermsChkBox'
);
if
( !chkBox.
checked
)
args.IsValid =
false
;
else
args.IsValid =
true
;
</script>
@Steve,
Hi Jochem,
Nice find--that did indead fix the problem. Silly little problem to have made it through QC but those are the ones that alway seem to be the easiest to miss.
Thanks--Steve
PS: Love the book title