| 2 |
lars |
1 |
<div class="adressdaten">
|
|
|
2 |
<!-- PayPalCheckout Rückgabe Rechnungskauf BEGIN -->
|
|
|
3 |
{if $smarty.session.SHOP.paypalCheckout.return.error===true && $smarty.get.ratepay_error==true}
|
|
|
4 |
<div>
|
|
|
5 |
<div>Fehler beim Rechnungskauf. {$langstrings.PayPalCheckout.rechnungskauf_error_add}</div>
|
|
|
6 |
<div>{$smarty.session.SHOP.paypalCheckout.return.msg}</div>
|
|
|
7 |
</div>
|
|
|
8 |
{/if}
|
|
|
9 |
<!-- PayPalCheckout Rückgabe Rechnungskauf END -->
|
|
|
10 |
|
|
|
11 |
{if $smarty.get.anfrage!=1 && $smarty.get.mode != "register"}
|
|
|
12 |
<h4> {$langstrings.buy.billing_address}</h4>
|
|
|
13 |
{/if}
|
|
|
14 |
|
|
|
15 |
<p>Bitte tragen Sie Ihre Adressdaten ein. Mit einem * gekennzeichnete Felder sind Pflichtfelder.</p>
|
|
|
16 |
|
|
|
17 |
<div>
|
|
|
18 |
{html_options name="Persdata[Anrede]" options=$anreden selected=$smarty.session.SHOP.buy.Persdata.Anrede}
|
|
|
19 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
20 |
</div>
|
|
|
21 |
|
|
|
22 |
<div class="addr_100">
|
|
|
23 |
<div class="addr_50">
|
|
|
24 |
<div class="placeholder">{$langstrings.buy.firstname} *</div>
|
|
|
25 |
<input type="text" name="Persdata[Vorname]" class="text" value="{$old.Persdata.Vorname|default:$smarty.session.SHOP.buy.Persdata.Vorname}" maxlength="255" autocomplete="given-name" required>
|
|
|
26 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
27 |
<input type="hidden" name="req[Vorname]" value="persdata">
|
|
|
28 |
|
|
|
29 |
</div>
|
|
|
30 |
|
|
|
31 |
<div class="addr_50">
|
|
|
32 |
<div class="placeholder">{$langstrings.buy.name} *</div>
|
|
|
33 |
<input name="Persdata[Nachname]" type="text" class="persdata" value="{$old.Persdata.Nachname|default:$smarty.session.SHOP.buy.Persdata.Nachname}" maxlength="255" autocomplete="family-name" required>
|
|
|
34 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
35 |
<input type="hidden" name="req[Nachname]" value="persdata">
|
|
|
36 |
</div>
|
|
|
37 |
</div>
|
|
|
38 |
|
|
|
39 |
<div>
|
|
|
40 |
<div class="placeholder">{$langstrings.buy.company}</div>
|
|
|
41 |
<input type="text" name="Persdata[Firma]" class="text" value="{$old.Persdata.Firma|default:$smarty.session.SHOP.buy.Persdata.Firma}" maxlength="255">
|
|
|
42 |
</div>
|
|
|
43 |
|
|
|
44 |
<div class="addr_100">
|
|
|
45 |
<div class="addr_50">
|
|
|
46 |
<div class="placeholder">{$langstrings.buy.street} *</div>
|
|
|
47 |
<input type="text" name="Persdata[Strasse]" class="text" value="{$old.Persdata.Strasse|default:$smarty.session.SHOP.buy.Persdata.Strasse}" maxlength="31" autocomplete="street-address" required>
|
|
|
48 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
49 |
<input type="hidden" name="req[Strasse]" value="persdata">
|
|
|
50 |
|
|
|
51 |
</div>
|
|
|
52 |
|
|
|
53 |
<div class="addr_50">
|
|
|
54 |
<div class="placeholder">Hausnummer *</div>
|
|
|
55 |
<input type="text" name="Persdata[Hausnummer]" class="text" value="{$old.Persdata.Hausnummer|default:$smarty.session.SHOP.buy.Persdata.Hausnummer}" maxlength="255" required />
|
|
|
56 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
57 |
<input type="hidden" name="req[Hausnummer]" value="persdata">
|
|
|
58 |
|
|
|
59 |
</div>
|
|
|
60 |
</div>
|
|
|
61 |
|
|
|
62 |
<div class="addr_100">
|
|
|
63 |
<div class="addr_50">
|
|
|
64 |
<div class="placeholder">{$langstrings.buy.postalcode} *</div>
|
|
|
65 |
<input type="text" name="Persdata[PLZ]" id="plz" class="text" value="{$old.Persdata.PLZ|default:$smarty.session.SHOP.buy.Persdata.PLZ}" maxlength="20" autocomplete="postal-code" required />
|
|
|
66 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
67 |
<input type="hidden" name="req[PLZ]" value="persdata">
|
|
|
68 |
|
|
|
69 |
</div>
|
|
|
70 |
|
|
|
71 |
<div class="addr_50">
|
|
|
72 |
<div class="placeholder">{$langstrings.buy.city} *</div>
|
|
|
73 |
<input type="text" name="Persdata[Ort]" id="ort" class="text" value="{$old.Persdata.Ort|default:$smarty.session.SHOP.buy.Persdata.Ort}" maxlength="255" autocomplete="address-level2" required />
|
|
|
74 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
75 |
<input type="hidden" name="req[Ort]" value="persdata">
|
|
|
76 |
|
|
|
77 |
</div>
|
|
|
78 |
</div>
|
|
|
79 |
|
|
|
80 |
<div>
|
|
|
81 |
{html_options options=$Laender id="Land" name="Persdata[Land]" selected=$old.Persdata.Land|default:$smarty.session.SHOP.buy.Persdata.Land|default:$defaultLandID}
|
|
|
82 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
83 |
</div>
|
|
|
84 |
|
|
|
85 |
<div>
|
|
|
86 |
<div class="placeholder">{$langstrings.buy.e_mail} *</div>
|
|
|
87 |
<input type="email" name="Persdata[email]" class="text" value="{$old.Persdata.email|default:$smarty.session.SHOP.buy.Persdata.email}" autocomplete="email" required>
|
|
|
88 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
89 |
<input type="hidden" name="req[email]" value="mail">
|
|
|
90 |
|
|
|
91 |
</div>
|
|
|
92 |
|
|
|
93 |
<div>
|
|
|
94 |
<div class="placeholder">{$langstrings.buy.phone} *</div>
|
|
|
95 |
<input type="text" name="Persdata[Telefon]" class="text" value="{$old.Persdata.Telefon|default:$smarty.session.SHOP.buy.Persdata.Telefon}" maxlength="31" autocomplete="tel" required>
|
|
|
96 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
97 |
<input type="hidden" name="Persdata[ID]" value="{$smarty.session.SHOP.buy.Persdata.ID}">
|
|
|
98 |
<input type="hidden" name="req[Telefon]" value="persdata">
|
|
|
99 |
|
|
|
100 |
</div>
|
|
|
101 |
|
|
|
102 |
<div>
|
|
|
103 |
<div id="ustidnr_text">
|
|
|
104 |
{$langstrings.buy.ustidnr_text|nl2br}
|
|
|
105 |
</div>
|
|
|
106 |
<div id="ustidnr_input" style="display:none;">
|
|
|
107 |
<div class="placeholder">{$langstrings.buy.ustidnr}</div>
|
|
|
108 |
<input type="text" name="Persdata[UStIdNr]" class="text" value="{$smarty.session.SHOP.buy.Persdata.UStIdNr}" maxlength="31">
|
|
|
109 |
</div>
|
|
|
110 |
</div>
|
|
|
111 |
|
|
|
112 |
{if $ini.finanzierung.aktiv==1}
|
|
|
113 |
<div>
|
|
|
114 |
<div class="placeholder"> {$langstrings.buy.birthday}</div>
|
|
|
115 |
{html_select_date field_array="Persdata[bday]" start_year=1900 end_year="-18" field_order="DMY" day_empty="Tag" month_empty="Monat" year_empty="Jahr" time=$smarty.session.SHOP.buy.Persdata.birthday day_value_format="%02d"}
|
|
|
116 |
{if $versandInfo.versandart=="finanzierung"}
|
|
|
117 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
118 |
{/if}
|
|
|
119 |
|
|
|
120 |
{if $versandInfo.versandart=="finanzierung"}
|
|
|
121 |
<input type="hidden" name="req[birthday]" value="date">
|
|
|
122 |
{/if}
|
|
|
123 |
{$langstrings.buy.birthday_explain}
|
|
|
124 |
|
|
|
125 |
</div>
|
|
|
126 |
{/if}
|
|
|
127 |
|
|
|
128 |
<div id="AGBCheckboxWrapper" class="{if $old.AGB||$smarty.session.AGB=="gelesen"}checked{else}unchecked{/if}">
|
|
|
129 |
<div class="checkbox">
|
|
|
130 |
<input id="AGB" type="checkbox" class="checkbox" name="AGB" value="gelesen" {if $old.AGB||$smarty.session.AGB=="gelesen"}checked="checked"{/if} required="required">
|
|
|
131 |
<span class="input_error_msg">Pflichtfeld</span>
|
|
|
132 |
<input type="hidden" name="req[AGB]" value="text">
|
|
|
133 |
<label for="AGB"> Ich akzeptiere die <a style="font-weight:bold;" href="/cms/agb" target="_blank">AGB.</a></label>
|
|
|
134 |
</div>
|
|
|
135 |
|
|
|
136 |
|
|
|
137 |
|
|
|
138 |
</div>
|
|
|
139 |
</div>
|
|
|
140 |
<style>
|
|
|
141 |
#AGBCheckboxWrapper {
|
|
|
142 |
display: flex;
|
|
|
143 |
flex-direction: row;
|
|
|
144 |
gap: 0.5%;
|
|
|
145 |
padding: 2%;
|
|
|
146 |
width: fit-content;
|
|
|
147 |
border-radius:5px;
|
|
|
148 |
}
|
|
|
149 |
|
|
|
150 |
#AGBCheckboxWrapper > .checkbox {
|
|
|
151 |
display: flex;
|
|
|
152 |
flex-direction: row;
|
|
|
153 |
align-items: center;
|
|
|
154 |
justify-content: flex-start;
|
|
|
155 |
gap:8px;
|
|
|
156 |
}
|
|
|
157 |
|
|
|
158 |
#AGBCheckboxWrapper .checkbox span.input_error_msg {
|
|
|
159 |
margin-top: 0;
|
|
|
160 |
padding: 0;
|
|
|
161 |
}
|
|
|
162 |
|
|
|
163 |
#AGBCheckboxWrapper label {
|
|
|
164 |
min-width: max-content;
|
|
|
165 |
}
|
|
|
166 |
|
|
|
167 |
.unchecked {
|
|
|
168 |
transition:all 200ms ease;
|
|
|
169 |
background:rgba(226,6,50,.3);
|
|
|
170 |
}
|
|
|
171 |
.checked {
|
|
|
172 |
transition:all 200ms ease;
|
|
|
173 |
background:rgba(33,143,61,.3);
|
|
|
174 |
}
|
|
|
175 |
</style>
|
|
|
176 |
<script>
|
|
|
177 |
document.addEventListener('DOMContentLoaded', () => {
|
|
|
178 |
// AGB toggle
|
|
|
179 |
const checkboxEl = document.querySelector('#AGB');
|
|
|
180 |
const wrapperEl = document.querySelector('#AGBCheckboxWrapper');
|
|
|
181 |
|
|
|
182 |
checkboxEl.addEventListener('change', () => {
|
|
|
183 |
wrapperEl.className = (checkboxEl.checked) ? 'checked' : 'unchecked';
|
|
|
184 |
});
|
|
|
185 |
|
|
|
186 |
wrapperEl.addEventListener('click', (e) => {
|
|
|
187 |
const tag = e.target.nodeName.toLowerCase();
|
|
|
188 |
if(tag !== 'a' && tag !== 'input' && tag !== 'label') {
|
|
|
189 |
checkboxEl.checked = !checkboxEl.checked;
|
|
|
190 |
wrapperEl.className = (checkboxEl.checked) ? 'checked' : 'unchecked';
|
|
|
191 |
}
|
|
|
192 |
});
|
|
|
193 |
|
|
|
194 |
// Required
|
|
|
195 |
const inputElements = document.querySelectorAll('input');
|
|
|
196 |
for(const inputElement of inputElements) {
|
|
|
197 |
const required = (inputElement.required);
|
|
|
198 |
const errorMsg = inputElement.parentElement.querySelector('.input_error_msg');
|
|
|
199 |
|
|
|
200 |
if(!errorMsg || inputElement.id === 'AGB' || inputElement.type === 'hidden') {
|
|
|
201 |
continue;
|
|
|
202 |
}
|
|
|
203 |
|
|
|
204 |
if(inputElement.value.length > 0 || required === false) {
|
|
|
205 |
errorMsg.style.opacity = '0';
|
|
|
206 |
}
|
|
|
207 |
|
|
|
208 |
if(required && (inputElement.value.length === 0 || inputElement.autocomplete === 'email')) {
|
|
|
209 |
let valid = false;
|
|
|
210 |
if(inputElement.autocomplete === 'email') {
|
|
|
211 |
valid = validateEmail(inputElement.value);
|
|
|
212 |
}
|
|
|
213 |
// inputElement.style.outline = (valid) ? 'unset' : 'red dashed 1px';
|
|
|
214 |
errorMsg.style.opacity = (valid) ? '0' : '1';
|
|
|
215 |
}
|
|
|
216 |
|
|
|
217 |
if(required) {
|
|
|
218 |
inputElement.addEventListener('blur', (e) => {
|
|
|
219 |
let valid = false;
|
|
|
220 |
const inputElement = e.target;
|
|
|
221 |
const errorMsg = e.target.parentElement.querySelector('.input_error_msg');
|
|
|
222 |
switch (inputElement.autocomplete) {
|
|
|
223 |
case 'email':
|
|
|
224 |
valid = validateEmail(inputElement.value);
|
|
|
225 |
break;
|
|
|
226 |
default:
|
|
|
227 |
valid = (inputElement.value.length > 0);
|
|
|
228 |
break;
|
|
|
229 |
}
|
|
|
230 |
inputElement.style.outline = (valid) ? 'unset' : 'red dashed 1px';
|
|
|
231 |
errorMsg.style.opacity = (valid) ? '0' : '1';
|
|
|
232 |
});
|
|
|
233 |
}
|
|
|
234 |
}
|
|
|
235 |
});
|
|
|
236 |
|
|
|
237 |
function validateEmail(email) {
|
|
|
238 |
{literal}
|
|
|
239 |
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
|
|
240 |
{/literal}
|
|
|
241 |
return email.match(emailRegex);
|
|
|
242 |
}
|
|
|
243 |
|
|
|
244 |
$( document ).ready(function() {
|
|
|
245 |
{* // toggle checked status (CSS)
|
|
|
246 |
$('#AGB').click( function() {
|
|
|
247 |
var chk = $(this).parent().parent();
|
|
|
248 |
let classname = chk.attr("class");
|
|
|
249 |
if(classname=="checked") {
|
|
|
250 |
chk.attr("class",'unchecked');
|
|
|
251 |
}else {
|
|
|
252 |
chk.attr("class",'checked');
|
|
|
253 |
}
|
|
|
254 |
}); *}
|
|
|
255 |
let marginInputFields;
|
|
|
256 |
$('#Land, #liefer_Land').change(function(){
|
|
|
257 |
let land=$('#Land').val();
|
|
|
258 |
if($('#Lieferadresse_f').prop("checked")==false)
|
|
|
259 |
{
|
|
|
260 |
land=$('#liefer_Land').val();
|
|
|
261 |
}
|
|
|
262 |
let c_url="/update_versand?Land="+land+"&liefer=1";
|
|
|
263 |
console.log(c_url);
|
|
|
264 |
$.get(c_url,function(pppVersand){
|
|
|
265 |
$('#Versand').val(pppVersand);
|
|
|
266 |
});
|
|
|
267 |
})
|
|
|
268 |
|
|
|
269 |
$( "#ustidnr_input" ).hide();
|
|
|
270 |
$( "#ustidnr_text" ).hide();
|
|
|
271 |
$('#Land').change(function(){
|
|
|
272 |
let selected_country = $( "#Land" ).val();
|
|
|
273 |
|
|
|
274 |
if (selected_country == 47) {
|
|
|
275 |
$( "#ustidnr_input" ).hide();
|
|
|
276 |
$( "#ustidnr_text" ).hide();
|
|
|
277 |
} else {
|
|
|
278 |
$( "#ustidnr_text" ).show();
|
|
|
279 |
$( "#ustidnr_input" ).show();
|
|
|
280 |
}
|
|
|
281 |
});
|
|
|
282 |
|
|
|
283 |
// placeholder anim
|
|
|
284 |
$('.placeholder').click(function() {
|
|
|
285 |
$(this).next().focus();
|
|
|
286 |
});
|
|
|
287 |
$('.adressdaten input[type=text], .adressdaten input[type=email], .adressdaten textarea').each(function() {
|
|
|
288 |
let inpt = $(this).val();
|
|
|
289 |
if (inpt.length > 0 && textAnimationData2D($(this)[0])) {
|
|
|
290 |
const { placeholder: { rawHeight } } = textAnimationData2D($(this)[0]);
|
|
|
291 |
$(this).prev().css({
|
|
|
292 |
"margin-left": "0px",
|
|
|
293 |
"margin-top": -rawHeight + "px",
|
|
|
294 |
"color": "#000",
|
|
|
295 |
});
|
|
|
296 |
}
|
|
|
297 |
});
|
|
|
298 |
$('.adressdaten input[type=text], .adressdaten input[type=email], .adressdaten textarea').focus(function(){
|
|
|
299 |
let inpt = $(this).val();
|
|
|
300 |
if(inpt.length == 0 && textAnimationData2D($(this)[0])) {
|
|
|
301 |
const { placeholder: { rawHeight } } = textAnimationData2D($(this)[0]);
|
|
|
302 |
$(this).prev().css({
|
|
|
303 |
"margin-left": "0px",
|
|
|
304 |
"margin-top": -rawHeight + "px",
|
|
|
305 |
"color": "#000",
|
|
|
306 |
});
|
|
|
307 |
}
|
|
|
308 |
});
|
|
|
309 |
$('.adressdaten input[type=text], .adressdaten input[type=email]').blur(function(){
|
|
|
310 |
let inpt = $(this).val();
|
|
|
311 |
if(inpt.length == 0 && textAnimationData2D($(this)[0])) {
|
|
|
312 |
const { input:{ height: heightInput }, placeholder:{ height: heightPlaceholder } } = textAnimationData2D($(this)[0]);
|
|
|
313 |
const margin = (heightInput - heightPlaceholder) / 2;
|
|
|
314 |
$(this).prev().css({
|
|
|
315 |
"margin-left": margin / 2 + "px",
|
|
|
316 |
"margin-top": margin + "px",
|
|
|
317 |
"color":"#8E8E8E",
|
|
|
318 |
});
|
|
|
319 |
marginInputFields = margin;
|
|
|
320 |
}
|
|
|
321 |
});
|
|
|
322 |
{*
|
|
|
323 |
INFO: Es kommt zu einem Problem mit der Animation
|
|
|
324 |
wenn vorher kein anderes Feld mit der Animation angesprochen wird da marginInputFields sonst leer ist.
|
|
|
325 |
Die Rückkehr animation funktioniert dann schlich nicht .
|
|
|
326 |
*}
|
|
|
327 |
$('.adressdaten textarea').blur(function(){
|
|
|
328 |
let inpt = $(this).val();
|
|
|
329 |
if(inpt.length == 0 && textAnimationData2D($(this)[0])) {
|
|
|
330 |
const { input:{ height: heightInput }, placeholder:{ height: heightPlaceholder } } = textAnimationData2D($(this)[0]);
|
|
|
331 |
$(this).prev().css({
|
|
|
332 |
"margin-left": marginInputFields / 2 + "px",
|
|
|
333 |
"margin-top": marginInputFields + "px",
|
|
|
334 |
"color":"#8E8E8E",
|
|
|
335 |
});
|
|
|
336 |
}
|
|
|
337 |
});
|
|
|
338 |
|
|
|
339 |
|
|
|
340 |
function textAnimationData2D(inputElement, textSelector = '.placeholder') {
|
|
|
341 |
if(!inputElement || !isDOM(inputElement)) return;
|
|
|
342 |
const placeholder = inputElement.parentElement.querySelector(textSelector);
|
|
|
343 |
if(!placeholder || !isDOM(placeholder)) return;
|
|
|
344 |
|
|
|
345 |
const { height: inputHeight } = getElement2DData(inputElement);
|
|
|
346 |
const { height: placeholderHeight, rawHeight: placeholderRawHeight } = getElement2DData(placeholder);
|
|
|
347 |
|
|
|
348 |
return {
|
|
|
349 |
input: {
|
|
|
350 |
height: inputHeight,
|
|
|
351 |
},
|
|
|
352 |
placeholder: {
|
|
|
353 |
height: placeholderHeight,
|
|
|
354 |
rawHeight: placeholderRawHeight,
|
|
|
355 |
ref: placeholder,
|
|
|
356 |
},
|
|
|
357 |
}
|
|
|
358 |
}
|
|
|
359 |
|
|
|
360 |
function getElement2DData(element) {
|
|
|
361 |
if(!isDOM(element)) return;
|
|
|
362 |
const style = getComputedStyle(element);
|
|
|
363 |
|
|
|
364 |
const paddingX = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
|
|
|
365 |
const paddingY = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);
|
|
|
366 |
const borderX = parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);
|
|
|
367 |
const borderY = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
|
|
|
368 |
|
|
|
369 |
return {
|
|
|
370 |
height: element.offsetHeight,
|
|
|
371 |
width: element.offsetWidth,
|
|
|
372 |
paddingX: paddingX,
|
|
|
373 |
paddingY: paddingY,
|
|
|
374 |
paddingLeft: parseFloat(style.paddingLeft),
|
|
|
375 |
paddingRight: parseFloat(style.paddingRight),
|
|
|
376 |
paddingTop: parseFloat(style.paddingTop),
|
|
|
377 |
paddingBottom: parseFloat(style.paddingBottom),
|
|
|
378 |
borderX: borderX,
|
|
|
379 |
borderY: borderY,
|
|
|
380 |
borderLeft: parseFloat(style.borderLeftWidth),
|
|
|
381 |
borderRight: parseFloat(style.borderRightWidth),
|
|
|
382 |
borderTop: parseFloat(style.borderTopWidth),
|
|
|
383 |
borderBottom: parseFloat(style.borderBottomWidth),
|
|
|
384 |
rawHeight: element.offsetHeight - paddingY - borderY,
|
|
|
385 |
rawWidth: element.offsetWidth - paddingX - borderX,
|
|
|
386 |
ref: {
|
|
|
387 |
target: element,
|
|
|
388 |
parent: element.parentElement
|
|
|
389 |
}
|
|
|
390 |
}
|
|
|
391 |
}
|
|
|
392 |
|
|
|
393 |
function isDOM(Obj) {
|
|
|
394 |
return Obj instanceof Element;
|
|
|
395 |
}
|
|
|
396 |
});
|
|
|
397 |
</script>
|