Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 949 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
111 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>
683 lars 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>
111 lars 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>
683 lars 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>
111 lars 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>
683 lars 41
            <input type="text" name="Persdata[Firma]" class="text" value="{$old.Persdata.Firma|default:$smarty.session.SHOP.buy.Persdata.Firma}" maxlength="255">
111 lars 42
        </div>
43
 
44
        <div class="addr_100">
45
            <div class="addr_50">
46
                <div class="placeholder">{$langstrings.buy.street} *</div>
683 lars 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>
111 lars 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>
683 lars 55
                <input type="text" name="Persdata[Hausnummer]" class="text" value="{$old.Persdata.Hausnummer|default:$smarty.session.SHOP.buy.Persdata.Hausnummer}" maxlength="255" required />
111 lars 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>
683 lars 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 />
111 lars 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>
683 lars 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 />
111 lars 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>
683 lars 81
            {html_options options=$Laender id="Land" name="Persdata[Land]" selected=$old.Persdata.Land|default:$smarty.session.SHOP.buy.Persdata.Land|default:$defaultLandID}
111 lars 82
            <span class="input_error_msg">Pflichtfeld</span>
83
        </div>
84
 
85
        <div>
86
            <div class="placeholder">{$langstrings.buy.e_mail} *</div>
683 lars 87
            <input type="email" name="Persdata[email]" class="text" value="{$old.Persdata.email|default:$smarty.session.SHOP.buy.Persdata.email}" autocomplete="email" required>
111 lars 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>
683 lars 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>
111 lars 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
 
696 lars 128
        <div id="AGBCheckboxWrapper" class="{if $old.AGB||$smarty.session.AGB=="gelesen"}checked{else}unchecked{/if}">
111 lars 129
            <div class="checkbox">
696 lars 130
                <input id="AGB" type="checkbox" class="checkbox" name="AGB" value="gelesen" {if $old.AGB||$smarty.session.AGB=="gelesen"}checked="checked"{/if} required="required">
111 lars 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;
931 lars 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
    })
949 lars 268
    $('#Land').change();
111 lars 269
 
270
    $( "#ustidnr_input" ).hide();
271
    $( "#ustidnr_text" ).hide();
272
    $('#Land').change(function(){
932 lars 273
        let selected_country = $( "#Land" ).val();
111 lars 274
 
275
        if (selected_country == 47) {
276
            $( "#ustidnr_input" ).hide();
277
            $( "#ustidnr_text" ).hide();
278
        } else {
279
            $( "#ustidnr_text" ).show();
280
            $( "#ustidnr_input" ).show();
281
        }
282
    });
283
 
284
    // placeholder anim
285
    $('.placeholder').click(function() {
286
        $(this).next().focus();
287
    });
288
    $('.adressdaten input[type=text], .adressdaten input[type=email], .adressdaten textarea').each(function() {
289
        let inpt = $(this).val();
290
        if (inpt.length > 0 && textAnimationData2D($(this)[0])) {
291
            const { placeholder: { rawHeight } } = textAnimationData2D($(this)[0]);
292
            $(this).prev().css({
293
                "margin-left": "0px",
294
                "margin-top": -rawHeight + "px",
295
                "color": "#000",
296
            });
297
        }
298
    });
299
    $('.adressdaten input[type=text], .adressdaten input[type=email], .adressdaten textarea').focus(function(){
300
        let inpt = $(this).val();
301
        if(inpt.length == 0 && textAnimationData2D($(this)[0])) {
302
            const { placeholder: { rawHeight } } = textAnimationData2D($(this)[0]);
303
            $(this).prev().css({
304
                "margin-left": "0px",
305
                "margin-top": -rawHeight + "px",
306
                "color": "#000",
307
            });
308
        }
309
    });
310
    $('.adressdaten input[type=text], .adressdaten input[type=email]').blur(function(){
311
        let inpt = $(this).val();
312
        if(inpt.length == 0 && textAnimationData2D($(this)[0])) {
313
            const { input:{ height: heightInput }, placeholder:{ height: heightPlaceholder } } = textAnimationData2D($(this)[0]);
314
            const margin = (heightInput - heightPlaceholder) / 2;
315
            $(this).prev().css({
316
                "margin-left": margin / 2 + "px",
317
                "margin-top": margin + "px",
318
                "color":"#8E8E8E",
319
            });
320
            marginInputFields = margin;
321
        }
322
    });
323
    {*
324
        INFO: Es kommt zu einem Problem mit der Animation
325
        wenn vorher kein anderes Feld mit der Animation angesprochen wird da marginInputFields sonst leer ist.
326
        Die Rückkehr animation funktioniert dann schlich nicht .
327
    *}
328
    $('.adressdaten textarea').blur(function(){
329
        let inpt = $(this).val();
330
        if(inpt.length == 0 && textAnimationData2D($(this)[0])) {
331
            const { input:{ height: heightInput }, placeholder:{ height: heightPlaceholder } } = textAnimationData2D($(this)[0]);
332
            $(this).prev().css({
333
                "margin-left": marginInputFields / 2 + "px",
334
                "margin-top": marginInputFields + "px",
335
                "color":"#8E8E8E",
336
            });
337
        }
338
    });
339
 
340
 
341
    function textAnimationData2D(inputElement, textSelector = '.placeholder') {
342
        if(!inputElement || !isDOM(inputElement)) return;
343
        const placeholder = inputElement.parentElement.querySelector(textSelector);
344
        if(!placeholder || !isDOM(placeholder)) return;
345
 
346
        const { height: inputHeight } = getElement2DData(inputElement);
347
        const { height: placeholderHeight, rawHeight: placeholderRawHeight } = getElement2DData(placeholder);
348
 
349
        return {
350
            input: {
351
                height: inputHeight,
352
            },
353
            placeholder: {
354
                height: placeholderHeight,
355
                rawHeight: placeholderRawHeight,
356
                ref: placeholder,
357
            },
358
        }
359
    }
360
 
361
    function getElement2DData(element) {
362
        if(!isDOM(element)) return;
363
        const style = getComputedStyle(element);
364
 
365
        const paddingX = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
366
        const paddingY = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom);
367
        const borderX = parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);
368
        const borderY = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
369
 
370
        return {
371
            height: element.offsetHeight,
372
            width: element.offsetWidth,
373
            paddingX: paddingX,
374
            paddingY: paddingY,
375
            paddingLeft: parseFloat(style.paddingLeft),
376
            paddingRight: parseFloat(style.paddingRight),
377
            paddingTop: parseFloat(style.paddingTop),
378
            paddingBottom: parseFloat(style.paddingBottom),
379
            borderX: borderX,
380
            borderY: borderY,
381
            borderLeft: parseFloat(style.borderLeftWidth),
382
            borderRight: parseFloat(style.borderRightWidth),
383
            borderTop: parseFloat(style.borderTopWidth),
384
            borderBottom: parseFloat(style.borderBottomWidth),
385
            rawHeight: element.offsetHeight - paddingY - borderY,
386
            rawWidth: element.offsetWidth - paddingX - borderX,
387
            ref: {
388
                target: element,
389
                parent: element.parentElement
390
            }
391
        }
392
    }
393
 
394
    function isDOM(Obj) {
395
        return Obj instanceof Element;
396
    }
397
});
949 lars 398
</script>