1<div class="container">
2 <div class="store-order-container">
3
4 <form method="post" action="{routePath('cart-order-addtocart')}" id="frmAddToCart">
5 <input type="hidden" name="pid" value="{$product->id}">
6 <input type="hidden" name="domain_type" value="" id="inputDomainType">
7
8 <div class="row">
9 <div class="col-sm-7">
10 <h2>{$product->name}</h2>
11
12 <p>{$product->description}</p>
13 </div>
14 <div class="col-sm-5">
15
16 <div class="payment-term">
17 <h4>{lang key='store.choosePaymentTerm'}</h4>
18 <select name="billingcycle" class="form-control">
19 {foreach $product->pricing()->allAvailableCycles() as $pricing}
20 <option value="{$pricing->cycle()}"{if $requestedCycle == $pricing->cycle()} selected{/if}>
21 {if $pricing->isRecurring()}
22 {if $pricing->isYearly()}
23 {$pricing->cycleInYears()} - {$pricing->yearlyPrice()}
24 {else}
25 {$pricing->cycleInMonths()} - {$pricing->monthlyPrice()}
26 {/if}
27 {else}
28 {$pricing->toFullString()}
29 {/if}
30 </option>
31 {/foreach}
32 </select>
33 </div>
34
35 </div>
36 </div>
37
38 <br>
39 <h4>{lang key='store.chooseDomain'}</h4>
40
41 <ul class="nav nav-tabs store-domain-tabs" role="tablist">
42 {if $requireDomain}
43 {if (count($domains) > 0 && $loggedin)}
44 <li role="presentation" class="active"><a href="#existing-domain" aria-controls="existing-domain" role="tab" data-toggle="tab">{lang key='store.chooseExistingDomain'}</a></li>
45 {/if}
46 {if $allowSubdomains}
47 <li role="presentation"><a href="#sub-domain" aria-controls="sub-domain" role="tab" data-toggle="tab">{lang key='store.subOfExisting'}</a></li>
48 {/if}
49 <li role="presentation"><a id="tabCustomDomainControl" href="#custom-domain" aria-controls="custom-domain" role="tab" data-toggle="tab">{lang key='store.domainAlreadyOwned'}</a></li>
50 {else}
51 <li role="presentation" class="active">
52 <a id="tabNoDomain" href="#no-domain" role="tab" data-toggle="tab">
53 {lang key='store.noDomain'}
54 </a>
55 </li>
56 {/if}
57 </ul>
58 <div class="tab-content store-domain-tab-content">
59 {if $requireDomain}
60 {if count($domains) > 0}
61 <div role="tabpanel" class="tab-pane active" id="existing-domain">
62 {if $loggedin}
63 <div class="row">
64 <div class="col-sm-8">
65 <select class="form-control" name="existing_domain">
66 {foreach $domains as $domain}
67 <option value="{$domain}"{if $domain == $selectedDomain} selected="selected"{/if}>
68 {$domain}
69 </option>
70 {/foreach}
71 </select>
72 </div>
73 <div class="col-sm-4">
74 <span class="domain-validation ok">
75 <i class="fas fa-check"></i>
76 {lang key='store.eligible'}
77 </span>
78 </div>
79 </div>
80 {else}
81 <a href="{routePath('cart-order-login')}">{lang key='store.login'}</a> {lang key='store.addToExistingPackage'}
82 {/if}
83 </div>
84 {/if}
85 {if $allowSubdomains}
86 <div role="tabpanel" class="tab-pane" id="sub-domain">
87 <div class="row">
88 <div class="col-sm-8">
89 <div style="display:inline-block;width:47%;">
90 <input type="text" class="form-control subdomain-input" name="sub_domain" placeholder="Your desired subdomain"></div>
91 <div style="display:inline-block;width:2%;text-align:center;">
92 .
93 </div>
94 <div style="display:inline-block;width:47%;">
95 <select class="form-control" name="existing_sld_for_subdomain" id="existing_sld_for_subdomain">
96 {foreach $domains as $domain}
97 <option value="{$domain}">{$domain}</option>
98 {/foreach}
99 </select>
100 </div>
101 </div>
102 <div class="col-sm-4">
103 <span class="domain-validation subdomain-validation"></span>
104 </div>
105 </div>
106 </div>
107 {/if}
108 <div role="tabpanel" class="tab-pane" id="custom-domain">
109 <div class="row">
110 <div class="col-sm-8">
111 <input type="text" class="form-control domain-input" placeholder="example.com" name="custom_domain" value="{$customDomain}">
112 </div>
113 <div class="col-sm-4">
114 <span class="domain-validation domain-input-validation"></span>
115 </div>
116 </div>
117 </div>
118 {else}
119 <div role="tabpanel" class="tab-pane" id="no-domain">
120 {lang key='store.noDomainRequired'}
121 </div>
122 {/if}
123 </div>
124 <div class="row">
125 <div class="col-sm-5">
126 <a href="javascript:history.go(-1)" class="btn btn-default">
127 <i class="fas fa-arrow-left"></i>
128 {lang key='back'}
129 </a>
130 </div>
131 <div class="col-sm-7 text-right">
132 <button type="submit" name="continue" value="1" class="btn btn-default">
133 {lang key='orderForm.continueShopping'}
134 </button>
135 <button type="submit" name="checkout" value="1" class="btn btn-primary">
136 {lang key='orderForm.checkout'}
137 <i class="fas fa-shopping-cart"></i>
138 </button>
139
140 </div>
141 </div>
142
143 </form>
144 </div>
145
146 {if $upsellProduct && $promotion}
147 <div class="store-promoted-product upsell-{$upsellProduct->productKey}">
148 <div class="row">
149 <div class="col-sm-3">
150 <div class="icon">
151 <img src="{$promotion->getImagePath()}">
152 </div>
153 </div>
154 <div class="col-sm-9">
155
156 <h3>{$promotion->getHeadline()}</h3>
157 <h4>{$promotion->getTagline()}</h4>
158 {if $promotion->getDescription()}
159 <p>{$promotion->getDescription()}</p>
160 {/if}
161 {if $promotion->hasFeatures()}
162 <ul class="features">
163 {foreach $promotion->getFeatures() as $highlight}
164 <li><i class="far fa-check-circle"></i> {$highlight}</li>
165 {/foreach}
166 </ul>
167 {/if}
168 <form method="post" action="{routePath('cart-order')}">
169 <input type="hidden" name="pid" value="{$upsellProduct->id}">
170 <button type="submit" class="btn btn-success">
171 {foreach $product->pricing()->allAvailableCycles() as $pricing}
172 <span class="span-upsell span-upsell-{$pricing->cycle()}">
173 {if is_null($upsellComparison->diff({$pricing->cycle()}))}
174 {$promotion->getCta()} {$upsellProduct->name} {lang key='store.fromJust'} {$upsellProduct->pricing()->best()->breakdownPrice()}
175 {else}
176 {$promotion->getCta()} {$upsellProduct->name} {lang key='store.forJust'} {$upsellComparison->diff({$pricing->cycle()})->breakdownPrice()} {lang key='more'}
177 {/if}
178 </span>
179 {/foreach}
180 </button>
181 </form>
182 </div>
183 </div>
184 </div>
185 {/if}
186</div>
187
188<script>
189jQuery(document).ready(function(){
190
191 var delay = (function(){
192 var timer = 0;
193 return function(callback, ms){
194 clearTimeout (timer);
195 timer = setTimeout(callback, ms);
196 };
197 })();
198
199 jQuery('.store-order-container .subdomain-input').keyup(function() {
200 delay(function(){
201 jQuery('.subdomain-validation').html('<i class="fas fa-spinner fa-spin"></i> Validating...').removeClass('ok');
202
203 jQuery('#frmAddToCart button[type="submit"]').prop('disabled', true);
204
205 var domainName = jQuery('.subdomain-input').val() + '.' + jQuery('#existing_sld_for_subdomain').val();
206
207 WHMCS.http.jqClient.post('{routePath('cart-order-validate')}', 'domain=' + domainName, function(data) {
208 if (data.valid) {
209 jQuery('.subdomain-validation').html('<i class="fas fa-check"></i> Valid').addClass('ok');
210 jQuery('#frmAddToCart button[type="submit"]').removeProp('disabled');
211 } else {
212 jQuery('.subdomain-validation').html('<i class="fas fa-times"></i> Invalid domain');
213 }
214 }, 'json');
215
216 }, 1000 );
217 });
218
219 var delay2 = (function(){
220 var timer = 0;
221 return function(callback, ms){
222 clearTimeout (timer);
223 timer = setTimeout(callback, ms);
224 };
225 })();
226
227 jQuery('.store-order-container .domain-input').keyup(function() {
228 delay2(function(){
229 jQuery('.domain-input-validation').html('<i class="fas fa-spinner fa-spin"></i> Validating...').removeClass('ok');
230 jQuery('#frmAddToCart button[type="submit"]').prop('disabled', true);
231 WHMCS.http.jqClient.post('{routePath('cart-order-validate')}', 'domain=' + jQuery('.domain-input').val(), function(data) {
232 if (data.valid) {
233 jQuery('.domain-input-validation').html('<i class="fas fa-check"></i> Valid').addClass('ok');
234 jQuery('#frmAddToCart button[type="submit"]').removeProp('disabled');
235 } else {
236 jQuery('.domain-input-validation').html('<i class="fas fa-times"></i> Invalid domain');
237 }
238 }, 'json');
239 }, 1000 );
240 });
241 {if $requireDomain}
242 jQuery('.store-domain-tabs a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
243 var tab = jQuery(e.target).attr('aria-controls');
244 jQuery('#inputDomainType').val(tab);
245 if (tab == 'custom-domain' || tab == 'sub-domain') {
246 var validationBlockSelector = tab == 'custom-domain' ? '.domain-input-validation' : '.subdomain-validation';
247 var validationHtml = jQuery(validationBlockSelector).html();
248
249 if (validationHtml == '<i class="fas fa-check"></i> Valid') {
250 jQuery('#frmAddToCart button[type="submit"]').removeProp('disabled');
251 } else {
252 jQuery('#frmAddToCart button[type="submit"]').prop('disabled', true);
253 }
254 } else {
255 {if $loggedin}
256 jQuery('#frmAddToCart button[type="submit"]').removeProp('disabled');
257 {else}
258 jQuery('#frmAddToCart button[type="submit"]').prop('disabled', true);
259 {/if}
260 }
261 });
262 {/if}
263
264 jQuery('.store-domain-tabs li').removeClass('active');
265 jQuery('.store-domain-tabs li:first-child a').click();
266 {if !$loggedin && $requireDomain}
267 jQuery('#frmAddToCart button[type="submit"]').prop('disabled', true);
268 {/if}
269
270 jQuery('.payment-term').find('select').change(function() {
271 var cycle = jQuery('.payment-term').find('option:selected').val();
272 updateUpsellDetailsOnBillingCycleChange(cycle);
273 });
274 updateUpsellDetailsOnBillingCycleChange(jQuery('.payment-term').find('option:selected').val());
275
276 {if $customDomain}
277 jQuery('#tabCustomDomainControl').click();
278 jQuery('.store-order-container .domain-input').trigger('keyup');
279 {/if}
280});
281
282function updateUpsellDetailsOnBillingCycleChange(cycle) {
283 jQuery('.span-upsell').hide();
284 jQuery('.span-upsell-' + cycle).show();
285}
286</script>
287