IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

jQuery Discussion :

Variation de valeur formulaire en fonction de boutons et cases


Sujet :

jQuery

  1. #1
    Futur Membre du Club Avatar de Saturos2k4
    Homme Profil pro
    Analyse système
    Inscrit en
    Juillet 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Juillet 2015
    Messages : 21
    Points : 8
    Points
    8
    Par défaut Variation de valeur formulaire en fonction de boutons et cases
    Bonjour,

    Voici le problème :

    Je travaille actuellement sur un formulaire de paiement en Php/html et javascript, le select item fonctionne et met à jour le prixdans la case grise total,

    J'aimerai rajouter des boutons "qualité" par default égale à 1, donc total x 1, et je voudrai faire varier la valeur de total

    Exemple : qualité standard => total x 1.50

    qualité pro => total x2.00



    voici mon code js du bouton select qui fonctionne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $('select[name="item_id"]').on('change', function() {
               var total = parseFloat($('select[name="item_id"] option:selected').attr('data-price')).toFixed(2);
               updateTotal(total);
           });
    code html/php du select :

    Code HTLM : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <select name="item_id" class="form-control" data-rule-required="true">
    											<option value="">-- S&eacute;lectionnez le produit --</option>
    											<?php foreach ( Model::factory('Item')->find_many() as $item ) : ?>
    											<option value="<?php echo $item->id; ?>" data-name="<?php echo $item->name; ?>" data-price="<?php echo $item->price; ?>" <?php echo get('item_id') == $item->id ? 'selected' : ''; ?>><?php echo $item->name; ?> (<?php echo currency($item->price); ?>)</option>
    											<?php endforeach; ?>
    										</select>
    voici le code js des boutons radio qui ne fonctionne pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $('input[name="quality"]').on('change', function() {
    			var input = document.getElementById(cb.getAttribute('data-qty'));									 
    			var qty = input.value;
    			var amount = 0;
    			if (qty != '') 
    			{
                amount += total * qty;
                }
                updateTotal(amount);
            });
    code html des boutons :

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <input name="quality" type="radio" class="my-activity" value="1.00" data-qty="1.00" checked> 
    Qualité 1er Prix (total x 1)<br />
    <input class="my-activity" type="radio" name="quality" value="1.50" data-qty="1.50"> Qualité Standard (total x 1.5)<br />
    <input class="my-activity" type="radio" name="quality" value="2.00" data-qty="2.00"> Qualité Pro (total x 2)<br />


    Je bloque un peu je dois avouer... Merci d'avance pour votre aide :-)

  2. #2
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    premier truc : les [inputs].value sont de type texte et non de type numérique.
    Chercher à faire des opérations arithmétiques avec du texte, ça ne peut pas marcher.

    Pour les [inputs] en HTML5 il faut utiliser des balises <label> surtout pour les boutons radio et les checkbox, et c'est pas juste une question de "respect des normes" mais c'est parce qu'il y a des mécanismes utiles qui vont avec.
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  3. #3
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 681
    Points : 5 221
    Points
    5 221
    Par défaut
    Eh oui...

    En d'autres termes, change tes valeurs avec Number(valeur), donne un id à chaque bouton, un label qui va bien avec, et sera un formulaire de paiement un peu plus engageant;

  4. #4
    Futur Membre du Club Avatar de Saturos2k4
    Homme Profil pro
    Analyse système
    Inscrit en
    Juillet 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Juillet 2015
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Bonsoir , merci beaucoup pour votre support ;-)

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <label for="quality"><span class="colordanger">*</span>Qualit&eacute; rédactionnelle:
    <input id="quality" name="quality" type="radio" class="my-activity" value="1.00" data-qty="1.00" checked> 
    Qualité 1er Prix (total x 1)<br />
    <input id="quality" class="my-activity" type="radio" name="quality" value="1.50" data-qty="1.50"> Qualité Standard (total x 1.5)<br />
    <input id="quality" class="my-activity" type="radio" name="quality" value="2.00" data-qty="2.00"> Qualité Pro (total x 2)<br />
    </label>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     $('input[id="quality"]').on('change', function() {
    			var input = document.getElementById(cb.getAttribute('data-qty'));									 
    			var qty = Number(value);
    			var amount = 0;
    			if (qty != '') 
    			{
                amount += total * qty;
                }
                updateTotal(amount);
            });
    Voici mes modifications, mais ça n'a pas l'air de fonctionner... j'ai du louper quelque chose :-/

  5. #5
    Expert confirmé
    Avatar de javatwister
    Homme Profil pro
    danseur
    Inscrit en
    Août 2003
    Messages
    3 681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : danseur

    Informations forums :
    Inscription : Août 2003
    Messages : 3 681
    Points : 5 221
    Points
    5 221
    Par défaut
    Number(input.value)

  6. #6
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    C'est un petit peu délirant comme code, alors j'ai au moins 2 questions :

    1 / à quoi ça sert d'avoir deux attributs différents pour indiquer la même chose ?
    comme ici value="1.50" data-qty="1.50"

    2 / Pourquoi utiliser du jQuery pour un truc aussi trivial qui peut s'écrire 100 fois plus simplement en javascript ?

    une remarque:
    visiblement, il s'agit d'un morceau de formulaire, j'aimerai mieux voir cette partie de code entière de ce formulaire en HTML (générée) et pas avec du PHP.
    parce que, par exemple, on ne voit pas ce que peut être l' élément HTML ayant comme critère jQuery $('input[id="quality"]') (qui au passage est vraiment tirré par les cheveux, mais pourquoi pas....)

    Exemple de formulaire quand on lit la documentation => voir le code à jour dans le post à la suite
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  7. #7
    Futur Membre du Club Avatar de Saturos2k4
    Homme Profil pro
    Analyse système
    Inscrit en
    Juillet 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Juillet 2015
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Bonjour,

    Effectivement j'ai laissé trainé data-qty dans le code, je l'ai supprimé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $('input[id="quality"]').on('change', function() {								 
    			var qty = Number(input.value);
    			var amount = 0;
    			if (qty != '') 
    			{
                amount += total * qty;
                }
                updateTotal(amount);
            });
    PS: Effectivement on pourrait faire plus simple...

    Voici le code entier du fichier JS :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    	var stripe = null;
     
    	var cardElement = null;
     
    var app = {
     
        /*
         * init is where we initialize everything
         */
        init: function() {
     
     
            this.addValidation();
            this.bootstrap();
            this.tableSearch();
            this.paymentPage();
            this.checkNotification();
        },
     
        /******************************************************
         *
         ******************************************************/
     
         /*
        * setup our payment page
        */
        paymentPage: function() {
     
    		if($('.publishable-key').val() != ''){
    			stripe=Stripe($('.publishable-key').val());
    			var elements = stripe.elements();
    			cardElement=elements.create('card');
    			cardElement.mount('#card-element');
    		}
     
     
            $('input:text:visible:first').focus();
     
            // show hide the recurring notice
            $('input[name="payment_type"]').on('change', function() {
                var type = $('input[name="payment_type"]:checked').val();
                if ( type == 'recurring' ) {
                    $('.recurring-alert').show();
     
                    var enableSubscriptions = $('.enable-subscriptions').val();
     
                    if ( enableSubscriptions == 'stripe_only' ) {
                        $('input[name="payment_method"][value="creditcard"]').click();
                        $('input[name="payment_method"][value="paypal"]').prop('disabled', true);
                    }
                    if ( enableSubscriptions == 'paypal_only' ) {
                        $('input[name="payment_method"][value="paypal"]').click();
                        $('input[name="payment_method"][value="creditcard"]').prop('disabled', true);
                    }
     
     
                } else {
                    $('.recurring-alert').hide();
                    $('input[name="payment_method"]').prop('disabled', false);
                }
            });
     
            // show hide the proper payment details
            $('input[name="payment_method"]').on('change', function() {
                var method = $('input[name="payment_method"]:checked').val();
                $('.stripe-length-text, .paypal-length-text').hide();
                if ( method == 'paypal' ) {
                    $('.paypal-content').show();
                    $('.creditcard-content').hide();
                    $('.paypal-length-text').show();
                } else {
                    $('.paypal-content').hide();
                    $('.creditcard-content').show();
                    $('.stripe-length-text').show();
                }
            });
     
            // show hide the recurring notice
            $('input[name="name"]').on('blur', function() {
                $('input[data-stripe="name"]').val($(this).val());
            });
     
            // show proper card type image on keyup
            $('.card-number').on('keyup', function() {
                var number = $(this).val();
                var type = app.getCardType(number);
                $('.card-type-image').removeClass('visa mastercard amex discover none').addClass(type);
            });
     
     
     
     
     
            var updateTotal = function(total) {
                if ( !isNaN(total) ) {
                    $('.submit-button .total span').html(total);
                    $('.submit-button .total').css('display', 'block');
                } else {
                    $('.submit-button .total').css('display', 'none');
                }
     
    			paymentIntent();
            }
     
    		var paymentIntent = function(){
    			console.log("Payment intent called");
    			let vamount=0.00;
     
    			if($('select[name="item_id"]').length > 0){
    				vamount=parseFloat($('select[name="item_id"] option:selected').attr('data-price')).toFixed(2);
    				console.log(vamount);
    			}
    			if($('#order_form input[name="amount"]').length > 0){
    				vamount=parseFloat($('input[name="amount"]').val()).toFixed(2);
    				console.log("coiso tal");
    			}
    			if($('#invoice-amount').length > 0){
    				vamount=parseFloat($('#invoice-amount').text()).toFixed(2);
    				console.log("tal");
    			}
     
    			vamount=Math.round(vamount*100);
    			if(isNaN(vamount)){
    				vamount=0.00;
    			} 
     
    			console.log(vamount);
     
    			let type=$('input[name=payment_type]:checked').val();
     
    			let url=$('#order_form').attr('action');
     
    			let data={
    				amount:vamount
    			};
     
    			if($("#payment_intentsk").val() !== ''){
    				data.payment_intentsk = $("#payment_intentsk").val();
    			}
     
    			$.post(url+"?action=create_intent", data , function(data, status){
    				if(status==="success"){
    					$("#payment_intentsk").val(data.message.client_secret);
    				} 
    			});
    		}
     
    		if($('#invoice-amount').length > 0){
    			paymentIntent();			
    		}
     
            // show total amount on button
            $('select[name="item_id"]').on('change', function() {
                var total = parseFloat($('select[name="item_id"] option:selected').attr('data-price')).toFixed(2);
                updateTotal(total);
            });
     
            $('input[name="amount"]').on('blur', function() {
                var total = parseFloat($(this).val()).toFixed(2);
                updateTotal(total);
            });
     
            $('input[id="quality"]').on('change', function() {								 
    			var qty = Number(total.value) * Number(quality.value)
    			var amount = 0;
    			if (qty != '') 
    			{
                amount += total * qty;
                }
                updateTotal(amount);
            });
     
     
            // update paypal form on paypal button click
            $('.paypal-button').on('click', function(e) {
                e.preventDefault();
                if ( $('#order_form').valid() ) {
                    // set button to loading
                    $('.paypal-button').button('loading');
     
                    // get amount and description
                    var amount = 0;
                    var description = '';
                    if ( $('#order_form select[name="item_id"]').length ) {
                        amount = $('#order_form select[name="item_id"] option:selected').attr('data-price');
                        description = $('#order_form select[name="item_id"] option:selected').attr('data-name');
                    } else if ( $('#order_form input[name="amount"]').length ) {
                        amount = $('#order_form input[name="amount"]').val();
                        description = $('#order_form textarea[name="description"]').val();
                        description = description ? description : 'PayPal Payment';
                    }
                    // serialize our form data
                    var formData = $('#order_form').serialize();
                    // remove undeeded data from string
                    formData = formData.replace(/(&?amount=[^&]*|&?description=[^&]*|&?action=[^&]*|&?payment_type=[^&]*|&?payment_method=[^&]*)/g, '');
                    formData = formData.replace(/^&/, '');
                    // add form data to custom input field
                    $('.paypal-form input[name="custom"]').val(formData);
     
     
                    // only update values if we dont' have invoice
                    if ( !$('input[name="invoice_id"]').length ) {
                        if ( $('input[name="payment_type"]:checked').val() == 'recurring' ) {
                            $('#paypal_form_recurring input[name="a3"]').val(amount);
                            $('#paypal_form_recurring input[name="item_name"]').val(description);
                        } else {
                            $('#paypal_form_one_time input[name="amount"]').val(amount);
                            $('#paypal_form_one_time input[name="item_name"]').val(description);
                        }
                    }
     
                    // submit proper form now
                    if ( $('input[name="payment_type"]:checked').val() == 'recurring' ) {
                        $('#paypal_form_recurring').submit();
                    } else {
                        $('#paypal_form_one_time').submit();
                    }
                }
            });
     
            // show success message on paypal success return
            if ( $.jGet('status') == 'paypal_success' ) {
                app.response = 'Your PayPal payment has been received, you should receive a confirmation email shortly.';
                $('.submit-button').button('complete');
                setTimeout(function() {
                    $('.submit-button').prop('disabled', true).removeClass('btn-primary').addClass('btn-default colorsuccess');
                    app.showSuccess();
                }, 10);
            }
            if ( $.jGet('status') == 'paypal_subscription_success' ) {
                app.response = 'Your PayPal subscription has been created successfully, you should receive a confirmation email shortly.';
                $('.submit-button').button('complete');
                setTimeout(function() {
                    $('.submit-button').prop('disabled', true).removeClass('btn-primary').addClass('btn-default colorsuccess');
                    app.showSuccess();
                }, 10);
            }
     
     
        },
     
        /*
        * setup our bootstrap functionality
        */
        bootstrap: function() {
     
            $('[data-toggle="tooltip"]').tooltip({html: true});
            $('[data-toggle="popover"]').popover();
     
            if ( $('.nav-tabs').length ) {
                if ( $.jGet('tab') ) {
                    $('.nav-tabs a[href="#' + $.jGet('tab') + '"]').tab('show');
                } else {
                    $('.nav-tabs a:first').tab('show');
                    if ( $('.nav-tabs.hash-tabs').length ) {
                        window.location.hash = '#tab=' + $('.nav-tabs.hash-tabs a:first').attr('href').substr(1);
                    }
                }
                $('.hash-tabs a[data-toggle="tab"]').off('shown.bs.tab').on('shown.bs.tab', function(e) {
                    window.location.hash = '#tab=' + e.target.hash.substr(1);
                });
            }
     
            // show last settings pane if it's set
            if ( localStorage.activePill ) {
                $('.nav-pill-control > li').removeClass('active');
                $('.nav-pill-control > li > a[href="' + localStorage.activePill + '"]').parent().addClass('active');
                $('.nav-pill-pane').hide();
                $(localStorage.activePill).show();
            }
     
            $('[data-hide]').on('click', function() {
                if ( $(this).parent().hasClass('modal-header') ) {
                    $('#' + $(this).attr('data-hide')).modal('hide')
                } else {
                    $(this).closest('.' + $(this).attr('data-hide')).hide();
                }
            });
     
            $('#add_item, #create_invoice').on('shown.bs.modal', function(e) {
                $(this).find('input:text:first').focus();
            });
     
            $('#edit_item').on('show.bs.modal', function(e) {
                var $tr = $(e.relatedTarget).closest('tr');
                $('#edit_item input[name="id"]').val($tr.attr('data-item-id'));
                $('#edit_item input[name="name"]').val($tr.attr('data-item-name'));
                $('#edit_item input[name="price"]').val($tr.attr('data-item-price'));
            });
     
            $('.datepicker').datepicker();
     
            $('.confirm-click').on('click', function(e) {
                e.preventDefault();
                $this = $(this);
                var text = $this.attr('data-text') ? $this.attr('data-text') : 'Yes, delete it!';
                swal({
                    title: 'Are you sure?',
                    text: 'This action cannot be undone.',
                    type: 'warning',
                    showCancelButton: true,
                    confirmButtonClass: 'btn-danger',
                    confirmButtonText: text,
                    closeOnConfirm: false
                }, function() {
                    window.location = $this.attr('href');
                });
     
            });
     
     
            $('.nav-pill-control a').on('click', function(e) {
                e.preventDefault();
                $('.nav-pill-control > li').removeClass('active');
                $(this).parent().addClass('active');
                $('.nav-pill-pane').hide();
                $($(this).attr('href')).show();
                localStorage.activePill = $(this).attr('href');
            });
     
            $('.maxlength[maxlength]').maxlength({
                alwaysShow: false,
                threshold: 20,
                showCharsTyped: true,
                placement: 'bottom',
                warningClass: 'label label-success',
                limitReachedClass: 'label label-danger',
                separator: ' of ',
                validate: true
            });
     
     
        },
     
        /*
        * table search
        */
        tableSearch: function() {
     
            // live filter searching
            $('input.filter').on('keyup', function() {
                var $table = $(this).closest('.tab-pane').find('table');
                var rex = new RegExp($(this).val(), 'i');
                $table.find('tbody tr').hide();
                $table.find('tbody tr').filter(function() {
                    return rex.test($(this).text());
                }).show();
                if ( $table.find('tbody tr:visible').length === 0 ) {
                    $table.find('tbody').next('tfoot').show();
                } else {
                    $table.find('tbody').next('tfoot').hide();
                }
            });
     
        },
     
        /*
         * Add our jquery form validation here
         */
        addValidation: function() {
            $('form.validate').each(function() {
                $(this).validate({
                    errorClass: 'validate-error control-label',
                    validClass: 'validate-valid control-label',
                    ignore: 'select:hidden:not(.selectpicker), input:hidden, textarea:hidden',
                    errorPlacement: function(error, element) {
                        if ( element.is('input:checkbox') || element.is('input:radio') ) {
                            var lastElement = $('[name="' + element.attr('name') + '"]:last');
                            lastElement = element.parent().hasClass('icheck') ? lastElement.closest('label') : lastElement;
                            error.insertAfter(lastElement.parent().is('label') ? lastElement.parent() : lastElement);
                        } else {
                            if ( element.closest('.input-group').length == 1 ) {
                                error.insertAfter(element.closest('.input-group'));
                            } else {
                                error.insertAfter(element);
                            }
                        }
                    },
                    highlight: function(element, errorClass, validClass) {
                        if ( $(element).closest('.form-group').length == 1 ) {
                            $(element).closest('.form-group').addClass('has-error');
                        } else {
                            $(element).addClass('validate-error');
                        }
                    },
                    unhighlight: function(element, errorClass, validClass) {
                        if ( $(element).closest('.form-group').length == 1 ) {
                            $(element).closest('.form-group').removeClass('has-error');
                        } else {
                            $(element).removeClass('validate-error');
                        }
                    },
                    /*onkeyup: function(element, event) {
                        if ( !$(element).hasClass('check-email') ) {
                            $(element).valid();
                        }
                    },*/
                    onfocusout: function(element, event) {
                        if ( !$(element).hasClass('check-email') && $(element).attr('aria-invalid') ) {
                            $(element).valid();
                        }
                    },
                    invalidHandler: function(event, validator) {
                        // this fires if the form didn't pass validatation
                    },
                    submitHandler: function(form,event) {
    					event.preventDefault();
                        app.submitForm(form);
                    }
                });
            });
     
        },
     
     
        /*
         * handle a form submission
         */
        submitForm: function(form) {
            $form = $(form);
     
            // prevent disabled form from submission
            if ( $form.hasClass('disabled') ) {
                return false;
            }
     
            // check for paypal method
            if ( $('input[name="payment_method"]:checked').val() == 'paypal' ) {
                $('.paypal-button').click();
                return false;
            }
     
            // set our button to loading state
            $button = $form.find('.btn[data-loading-text]:visible:last');
            $button.button('loading');
     
            if ( $form.attr('id') == 'order_form' ) {
                // hide errors first
                $('.error-alert').hide();
     
    			let ptype=$('input[name=payment_type]:checked').val();
     
    			if(ptype==='recurring'){
     
    				stripe.createToken(cardElement).then(function(result) {
    					if (result.error) {
    						// Inform the customer that there was an error.
    						app.response = result.error.message;
    						app.showError();
    						$button.button('reset');
    						return false;
    					} else {
    					  // Send the token to your server.
    					  console.log(result);
     
    						$form.ajaxSubmit({
    								data: {
    									token:result.token,
    									source:result.token.id
    								},
    								beforeSubmit: function() {
    								},
    								error: function(jqXHR, textStatus, errorThrown) {
    									// set our response and show error
    									app.response = jqXHR.responseText;
    									app.showError();
    									// reset the button state now
    									$button.button('reset');
    								},
    								success: function(data) {
    									// set the global response value
    									app.response = data.message;
    									// reset the button state now
    									$button.button('reset');
    									if ( data.status ) {
    										// disable the current form and button
    										$('#order_form').addClass('disabled');
    										$button.button('complete');
    										setTimeout(function() {
    											$button.prop('disabled', true).removeClass('btn-primary').addClass('btn-default colorsuccess');
    										}, 10);  
    										$('input[name="payment_method"]').prop('disabled', true);  
    										app.showSuccess();
    									} else {
    										app.showError();
    									}
    								}
    						});
     
    					}
    				});
     
    			}
    			else {
     
    				let clientSecret=$("#payment_intentsk").val();
     
    					stripe.handleCardPayment(
    						clientSecret, cardElement, {
    						  payment_method_data: {
    							billing_details: {name: $("input[name='name']").val()}
    						  }
    						}
    					  ).then(function(result) {
    						if (result.error) {
    							app.response = result.error.message;
    							app.showError();
    							$button.button('reset');
    							return false;
    						} else {
     
    							$form.ajaxSubmit({
    								data: {
    									paymentintentid: result.paymentIntent.id
    								},
    								beforeSubmit: function() {
    								},
    								error: function(jqXHR, textStatus, errorThrown) {
    									// set our response and show error
    									app.response = jqXHR.responseText;
    									app.showError();
    									// reset the button state now
    									$button.button('reset');
    								},
    								success: function(data) {
    									// set the global response value
    									app.response = data.message;
    									// reset the button state now
    									$button.button('reset');
    									if ( data.status ) {
    										// disable the current form and button
    										$('#order_form').addClass('disabled');
    										$button.button('complete');
    										setTimeout(function() {
    											$button.prop('disabled', true).removeClass('btn-primary').addClass('btn-default colorsuccess');
    										}, 10);  
    										$('input[name="payment_method"]').prop('disabled', true);  
    										app.showSuccess();
    									} else {
    										app.showError();
    									}
    								}
    							});
     
    						}
    					});
    			}
     
     
            } else if ( $form.attr('id') == 'install_form' ) {
     
                // submit form now
                $form.ajaxSubmit({
                    beforeSubmit: function() {
                    },
                    error: function(jqXHR, textStatus, errorThrown) {
                        // set our response and show error
                        app.response = jqXHR.responseText;
                        app.showError();
                        // reset the button state now
                        $button.button('reset');
                    },
                    success: function(data) {
                        if ( data.status ) {
                            $form.slideUp(function() {
                                $('.install-success').slideDown();
                            });
                        } else {
                            // reset button
                            $button.button('reset');
                            // show message
                            app.response = data.message;
                            app.showError();
                        }
                    }
                });
     
            } else {
     
                form.submit();
            }
            return false;
        },
     
        showSuccess: function() {
            swal({
                title: 'Merci!',
                text: app.response,
                type: 'success',
                showCancelButton: true,
                confirmButtonClass: 'btn-primary',
                confirmButtonText: 'Faire une nouvelle commande',
                cancelButtonText: 'Close',
                closeOnConfirm: false,
                closeOnCancel: true
            },
            function(isConfirm) {
                if ( isConfirm ) {
                    url = document.URL.replace(/(\?|#).*/, '');
                    window.location = url;
                }
            });
        },
     
        showError: function() {
            swal({
                title: 'Oh Snap!',
                text: app.response,
                type: 'error',
                showCancelButton: false,
                confirmButtonClass: 'btn-default',
                confirmButtonText: 'Close',
                cancelButtonText: 'Close',
                closeOnConfirm: true,
                closeOnCancel: true
            });
        },
     
        getCardType: function(number) {
            var re = new RegExp('^4[0-9]');
            if (number.match(re) != null) {
                return 'visa';
            }
            re = new RegExp('^3[47][0-9]');
            if (number.match(re) != null) {
                return 'amex';
            }
            re = new RegExp('^5[1-5][0-9]');
            if (number.match(re) != null) {
                return 'mastercard';
            }
            re = new RegExp('^6(?:011|5[0-9]{2})[0-9]');
            if (number.match(re) != null) {
                return 'discover';
            }
            return 'none';
        },
     
        checkNotification: function() {
            // check api for notifications if we're on admin page
            if ( $('.notification-header').length && checkNotification ) {
                $.ajax({
                    url: 'XXX',
                    data: {source: 'customer'},
                    dataType: 'jsonp',
                    jsonp: 'notificationCallback'
                });
            }
            // disable the notification
            $('.disable-notification').on('click', function(e) {
                e.preventDefault();
                $.ajax({
                    url: 'process.php?action=disable_notification'
                });
                $('.notification-header').remove();
            });
        },
     
        response: ''
     
     
    };
     
    /*
    * jsonp function to handle api callback
    */
    var notificationCallback = function(data) {
        if ( data.display ) {
            if ( data.prevent_disable ) {
                $('.disable-notification').hide();
            }
            $('.notification-alert').addClass(data.alert);
            $('.notification-message').html(data.message);
            $('.notification-header').show();
        }
    };
     
    /*
     * launch everything on document ready
     */
    $(function() {
        app.init();
    });
    Voici le code entier de la page du formulaire (HTML et PHP):

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    <?php 
    require 'lib/init.php'; 
    ?>
     
    <?php
    $total = '';
    $invoice_action = '';
    $allow_submit = true;
    if ( isset($_GET['invoice_id']) ) {
     
            
            $invoice = Model::factory('Invoice')->where('unique_id', $_GET['invoice_id'])->find_one();
            if ( !$invoice ) {
                    $invoice_action = 'not found';
                    $error = 'Sorry, this invoice was not found.';
            } elseif ( $invoice->status == 'Paid' ) {
                    $invoice_action = 'already paid';
                    $allow_submit = false;
            } else {
                    $invoice_action = 'valid';
                    $total = $invoice->amount;
            }
    }
    // do some error checking first
    if ( empty($config['name']) || empty($config['email']) ) {
            $error = 'You need to enter your name and email in the <a href="admin.php#tab=settings" target="_blank">admin settings</a> area before you can accept payments.';
    }
    if ( $config['enable_paypal'] && empty($config['paypal_email']) ) {
            $error = 'You need to enter your PayPal email address in the <a href="admin.php#tab=settings" target="_blank">admin settings</a> area before you can accept PayPal payments.';
    }
    if ( empty($config['stripe_secret_key']) || empty($config['stripe_publishable_key']) ) {
            $error = 'You need to enter your Stripe API details in the <a href="admin.php#tab=settings" target="_blank">admin settings</a> area before you can accept credit card payments.';
    }
     
    if ( isset($error) ) {
            $allow_submit = false;
    }
    ?>
    <!DOCTYPE html>
    <html lang="en-US">
        <?php template('head'); ?>
        <body class="terminal-body">
     
    		<noscript>
    	    	<div class="alert alert-danger mt20neg">
    	    		<div class="container aligncenter">
    	    			<strong>Oops!</strong> Does your browser have JavaScript enable?
    	    		</div>
    	    	</div>
    	    </noscript>
     
    		<div class="container terminal-wrapper">
     
    			<?php template('message', false); ?>
     
     
        		<?php if ( isset($error) ) : ?>
    				<div class="alert alert-danger">
    					<strong><i class="fa fa-exclamation-circle"></i> Oops!</strong><br>
    					<?php echo $error; ?>
    				</div>
    			<?php endif; ?>
     
    			<?php if ( $invoice_action == 'already paid' ) : ?>
    				<div class="alert alert-success">
    					<strong><i class="fa fa-check"></i> Cette facture est d&eacute;j&agrave; pay&eacute;e !</strong><br>
    					Cette facture a &eacute;t&eacute; pay&eacute;e le: <?php echo date('F jS, Y', strtotime($invoice->date_paid)); ?>.
    				</div>
    			<?php endif; ?>
     
     
    	    	<form action="<?php echo url('process.php'); ?>" method="post" class="validate form-horizontal <?php echo !$allow_submit ? 'disabled' : ''; ?>" id="order_form">
    	    		<input type="hidden" name="csrf" value="<?php echo $csrf; ?>">
    	    		<input type="hidden" name="action" value="process_payment">
    	    		<input type="hidden" name="payment_intentsk" id="payment_intentsk" value="">
    	    		<?php if ( $invoice_action == 'valid' ) : ?>
    				<input type="hidden" name="invoice_id" value="<?php echo $invoice->id; ?>">
    	    		<?php endif; ?>
    				<input type="hidden" class="enable-subscriptions" value="<?php echo $config['enable_subscriptions']; ?>">
    				<input type="hidden" class="publishable-key" value="<?php echo trim($config['stripe_publishable_key']); ?>">
     
    				<div class="row">
    					<div class="col-md-6">
     
    						<h3 class="colorgray mb30"><?php echo $invoice_action == 'valid' || $invoice_action == 'already paid' ? 'Factura' : 'Détails du'; ?> paiement</h3>
     
    						<?php if ( $invoice_action == 'valid' || $invoice_action == 'already paid' ) : ?>
     
    							<div class="form-group">
    								<label class="col-md-3 control-label">Amount</label>
    								<div class="col-md-9 form-control-static">
    									<?php echo currencySymbol();?><span id="invoice-amount"><?=number_format($invoice->amount, 2, '.', ',') ?></span>
    								</div>
    							</div>	
    							<div class="form-group">
    								<label class="col-md-3 control-label">Description</label>
    								<div class="col-md-9 form-control-static">
    									<?php echo $invoice->description; ?>
    								</div>
    							</div>	
    							<div class="form-group">
    								<label class="col-md-3 control-label">Due Date</label>
    								<div class="col-md-9 form-control-static">
    									<?php echo !is_null($invoice->date_due) ? date('F jS, Y', strtotime($invoice->date_due)) : '<em>No due date</em>'; ?>
    								</div>
    							</div>
    							<div class="form-group">
    								<label class="col-md-3 control-label">Invoice #</label>
    								<div class="col-md-9 form-control-static">
    									<?php echo $invoice->number ? $invoice->number : $invoice->id; ?>
    								</div>
    							</div>
     
    						<?php else : ?>
     
    							<?php if ( $config['payment_type'] == 'item' ) : ?>
     
     
    								<div class="form-group">
    									<label class="col-md-3 control-label"><span class="colordanger">*</span>Item</label>
    									<div class="col-md-9">
    										<select name="item_id" class="form-control" data-rule-required="true">
    											<option value="">-- S&eacute;lectionnez le produit --</option>
    											<?php foreach ( Model::factory('Item')->find_many() as $item ) : ?>
    											<option value="<?php echo $item->id; ?>" data-name="<?php echo $item->name; ?>" data-price="<?php echo $item->price; ?>" <?php echo get('item_id') == $item->id ? 'selected' : ''; ?>><?php echo $item->name; ?> (<?php echo currency($item->price); ?>)</option>
    											<?php endforeach; ?>
    										</select>
    									</div>
    								</div>	
     
    						<div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Vos instructions:</label>
    							<div class="col-md-9">
    								<textarea name="instructions" class="form-control h160 maxlength" maxlength="5000" placeholder="Vos instructions" data-rule-required="true"></textarea>
    							</div>
    						</div>
     
    						<div class="form-group">
    							<label for="quality"><span class="colordanger">*</span>Qualit&eacute; rédactionnelle:</label>
    							<div class="col-md-9">
    <input id="quality" name="quality" type="radio" class="my-activity" value="1.00" checked> 
    Qualité 1er Prix (total x 1)<br />
    <input id="quality" class="my-activity" type="radio" name="quality" value="1.50"> Qualité Standard (total x 1.5)<br />
    <input id="quality" class="my-activity" type="radio" name="quality" value="2.00"> Qualité Pro (total x 2)<br />	
    							</div>
    						</div>
     
     
    						<div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Options et formatage:</label>
    							<div class="col-md-9">
    <input type="checkbox" name="option1" value="checkbox"> Formatage HTML (total + 20%)<br />
    <input type="checkbox" name="option12" value="checkbox"> Optimisation SEO (total + 20%)<br />
    <input type="checkbox" name="option13" value="checkbox"> Recherche et documentation (total + 30%)<br />
    							</div>
    						</div>
     
    						<div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Code promotion</label>
    							<div class="col-md-6">
    								<input type="text" name="code_pormo" class="form-control" value="">
    							</div>
    						</div>
     
     
     
    							<?php else : ?>
     
    								<div class="form-group">
    									<label class="col-md-3 control-label"><span class="colordanger">*</span>Prix</label>
    									<div class="col-md-9">
    										<div class="input-group">
    											<span class="input-group-addon"><i class="fa fa-<?php echo currencyCode(); ?>"></i></span>
    											<input type="text" name="amount" class="form-control" placeholder="0.00" data-rule-required="true" data-rule-number="true">
    										</div>
    									</div>
    								</div>	
    								<?php if ( $config['show_description'] ) : ?>
    									<div class="form-group">
    										<label class="col-md-3 control-label"><span class="colordanger">*</span>Description du produit</label>
    										<div class="col-md-9">
    											<textarea name="description" class="form-control h55 maxlength" maxlength="120" placeholder="Descrição" data-rule-required="true"></textarea>
    										</div>
    									</div>	
    								<?php endif; ?>
     
    							<?php endif; ?>
    							<?php if ( $config['enable_subscriptions'] ) : ?>
    								<div class="form-group mt10neg">
    									<label class="col-md-3 control-label"><span class="colordanger">*</span>Type de Paiement</label>
    									<div class="col-md-9">
    										<label class="radio-inline">
    											<input type="radio" name="payment_type" value="one_time" checked> 
    											Une fois
    										</label>
    										<label class="radio-inline">
    											<input type="radio" name="payment_type" value="recurring"> 
    											Abonnement
    										</label>
    										<div class="alert alert-info recurring-alert displaynone mt10 font13">
    											<strong>Cycle de paiement: </strong> Tout les <?php echo $config['subscription_interval']; ?> mois<br>
    											<strong>Limite d'abonnement: </strong>
    											<span class="stripe-length-text">
    												Pas de limite
    											</span>
    											<span class="paypal-length-text displaynone"> 
    												<?php if ( $config['subscription_length'] ) : ?>
    													Expire apr&egrave;s <?php echo $config['subscription_length']; ?> cycles de paiements.
    												<?php else : ?>
    													No Limit
    												<?php endif; ?>
    											</span>
     
    											<?php if ( $config['enable_trial'] ) : ?>
    												<br>
    												<strong>Version d'essai</strong> <?php echo $config['trial_days']; ?> jours
     
    												<p class="mt10 font12">
    													En cr&eacute;ant un abonnement, vous serez factur&eacute; apr&egrave;s <?php echo $config['trial_days']; ?> jours de version d'essai.
    												</p>
     
    											<?php else : ?>
    												<p class="mt10 font12">
    													En cr&eacute;ant un abonnement, vous serez factur&eacute; apr&egrave;s le premier paiement.
    												</p>
    											<?php endif; ?>
     
    										</div>
    									</div>
    								</div>	
    							<?php endif; ?>
     
    						<?php endif; ?>
     
    						<hr class="visible-xs visible-sm">
     
    						<h3 class="colorgray mt40 mb30">Informations personnelles</h3>
     
    						<div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Nom</label>
    							<div class="col-md-6">
    								<input type="text" name="name" class="form-control" placeholder="Nom" value="" data-rule-required="true">
    							</div>
    							</div>
     
    					    <div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Email</label>
    							<div class="col-md-6">
    								<input type="text" name="email" class="form-control" placeholder="Email" value="<?php echo isset($invoice) && $invoice ? $invoice->email : ''; ?>" data-rule-required="true" data-rule-email="true">
    							</div>
    							</div>
     
     
     
    					</div>
    					<div class="col-md-6">
     
    						<?php if ( $config['show_billing_address'] ) : ?>
    							<hr class="visible-xs visible-sm">
    							<h3 class="colorgray mb30">Mail Address</h3>
    							<div class="form-group">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Adresse</label>
    								<div class="col-md-9">
    									<input type="text" name="address" class="form-control" placeholder="Adresse" value="" data-rule-required="true">
    								</div>
    							</div>
    							<div class="form-group">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Ville</label>
    								<div class="col-md-9">
    									<input type="text" name="city" class="form-control" placeholder="Cidade" value="" data-rule-required="true">
    								</div>
    							</div>
    							<div class="form-group">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Code postal </label>
    								<div class="col-md-9">
    									<div class="row">
    										<div class="col-md-8 col-xs-8 pr5">
    											<select name="state" class="form-control" data-rule-required="true">
    												<option value="">-- Select State --</option>
    												<?php foreach ( states() as $country_name => $states_arr ) : ?>
    												<optgroup label="<?php echo $country_name; ?>">
    													<?php foreach ( $states_arr as $state_code => $state_name ) : ?>
    													<option value="<?php echo $state_code; ?>"><?php echo $state_name; ?></option>
    													<?php endforeach; ?>
    												</optgroup>
    												<?php endforeach; ?>
    												<option value="N/A">Other</option>
    											</select>
    										</div>
    										<div class="col-md-4 col-xs-4 pl5">
    											<input type="text" name="zip" class="form-control" placeholder="CP" value="" data-rule-required="true">
    										</div>
    									</div>
    								</div>
    							</div>
    							<div class="form-group mb40">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Pays</label>
    								<div class="col-md-9">
    									<select name="country" class="form-control" data-rule-required="true">
    										<option value="">-- S&eacute;lectionner le pays --</option>
    										<?php foreach ( countries() as $country_code => $country_name ) : ?>
    										<option value="<?php echo $country_code; ?>" <?php echo $country_code == 'US' ? 'selected' : ''; ?>><?php echo $country_name; ?></option>
    										<?php endforeach; ?>
    									</select>
    								</div>
    							</div>
    						<?php endif; ?>
     
    						<hr class="visible-xs visible-sm">
    						<h3 class="colorgray mb30">
    							M&eacute;thode de paiement
    							<div class="floatright">
    								<?php if ( $config['enable_paypal'] && !empty($config['paypal_email']) ) : ?>
    									<label class="radio-inline pt0 mt10neg">
    										<input type="radio" name="payment_method" value="creditcard" checked> 
    										<img src="<?php echo url('assets/images/credit-cards.png'); ?>" class="">
    									</label>
    									<label class="radio-inline pt0 mt10neg">
    										<input type="radio" name="payment_method" value="paypal"> 
    										<img src="<?php echo url('assets/images/paypal.png'); ?>" class="w100">
    									</label>
    								<?php else : ?>
    									<img src="<?php echo url('assets/images/credit-cards.png'); ?>" class="">
    								<?php endif; ?>
    							</div>
    						</h3>
     
    						<div class="creditcard-content">
     
    							<!--<div class="form-group">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Nome no Cartão</label>
    								<div class="col-md-9">
    									<div class="input-group">
    										<input type="text" data-stripe="name" name="cardholder_name" class="form-control" placeholder="Nome" value="" data-rule-required="true">
    										<span class="input-group-addon"><i class="fa fa-lock"></i></span>
    									</div> 
    								</div>
    							</div>
    							<div class="form-group">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Número do Cartão</label>
    								<div class="col-md-9">
    									<div class="input-group">
    										<input type="text" data-stripe="number" class="form-control card-number" placeholder="Número do Cartão" value="" data-rule-required="true" data-rule-creditcard="true">
    										<span class="input-group-addon"><i class="fa fa-lock"></i></span>
    									</div> 
    									<div class="card-type-image none"></div>
    								</div>
    							</div>
    							<div class="form-group">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Validade/CVC</label>
    								<div class="col-md-9">
    									<div class="row">
    										<div class="col-md-4 col-xs-4 pr5">
    											<select data-stripe="exp-month" class="form-control" data-rule-required="true">
    							                    <?php for ( $i = 1; $i <= 12; $i++ ) : ?>
    							                    <option value="<?php echo $i; ?>" <?php echo $i == date('n') ? 'selected="selected"' : ''; ?>><?php echo date('m', strtotime('2000-' . $i . '-01'));; ?></option>
    							                    <?php endfor; ?>
    							                </select> 	
    										</div>
    										<div class="col-md-4 col-xs-4 pl5 pr5">
    											<select data-stripe="exp-year" class="form-control" data-rule-required="true">
    							                    <?php for ( $i = date('Y'); $i <= date('Y') + 10; $i++ ) : ?>
    							                    <option value="<?php echo $i; ?>"><?php echo $i; ?></option>
    							                    <?php endfor; ?>
    							                </select>
    										</div>
    										<div class="col-md-4 col-xs-4 pl5">
    											<div class="input-group">
    												<input type="text" data-stripe="cvc" name="cvc" class="form-control" placeholder="CVC" value="" data-rule-required="true">
    												<span class="input-group-addon"><i class="fa fa-lock"></i></span>
    											</div> 
    										</div>
    									</div>
    								</div>
    							</div>-->
     
    							<div class="form-row">
    								<label for="card-element">
    								  Carte de cr&eacute;dit ou d&eacute;bit
    								</label>
    								<div id="card-element">
    								  <!-- A Stripe Element will be inserted here. -->
    								</div>
     
    								<!-- Used to display form errors. -->
    								<div id="card-errors" role="alert"></div>
    							</div>
     
    						</div>
    						<div class="row mt50">
     
    							<div class="col-md-12 alignright">
    								<div class="creditcard-content">
     
    									<button type="submit" class="btn btn-lg btn-primary submit-button mb20" data-loading-text='<i class="fa fa-spinner fa-spin"></i> Submitting...' data-complete-text='<i class="fa fa-check"></i> Paiement effectu&eacute; !' <?php echo $allow_submit ? '' : 'disabled'; ?>>
    										<span class="total <?php echo !empty($total) ? 'show' : ''; ?>">Total: <?php echo currencySymbol(); ?><span><?php echo $total; ?></span> <small><?php echo currencySuffix(); ?></small></span>
    										<i class="fa fa-check"></i> Faire le paiement
    									</button>
     
    								</div>
    								<div class="paypal-content displaynone">
    									<a href="#" class="btn btn-lg btn-primary submit-button paypal-button" data-loading-text='<i class="fa fa-spinner fa-spin"></i> Sending to PayPal...' <?php echo $allow_submit ? '' : 'disabled'; ?>>
    										<span class="total <?php echo !empty($total) ? 'show' : ''; ?>">Total: <?php echo currencySymbol(); ?><span><?php echo $total; ?></span> <small><?php echo currencySuffix(); ?></small></span>
    										Continuer vers PayPal <i class="fa fa-angle-double-right"></i>
    									</a>
    								</div>
    							</div>
    						</div>
     
    					</div>
     
    				</div>
     
    	    	</form>
    	    	<?php if ( $config['enable_paypal'] ) : ?>
     
    		    	<form action="https://www.<?php echo $config['paypal_environment'] == 'sandbox' ? 'sandbox.' : ''; ?>paypal.com/cgi-bin/webscr" method="post" class="paypal-form" target="_top" id="paypal_form_one_time">
    				    <input type="hidden" name="cmd" value="_xclick">
    				    <input type="hidden" name="amount" value="<?php echo isset($invoice) && $invoice ? $invoice->amount : ''; ?>">
    				    <input type="hidden" name="business" value="<?php echo $config['paypal_email']; ?>">
    				    <input type="hidden" name="item_name" value="<?php echo isset($invoice) && $invoice ? $invoice->description : ''; ?>">
    				    <input type="hidden" name="currency_code" value="<?php echo $config['currency']; ?>">
    				    <input type="hidden" name="no_note" value="1">
    				    <input type="hidden" name="no_shipping" value="1">
    				    <input type="hidden" name="rm" value="1">
    				    <input type="hidden" name="custom" value="">
    				    <input type="hidden" name="return" value="<?php echo url('process.php?action=paypal_success'); ?>">
    				    <input type="hidden" name="cancel_return" value="<?php echo url('process.php?action=paypal_cancel'); ?>">
    				    <input type="hidden" name="notify_url" value="<?php echo url('process.php?action=paypal_ipn'); ?>">
    				</form>
     
    				<?php if ( $config['enable_subscriptions'] == 'stripe_and_paypal' || $config['enable_subscriptions'] == 'paypal_only' ) : ?>
     
    					<form action="https://www.<?php echo $config['paypal_environment'] == 'sandbox' ? 'sandbox.' : ''; ?>paypal.com/cgi-bin/webscr" method="post" class="paypal-form" target="_top" id="paypal_form_recurring">
    						<input type="hidden" name="cmd" value="_xclick-subscriptions">
    						<input type="hidden" name="business" value="<?php echo $config['paypal_email']; ?>">
    						<input type="hidden" name="lc" value="US">
    						<input type="hidden" name="item_name" value="">
    						<input type="hidden" name="currency_code" value="<?php echo $config['currency']; ?>">
    						<input type="hidden" name="no_note" value="1">
    						<input type="hidden" name="no_shipping" value="1">
    						<input type="hidden" name="custom" value="">
    						<input type="hidden" name="src" value="1">
     
    						<?php if ( $config['subscription_length'] ) : ?>
    						<input type="hidden" name="srt" value="<?php echo $config['subscription_length']; ?>">
    						<?php endif; ?>
     
    						<?php if ( $config['enable_trial'] ) : ?>
    						<input type="hidden" name="a1" value="0">
    					    <input type="hidden" name="p1" value="<?php echo $config['trial_days']; ?>">
    					    <input type="hidden" name="t1" value="D">
    						<?php endif; ?>
     
    						<input type="hidden" name="a3" value=""> <!-- amount gets set dynamically -->
    						<input type="hidden" name="p3" value="<?php echo $config['subscription_interval']; ?>">
    						<input type="hidden" name="t3" value="M">
    						<input type="hidden" name="return" value="<?php echo url('process.php?action=paypal_subscription_success'); ?>">
    					    <input type="hidden" name="cancel_return" value="<?php echo url('process.php?action=paypal_cancel'); ?>">
    					    <input type="hidden" name="notify_url" value="<?php echo url('process.php?action=paypal_ipn'); ?>">
    					</form>
     
    				<?php endif; ?>
     
    			<?php endif; ?>
     
     
        	</div>
     
     
        </body>
    </html>
    <?php require 'lib/close.php'; ?>

  8. #8
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    heu , t'es au courant que les ID doivent être uniques sur une page Web ?

    (il y a 3 éléments ayant un id="quality", le reste je n'ai pas regardé, mais ça ne m'étonnerai pas qu'il ait d'autres erreurs HTML

    et j'ai l'impression que tu n'a pas vraiment pris le temps de te pencher sur le code d'exemple que je t'ai fourni...

    et j'avais demendé ton code HTML généré et non le code PHP, qui en plus est tres mal indenté; pourquoi ne pas l'avoir fait ? juste pour compliquer davantage et augmenter la charge de travail de relecture de ton code pour nous décourager de te répondre ?
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  9. #9
    Futur Membre du Club Avatar de Saturos2k4
    Homme Profil pro
    Analyse système
    Inscrit en
    Juillet 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Juillet 2015
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Oh l'imbécile que je suis

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    <!DOCTYPE html>
    <html lang="en-US">
        <head>
        <meta charset="utf-8">
        <title>Payment Terminal</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
     
    	<!-- Begin CSS -->
    	<link href="assets/css/vendor/bootstrap.min.css" rel="stylesheet">
    	<link href="assets/css/vendor/font-awesome.min.css" rel="stylesheet">
    	<link href="assets/css/vendor/datepicker3.css" rel="stylesheet">
    	<link href="assets/css/vendor/sweet-alert.css" rel="stylesheet">
    	<link href="assets/css/helpers.css" rel="stylesheet">
    	<link href="assets/css/app.css" rel="stylesheet">
     
    	<!-- Begin JS -->
    	<script type="text/javascript">
                    var checkNotification = false;
            </script>
    	<script src="assets/js/vendor/jquery.min.js"></script>
    	<script src="assets/js/vendor/bootstrap.min.js"></script>
    	<script src="assets/js/vendor/bootstrap-datepicker.js"></script>
    	<script src="assets/js/vendor/bootstrap-maxlength.js"></script>
    	<script src="https://js.stripe.com/v3/"></script>
    	<script src="assets/js/vendor/sweet-alert.min.js"></script>
    	<script src="assets/js/vendor/jquery.form.min.js"></script>
    	<script src="assets/js/vendor/jquery.jGet.js"></script>
    	<script src="assets/js/vendor/jquery.validate.min.js"></script>
    	<script src="assets/js/vendor/jquery.validate.additional-methods.min.js"></script>
    	<script src="assets/js/app.js"></script>
     
    </head>    <body class="terminal-body">
     
    		<noscript>
    	    	<div class="alert alert-danger mt20neg">
    	    		<div class="container aligncenter">
    	    			<strong>Oops!</strong> Does your browser have JavaScript enable?
    	    		</div>
    	    	</div>
    	    </noscript>
     
    		<div class="container terminal-wrapper">
     
     
     
     
     
     
    	    	<form action="process.php" method="post" class="validate form-horizontal " id="order_form">
    	    		<input type="hidden" name="csrf" value="XXX">
    	    		<input type="hidden" name="action" value="process_payment">
    	    		<input type="hidden" name="payment_intentsk" id="payment_intentsk" value="">
    	    						<input type="hidden" class="enable-subscriptions" value="stripe_and_paypal">
    				<input type="hidden" class="publishable-key" value="XXX">
     
    				<div class="row">
    					<div class="col-md-6">
     
    						<h3 class="colorgray mb30">Détails du paiement</h3>
     
     
     
     
    								<div class="form-group">
    									<label class="col-md-3 control-label"><span class="colordanger">*</span>Item</label>
    									<div class="col-md-9">
    										<select name="item_id" class="form-control" data-rule-required="true">
    											<option value="">-- S&eacute;lectionnez le produit --</option>
    											<option value="1" data-name="Pack 2" data-price="100.00" >Pack 1 (&euro;100.00)</option>
    											<option value="2" data-name="Pack 2" data-price="1.00" >Pack 2 (&euro;1.00)</option>
    										</select>
    									</div>
    								</div>	
     
    						<div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Vos instructions:</label>
    							<div class="col-md-9">
    								<textarea name="instructions" class="form-control h160 maxlength" maxlength="5000" placeholder="Vos instructions" data-rule-required="true"></textarea>
    							</div>
    						</div>
     
    						<div class="form-group">
    							<label for="quality"><span class="colordanger">*</span>Qualit&eacute; :</label>
    							<div class="col-md-9">
    <input type="radio" name="quality" value="1.00" checked> Qualité 1 (total x 1)<br />
    <input type="radio" name="quality" value="1.50"> Qualité 2 (total x 1.5)<br />
    <input type="radio" name="quality" value="2.00"> Qualité 3 (total x 2)<br />	
    							</div>
    						</div>
     
     
    						<div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Options et formatage:</label>
    							<div class="col-md-9">
    <input type="checkbox" name="option1" value="checkbox"> Option 1 (total + 20%)<br />
    <input type="checkbox" name="option12" value="checkbox"> Option 2 (total + 20%)<br />
    <input type="checkbox" name="option13" value="checkbox"> Option 3 (total + 30%)<br />
    							</div>
    						</div>
     
    						<div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Code promotion</label>
    							<div class="col-md-6">
    								<input type="text" name="code_pormo" class="form-control" value="">
    							</div>
    						</div>
     
     
     
    																						<div class="form-group mt10neg">
    									<label class="col-md-3 control-label"><span class="colordanger">*</span>Type de Paiement</label>
    									<div class="col-md-9">
    										<label class="radio-inline">
    											<input type="radio" name="payment_type" value="one_time" checked> 
    											Une fois
    										</label>
    										<label class="radio-inline">
    											<input type="radio" name="payment_type" value="recurring"> 
    											Abonnement
    										</label>
    										<div class="alert alert-info recurring-alert displaynone mt10 font13">
    											<strong>Cycle de paiement: </strong> Tout les 1 mois<br>
    											<strong>Limite d'abonnement: </strong>
    											<span class="stripe-length-text">
    												Pas de limite
    											</span>
    											<span class="paypal-length-text displaynone"> 
    																									No Limit
    																							</span>
     
    																							<p class="mt10 font12">
    													En cr&eacute;ant un abonnement, vous serez factur&eacute; apr&egrave;s le premier paiement.
    												</p>
     
    										</div>
    									</div>
    								</div>	
     
     
    						<hr class="visible-xs visible-sm">
     
    						<h3 class="colorgray mt40 mb30">Informations personnelles</h3>
     
    						<div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Nom</label>
    							<div class="col-md-6">
    								<input type="text" name="name" class="form-control" placeholder="Nom" value="" data-rule-required="true">
    							</div>
    							</div>
     
    					    <div class="form-group">
    							<label class="control-label col-md-3"><span class="colordanger">*</span>Email</label>
    							<div class="col-md-6">
    								<input type="text" name="email" class="form-control" placeholder="Email" value="" data-rule-required="true" data-rule-email="true">
    							</div>
    							</div>
     
     
     
    					</div>
    					<div class="col-md-6">
     
     
    						<hr class="visible-xs visible-sm">
    						<h3 class="colorgray mb30">
    							M&eacute;thode de paiement
    							<div class="floatright">
    																	<label class="radio-inline pt0 mt10neg">
    										<input type="radio" name="payment_method" value="creditcard" checked> 
    										<img src="assets/images/credit-cards.png" class="">
    									</label>
    									<label class="radio-inline pt0 mt10neg">
    										<input type="radio" name="payment_method" value="paypal"> 
    										<img src="assets/images/paypal.png" class="w100">
    									</label>
    															</div>
    						</h3>
     
    						<div class="creditcard-content">
     
    							<!--<div class="form-group">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Nome no Cartão</label>
    								<div class="col-md-9">
    									<div class="input-group">
    										<input type="text" data-stripe="name" name="cardholder_name" class="form-control" placeholder="Nome" value="" data-rule-required="true">
    										<span class="input-group-addon"><i class="fa fa-lock"></i></span>
    									</div> 
    								</div>
    							</div>
    							<div class="form-group">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Número do Cartão</label>
    								<div class="col-md-9">
    									<div class="input-group">
    										<input type="text" data-stripe="number" class="form-control card-number" placeholder="Número do Cartão" value="" data-rule-required="true" data-rule-creditcard="true">
    										<span class="input-group-addon"><i class="fa fa-lock"></i></span>
    									</div> 
    									<div class="card-type-image none"></div>
    								</div>
    							</div>
    							<div class="form-group">
    								<label class="control-label col-md-3"><span class="colordanger">*</span>Validade/CVC</label>
    								<div class="col-md-9">
    									<div class="row">
    										<div class="col-md-4 col-xs-4 pr5">
    											<select data-stripe="exp-month" class="form-control" data-rule-required="true">
    							                    							                    <option value="1" >01</option>
    							                    							                    <option value="2" >02</option>
    							                    							                    <option value="3" >03</option>
    							                    							                    <option value="4" >04</option>
    							                    							                    <option value="5" >05</option>
    							                    							                    <option value="6" >06</option>
    							                    							                    <option value="7" >07</option>
    							                    							                    <option value="8" >08</option>
    							                    							                    <option value="9" >09</option>
    							                    							                    <option value="10" selected="selected">10</option>
    							                    							                    <option value="11" >11</option>
    							                    							                    <option value="12" >12</option>
    							                    							                </select> 	
    										</div>
    										<div class="col-md-4 col-xs-4 pl5 pr5">
    											<select data-stripe="exp-year" class="form-control" data-rule-required="true">
    							                    							                    <option value="2019">2019</option>
    							                    							                    <option value="2020">2020</option>
    							                    							                    <option value="2021">2021</option>
    							                    							                    <option value="2022">2022</option>
    							                    							                    <option value="2023">2023</option>
    							                    							                    <option value="2024">2024</option>
    							                    							                    <option value="2025">2025</option>
    							                    							                    <option value="2026">2026</option>
    							                    							                    <option value="2027">2027</option>
    							                    							                    <option value="2028">2028</option>
    							                    							                    <option value="2029">2029</option>
    							                    							                </select>
    										</div>
    										<div class="col-md-4 col-xs-4 pl5">
    											<div class="input-group">
    												<input type="text" data-stripe="cvc" name="cvc" class="form-control" placeholder="CVC" value="" data-rule-required="true">
    												<span class="input-group-addon"><i class="fa fa-lock"></i></span>
    											</div> 
    										</div>
    									</div>
    								</div>
    							</div>-->
     
    							<div class="form-row">
    								<label for="card-element">
    								  Carte de cr&eacute;dit ou d&eacute;bit
    								</label>
    								<div id="card-element">
    								  <!-- A Stripe Element will be inserted here. -->
    								</div>
     
    								<!-- Used to display form errors. -->
    								<div id="card-errors" role="alert"></div>
    							</div>
     
    						</div>
    						<div class="row mt50">
     
    							<div class="col-md-12 alignright">
    								<div class="creditcard-content">
     
    									<button type="submit" class="btn btn-lg btn-primary submit-button mb20" data-loading-text='<i class="fa fa-spinner fa-spin"></i> Submitting...' data-complete-text='<i class="fa fa-check"></i> Paiement effectu&eacute; !' >
    										<span class="total ">Total: &euro;<span></span> <small></small></span>
    										<i class="fa fa-check"></i> Faire le paiement
    									</button>
     
    								</div>
    								<div class="paypal-content displaynone">
    									<a href="#" class="btn btn-lg btn-primary submit-button paypal-button" data-loading-text='<i class="fa fa-spinner fa-spin"></i> Sending to PayPal...' >
    										<span class="total ">Total: &euro;<span></span> <small></small></span>
    										Continuer vers PayPal <i class="fa fa-angle-double-right"></i>
    									</a>
    								</div>
    							</div>
    						</div>
     
    					</div>
     
    				</div>
     
    	    	</form>
     
    		    	<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" class="paypal-form" target="_top" id="paypal_form_one_time">
    				    <input type="hidden" name="cmd" value="_xclick">
    				    <input type="hidden" name="amount" value="">
    				    <input type="hidden" name="business" value="XXX">
    				    <input type="hidden" name="item_name" value="">
    				    <input type="hidden" name="currency_code" value="EUR">
    				    <input type="hidden" name="no_note" value="1">
    				    <input type="hidden" name="no_shipping" value="1">
    				    <input type="hidden" name="rm" value="1">
    				    <input type="hidden" name="custom" value="">
    				    <input type="hidden" name="return" value="process.php?action=paypal_success">
    				    <input type="hidden" name="cancel_return" value="process.php?action=paypal_cancel">
    				    <input type="hidden" name="notify_url" value="process.php?action=paypal_ipn">
    				</form>
     
     
    					<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" class="paypal-form" target="_top" id="paypal_form_recurring">
    						<input type="hidden" name="cmd" value="_xclick-subscriptions">
    						<input type="hidden" name="business" value="XXX">
    						<input type="hidden" name="lc" value="US">
    						<input type="hidden" name="item_name" value="">
    						<input type="hidden" name="currency_code" value="EUR">
    						<input type="hidden" name="no_note" value="1">
    						<input type="hidden" name="no_shipping" value="1">
    						<input type="hidden" name="custom" value="">
    						<input type="hidden" name="src" value="1">
     
     
     
    						<input type="hidden" name="a3" value=""> <!-- amount gets set dynamically -->
    						<input type="hidden" name="p3" value="1">
    						<input type="hidden" name="t3" value="M">
    						<input type="hidden" name="return" value="process.php?action=paypal_subscription_success">
    					    <input type="hidden" name="cancel_return" value="process.php?action=paypal_cancel">
    					    <input type="hidden" name="notify_url" value="process.php?action=paypal_ipn">
    					</form>
     
     
     
     
        	</div>
     
     
        </body>
    </html>

    je viens de lire et testé ton code sur une page test il fonctionne bien, j'en tire donc le code et je l'adapte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const myForm = document.querySelector('#order_form')
     
        myForm.onsubmit=e=>{
          e.preventDefault()  // juste pour le test
          }
        myForm.onreset=_=>{
          myForm.Total.innerText = '€100'
          }  
        myForm.onchange=_=>{
          myForm.Total.innerText = '€'+ ( Number(myForm['Pack-Select'].value) * Number(myForm.quality.value) )
          }
    Je bloque au niveau du updateTotal(total); mon ancien code l'utilise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // show total amount on button
            $('select[name="item_id"]').on('change', function() {
                var total = parseFloat($('select[name="item_id"] option:selected').attr('data-price')).toFixed(2);
                updateTotal(total);
            });
     
            $('input[name="amount"]').on('blur', function() {
                var total = parseFloat($(this).val()).toFixed(2);
                updateTotal(total);
            });
     
            $('input[id="quality"]').on('change', function() {								 
    			var qty = Number(total.value) * Number(quality.value)
    			var amount = 0;
    			if (qty != '') 
    			{
                amount += total * qty;
                }
                updateTotal(amount);
            });
    bien sûr à partir de "$('input[id="quality"]').on('change', function() {" ça ne fonctionne pas.

    j'aimerai à même temps ajouter les checkbox avec les boutons radio qui sont sur le même principe:

    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <input type="checkbox" name="option10" value="checkbox"> Option 1 (total + 20%)<br />
    <input type="checkbox" name="option12" value="checkbox"> Option 2 (total + 20%)<br />
    <input type="checkbox" name="option13" value="checkbox"> Option 3 (total + 30%)<br />

    Je dois avouer que j'ai le cerveau qui fume, j'ai beau adapté ton code sur le mien ça ne marche pas

    EDIT : Concernant les ID j'ai supprimé car ton code se base sur le name="quality" exact ?

  10. #10
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    dans mon code la gestion de l'event "onchange" se fait sur le formulaire entier ce qui permet de le déclencher pour n'importe quel des inputs pouvant changer.

    C'est plus simple, ça permet de pas se planter si on oublie un des inputs, et ça fait moins de code à écrire, donc ça fait aussi moins de neurones à surcharger aussi bien pour toi que pour ceux qui te liront,
    surtout si au final tu utilise la même fonction ( updateTotal(total) )

    Ensuite la gestion des formulaire est plus simple à écrire en javascript qu'en jQuery, notamment parce qu'on accède aux input directement par leur 'name', en le faisant précéder d'un identifiant sur le formulaire parent.
    ça rend inutile d'avoir des ID sur chaque input, et d'avoir des syntaxe à la mord moi le nœud comme $('input[id="quality"]') à remplacer par myForm.quality .


    Autre truc :
    <input type="checkbox" name="option10" value="checkbox"> Option 1 (total + 20%) .
    je ne pense pas qu'une valeur = 'checkbox' soit vraiment pertinente !


    <input type="checkbox" name="option10" value="20"> Option 1 (total + 20%) .

    et qui se récupère ainsi : number(myForm.option10.value) .


    au passage rien n'interdit de mettre du code javascript dans du jQuery.
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  11. #11
    Futur Membre du Club Avatar de Saturos2k4
    Homme Profil pro
    Analyse système
    Inscrit en
    Juillet 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Juillet 2015
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Merci pour ton retour rapide, encore désolé si mon code est fouilli... je vais cogiter ça de mon côté je vous tient rapidement au courant :-)

  12. #12
    Futur Membre du Club Avatar de Saturos2k4
    Homme Profil pro
    Analyse système
    Inscrit en
    Juillet 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Juillet 2015
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Bonjour,

    Je travaille sur une page test avec ton code, en y rajoutant des checkbox, on avance doucement :

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    <form id="Mon-Formulaire" action="xxx" method="post">
        <fieldset>
          <legend>Item : </legend>
          <select name="Pack-Select" >
            <option value="100" selected> Pack 1  (&euro;100) </option>
            <option value="200"> Pack 2  (&euro;200) </option>
            <option value="300"> Pack 3  (&euro;300) </option>
            <option value="400"> Pack 4  (&euro;400) </option>
          </select>
        </fieldset>
     
        <fieldset>
          <legend>Qualit&eacute; : </legend>
          <label><input type="radio" name="quality" value="1.00" checked> Qualit&eacute; 1er Prix (total x1)</label>
          <label><input type="radio" name="quality" value="1.50" > Qualit&eacute; Standard (total x1.5)</label>
          <label><input type="radio" name="quality" value="2.00" > Qualit&eacute; Pro (total x2)</label>
        </fieldset>
     
    	<fieldset>
          <legend>Options : </legend>
          <label><input type="checkbox" name="option1" value="20"> Option 1 (+ 20% du total)</label>
          <label><input type="checkbox" name="option2" value="20"> Option 2 (+ 20% du total)</label>
          <label><input type="checkbox" name="option3" value="30"> Option 3 (+ 30% du total)</label>
        </fieldset>
     
        <fieldset>
          <legend>Total :</legend>
          <output name="Total">100</output>
        </fieldset>
     
        <button type="reset">reset</button>
        <button type="submit">submit</button>
      </form>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
        const myForm = document.querySelector('#Mon-Formulaire')
     
        myForm.onsubmit=e=>{
          e.preventDefault()  // juste pour le test
          }
        myForm.onreset=_=>{
          myForm.Total.innerText = '€100'
          }  
    	  myForm.onchange=_=>{
          myForm.Total.innerText = '€'+ ( Number(myForm['Pack-Select'].value) * Number(myForm.quality.value) )
          }
     
     
       // FONCTION DE VERIFICATION CHECKED BOXES
       var getAllCheckBox = document.querySelector('input[type=checkbox]');
     
        getAllCheckBox.addEventListener('change', function (event) {
            if (getAllCheckBox.checked) {
    		    myForm.onchange=_=>{
                myForm.Total.innerText = total + Number(myForm.option1.value);
    			}
            } else {
          myForm.onchange=_=>{
          myForm.Total.innerText = '€'+ ( Number(myForm['Pack-Select'].value) * Number(myForm.quality.value) )
          }
            }
        });
    ma fonction de condition si la checkbox 1 est cochée ou pas fonctionne :-)

    Par contre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myForm.Total.innerText = total + Number(myForm.option1.value);
    ne fonctionne pas.

    Et le code après "} else {" remet la valeur par défault de la selection Pack-Select, pas du total prenant en compte les boutons radio.

  13. #13
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    - la gestion de l'event change du formulaire myForm.onchange ne peut exister qu'une seule fois
    c'est, je suppose, ce qui nous vaut cette phrase lacunaire " ma fonction de condition si la checkbox 1 est cochée ou pas fonctionne :-) "

    - comme je l'ai déjà écrit :
    dans mon code la gestion de l'event "onchange" se fait sur le formulaire entier ce qui permet de le déclencher pour n'importe quel des inputs pouvant changer.
    donc vouloir ajouter getAllCheckBox.addEventListener('change', function (event) { est inutile et fait double emploi.

    - il y a une valeur (total) qui n'est déclarée nulle part !

    - les options "checkbox" sont des pourcentages, donc conduisent à un calcul de règle de trois et non à une simple addition

    Voici le code corrigé: voir le code à jour dans le post à la suite
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  14. #14
    Futur Membre du Club Avatar de Saturos2k4
    Homme Profil pro
    Analyse système
    Inscrit en
    Juillet 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Juillet 2015
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Merci pour la réponse, j'apprécie le temps dédié à ma demande étant débutant en javascript j’apprends sur le tas, et avant d'incorporer ça sur le script de base je vais essayer de comprendre ce que tu m’envoies :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <script>
        const myForm = document.querySelector('#Mon-Formulaire')
     
        myForm.onsubmit=e=>{
          e.preventDefault()  // juste pour le test
          }
        myForm.onreset=_=>{
          myForm.Total.innerText = '€ 100.00'
          }  
        myForm.onchange=_=>{
          let myTotal    = Number(myForm['Pack-Select'].value) * Number(myForm.quality.value)
            , OptPercent = Array.from(myForm.querySelectorAll('.option:checked'))      // calcul de la somme des pourcentages 
                                .reduce((sum,opt)=>sum+=Number(opt.value),0)          //   à appliquer par les options
            , OptionsVal = myTotal * OptPercent / 100                                // la regle de troie, sans cheval
     
          myTotal += OptionsVal
     
          myForm.Total.innerText = '€ '+ myTotal.toFixed(2)
          }
      </script>
    Au niveau du myForm.onsubmit, pourquoi utiliser " =e=> " ?

    Pareil pour le myForm.onreset on utilise également " =_=> " ...

    myForm.onchange=_=> , pourquoi le signe " =_=> " avant l'accolade ?

    L'utilisation de la virgule est obligatoire car dans l'accolade du myForm.onchange=_=>{ CODE_ICI } ?

    Tu essaye de créer un array à partir des cases cochées donc la première ligne va donner par exemple : 20,20,30 exact ? si tu peux préciser ce qui se passe à chaque étape ça serait génial :-)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    OptPercent = Array.from(myForm.querySelectorAll('.option:checked'))      // calcul de la somme des pourcentages 
                                .reduce((sum,opt)=>sum+=Number(opt.value),0)
    Le reste ça peut aller

    Merci d'avance.

  15. #15
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    Au niveau du myForm.onsubmit, pourquoi utiliser " =e=> " ?
    Pareil pour le myForm.onreset on utilise également " =_=> "
    il s'agit de fonction fléchées, et force de les utiliser je n'y penses même plus.

    c'est une variation syntaxique de fonction toto(arg) { ... code } <=> toto=arg=>{ ... code }. dans cet exemple il n'y a qu' seul argument, alors la fonction fléchée permet de se passer du parenthésage autour de la liste d'argument s'il y en a qu'un seul.

    dans le cas de toto=_=>{ ... code } c'est équivalent à fonction toto() { ... code } qui normalement devrait être toto=()=>{ ... code }.
    Il s'agit juste d'une convention ninja ( il y a des tas d'articles sur la manière de coder ninja).
    en remplace le () par un argument non utile (on a le droit d'utiliser le caractère _ (même tout seul) pour désigner une variable en JS ( genre var _ = 50 ) mais évidement c'est déconseillé.
    Alors la communauté des programmeurs ninja à décider d'utiliser ce caractère pour désigner un argument inutilisé, et qui permet de n'avoir qu'1 seul caractère à taper au lieu de 2 (les parenthèses) qui ont aussi le gros défaut de demander une un double effort carpien (sans oublier le coté esthétique )

    il y a aussi d'autres aspects important sur l'utilisation des fonctions fléchées, mais c'est un autre cours;

    L'utilisation de la virgule est obligatoire car dans l'accolade du myForm.onchange=_=>{ CODE_ICI } ?
    tu parles de cette virgule , OptPercent = .... ?

    non elle n'a pas grand chose à voir avec l'utilisation des fonction fléchées, mais oui, elle est obligatoire dans les déclarations de variables.

    exemple let nom = 'Chichi' , prenom = 'Jaco' ;

    mais pour ça aussi c'est une question d'habitude et je n'y pense même plus , sauf sur le code que je laisse ici parce que les lecteurs sont souvent déstabilisés par mon style de coding (un mix perso du whitesmiths style) et oui, je préfère mettre la virgule en début de ligne suivante plutôt qu'en fin de ligne.

    Ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    let nom    = 'Chichi'
      , prenom = 'Jaco'
    ua lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    let nom = 'Chichi',
        prenom = 'Jaco'
    comme le font tous les beautifiers de code ( mais je me suis écrit mon propre beautifier -> pour juste ce genre de truc)
    alors j'aligne aussi les = pour la lisibilité du code, et les virgules en début de ligne me permettent d'être sur de ne pas en avoir loupé une comme cela m'arrivait souvent avant.
    Quand on code "en direct" on se crée souvent des tas de variables au début, puis après on fait du nettoyage et c'est la qu'on se loupe sur les virgules. Au moins en les plaçant devant elles sont visibles (et cela évite de perdre du temps en débugging pour une simple virgule oubliée au bout d'une ligne de 10 kilomètres.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    OptPercent = Array.from(myForm.querySelectorAll('.option:checked'))      // calcul de la somme des pourcentages 
                                .reduce((sum,opt)=>sum+=Number(opt.value),0)
    pour ce dernier morceau il faut avoir en tête que le javascript permet le chainage de fonctions.

    donc ici , et dans l'ordre on utilise

    1 ) la méthode from de l'objet Array,
    2) qui utilise comme argument le résultat de la méthode querySelectorAll sur l'objet myForm
    3 ) qui elle-même utilise comme argument le résultat d'une sélection d'éléments du DOM répondant a ce critère = '.option:checked'
    4) sur lequel on chaine la méthode réduce ( faite pour les objets de type array)

    1) => transforme un élément itérable en un objet array
    2) => noter qu'ici le querySelectorAll est appliqué juste sur myForm et non sur le document entier
    3) => le query ne recherche que les élément cochés, ayant pour nom de classe = "option"

    4) a ce stade on dispose donc d'un array contenant une liste de pointeurs sur les éléments du DOM ayant une case cochée à l'intérieur du formulaire ( myForm = document.querySelector('#Mon-Formulaire') )

    la méthode réduce permet de parcourir un array et d'effectuer des calculs à chaque itération, via un principe d' accumulation / itération, il y a un principe optionnel via le second argument ici (,0)) qui ici force la première valeur d'accumulation sur zéro.
    voir https://developer.mozilla.org/fr/doc...edArray/reduce

    la méthode reduce ne peut s'appliquer que sur un objet array tandis que la méthode querySelectorAll produit elle un objet itératif. donc pour faire entrer un carré dans un rond j'ai utilisé la méthode Array.from.

    PS; je n'ai rien inventé, c''est juste un grand classique en programmation JS, et on rencontre souvent ce type d’enchaînement
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  16. #16
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Bonjour,
    Citation Envoyé par Saturos2k4
    étant débutant en javascript j’apprends sur le tas
    c'est ce qui motive ma participation à ta discussion

    Je reprend ci dessous quelques points ...

    •••
    Citation Envoyé par psychadelic
    au passage rien n'interdit de mettre du code javascript dans du jQuery.
    ce n'est parce que l'on peut que l'on doit, mais sur le coup des formulaires force est d'admettre que l'écriture s'en retrouve fortement allégée.

    Pour l'écriture je trouve préférable d'uniformiser l'écriture en privilégiant la forme avec crochets autorisant plus de « type » de name.
    Je préfère, mais c'est histoire de goût :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Number(myForm['Pack-Select'].value) * Number(myForm["quality"].value)
    au mixage suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Number(myForm['Pack-Select'].value) * Number(myForm.quality.value)
    •••
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <label><input type="checkbox" class="option" value="20"> Option 1 (+ 20% du total)</label>
    <label><input type="checkbox" class="option" value="20"> Option 2 (+ 20% du total)</label>
    <label><input type="checkbox" class="option" value="30"> Option 3 (+ 30% du total)</label>
    Il vaut mieux remplacer la class par un name = "option[]" si l'on veut pouvoir en faire quelque chose à la soumission du formulaire.

    •••
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    myForm.onreset=_=>{
        myForm.Total.innerText = '€ 100.00'
    }
    Cette fonction est complètement inutile, le <button type="reset"> faisant bien son job.

    •••
    Citation Envoyé par psychadelic
    Alors la communauté des programmeurs ninja à décider d'utiliser ce caractère pour désigner un argument inutilisé, et qui permet de n'avoir qu'1 seul caractère à taper au lieu de 2 (les parenthèses)
    Je suis surpris que l'on utilise un tel argument, la plupart de IDE fermant la parenthèse et créer une variable juste pour cela !!!!

    Concernant l'écriture je mets systématique les parenthèses, ce qui pour moi est plus lisible.
    Je préfère, mais c'est histoire de goût :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    oForm.addEventListener("change", (ev) => {
    à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    oForm.addEventListener("change", _=> {
    mais bon les « arrow function » permettent bien des choses et chacun y verra sa meilleur utilisation.
    Fonctions fléchées, pour en juger.

    •••
    Citation Envoyé par psychadelic
    tu parles de cette virgule ,
    (...)
    comme le font tous les beautifiers de code ( mais je me suis écrit mon propre beautifier -> pour juste ce genre de truc)
    pas mal de « beautifier » ont l'option Use comma-first list style, par exemple : https://beautifier.io/.
    Il est vrai que cela peut s'avérer très pratique lors de la phase de réalisation de tests et sur les déclarations d'objet type JSON.

    Un petit mot sur let et const, j'utilise
    • let pour déclarer toutes variables variables
    • const pour toutes variables affectées lors de la déclaration et dont le type ne change pas.

    let sur MDN
    const sur MDN

    •••
    Un dernier mot sur l'utilisation de Array.from, quand une méthode native existe j'aurais tendance à utiliser celle ci, en l’occurrence il existe forEach, et donc j'aurais plutôt écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    let pcOption = 0;
    oForm["option[]"].forEach((elem) => {
        pcOption += elem.checked ? Number(elem.value) : 0;
    });
    •••
    Comme tu le vois il y a presque autant de façons d'écrire un code que de « faiseurs de code », le principal est que tu trouves ta « propre », dans les deux sens, façon de faire.
    • ne néglige pas l'indentation de ton code ;
    • ne néglige pas l'identification de tes variables ;
    • ne néglige pas la documentation en ligne qui est actuellement riche ;
    • n'hésite pas à regarder d'autres sources ;
    • tu dois pouvoir comprendre, ou quelqu'un d'autre, ton code dans 6 mois ou plus ;
    • la touche F12 doit être ton alliée ;
    • ...


    •••
    Pour finir voilà ce que j'aurais pu écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    document.forms["calcul"].addEventListener("change", (ev) => {
        // récup. données
        const oForm = ev.currentTarget;
        const valeurPack = Number(oForm["Pack-Select"].value);
        const pcQuality = Number(oForm["quality"].value);
        // calcul options
        let pcOption = 0;
        oForm["option[]"].forEach((elem) => {
            pcOption += elem.checked ? Number(elem.value) : 0;
        });
        // ajuste multiplicateur
        pcOption = 1 + pcOption / 100;
        //calcul final et affichage si OK
        oForm["total"].value = (valeurPack * pcQuality * pcOption || "");
    });
    c'est plus verbeux mais tu auras tout le temps de simplifier si c'est nécessaire.

    Voilà j'ai été un peu long mais .. bon ...

  17. #17
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    rien à redire, sauf
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    myForm.onreset=_=>{
        myForm.Total.innerText = '€ 100.00'}
    Cette fonction est complètement inutile, le <button type="reset"> faisant bien son job.
    ben si elle est utile, le bouton reset remet bien toutes les valeurs par défaut, sauf sur le champs <output name="Total">€ 100.00</output> qui conserve la valeur calculée précédemment.
    j'ai essayé de mettre une valeur par défaut sur le champs de tag output, mais ça ne donne rien. ( il faudrait mieux la remplacer par un nouveau calcul)

    Ce formulaire est loin d'être la panacée, je l'ai juste ajouté ici pour illustrer les différentes techniques HTML5 / CSS3 / JS à mettre en œuvre dans l'élaboration d'un formulaire ( d'ou le Number(myForm['Pack-Select'].value) * Number(myForm.quality.value) que j'éviterai moi aussi de mixer)

    [edit] suite à la remarque pertinente de NoSmoking :
    Il vaut mieux remplacer la class par un name = "option[]" si l'on veut pouvoir en faire quelque chose à la soumission du formulaire.
    c.a.d. : <input type="checkbox" name="option[]"....
    ce qui transforme le code JS:
    Array.from(myForm.querySelectorAll('.option:checked'))en
    [...myForm.elements['option[]']] mais on perd la sélection sur les éléments cochés

    pour la syntaxe [...element ] elle est équivalente au Array.from , c'est une combinaison entre la création d'un array ( let xy = [1,2,3] )
    que l'on rempli avec l'ensemble Les ittérations de myForm.elements['option[]']en untilisant la syntaxe de décomposition ...liste (les 3 points) => https://developer.mozilla.org/fr/doc...%A9composition

    du coupl'ensemble du code devient: (et en prennant aussi le pb de mise à jour du total sur le reset)
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    <!DOCTYPE html>
    <html lang="fr">
    <head>
      <meta charset="UTF-8">
      <title>formulaire type</title>
      <style>
        body     { font: 16px Arial, Helvetica, sans-serif; }
        fieldset { padding:0 0 0 5.5em; margin:.6em 0; border:none }
        legend   { margin:.3em 0 0 -6em; width: 5em; text-align: right; float: left; font-weight: bold; font-size: .9em;}
        label                { display: block; }
        input[type=radio],
        input[type=checkbox] { position:relative; top: .3em; }
        output               { line-height: 1.7em; font-weight: bold; }
      </style>
    </head>
    <body>
      <form id="Mon-Formulaire" action="xxx" method="post">
        <fieldset>
          <legend>Item : </legend>
          <select name="Pack-Select" >
            <option value="100" selected> Pack 1  (&euro;100) </option>
            <option value="200"> Pack 2  (&euro;200) </option>
            <option value="300"> Pack 3  (&euro;300) </option>
            <option value="400"> Pack 4  (&euro;400) </option>
          </select>
        </fieldset>
     
        <fieldset>
          <legend>Qualit&eacute; : </legend>
          <label><input type="radio" name="quality" value="1.00" checked> Qualit&eacute; 1er Prix (total x1)</label>
          <label><input type="radio" name="quality" value="1.50" > Qualit&eacute; Standard (total x1.5)</label>
          <label><input type="radio" name="quality" value="2.00" > Qualit&eacute; Pro (total x2)</label>
        </fieldset>
     
        <fieldset>
          <legend>Options : </legend>
          <label><input type="checkbox" name="option[]" value="20"> Option 1 (+ 20% du total)</label>
          <label><input type="checkbox" name="option[]" value="20"> Option 2 (+ 20% du total)</label>
          <label><input type="checkbox" name="option[]" value="30"> Option 3 (+ 30% du total)</label>
        </fieldset>
     
        <fieldset>
          <legend>Total :</legend>
          <output name="Total">€ ???</output>
        </fieldset>
     
        <button type="button" id="bt-Reset">reset</button>
        <button type="submit">submit</button>
     
      </form>
     
      <script>
        const myForm = document.querySelector('#Mon-Formulaire')
     
        myForm.onsubmit =e=> e.preventDefault()  // juste pour le test == désactive l'envoi
     
        window.onload =_=>
          {
          myForm.reset()
          CalcTotal() 
          }
        document.getElementById('bt-Reset').onclick =_=>
          {
          myForm.reset()
          CalcTotal() 
          } 
        myForm.onchange = CalcTotal
        
        function CalcTotal()
          {
          let cTotal      = Number(myForm['Pack-Select'].value) * Number(myForm.quality.value)
             , OptPercent = [...myForm.elements['option[]']]                            // Array sur name="option[]" 
                            .reduce((sum,opt)=>sum+=opt.checked?Number(opt.value):0 ,0) // somme des pourcentages cochés
     
          cTotal += (cTotal * OptPercent / 100)            // sum + regle de trois,
     
          myForm.Total.innerText = '€ '+ cTotal.toFixed(2)
          }
      </script>
    </body>
    </html>

    le truc du reset, c'est que la capture de l'event reset se fait avant que les valeurs soient réinitialisées.
    donc il s'agit d'un bouton "normal" qui lance le reset sur le formulaire et qui ensuite lance le calcul.

    au passage je l'ai aussi mis lors du rechargement de la page.

    Sinon merci pour https://beautifier.io/ il est mille fois plus élaboré que le mien; j’espère pouvoir le décortiquer un peu pour améliorer mes connaissances sur ce type de code ou je galère pas mal.
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  18. #18
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    (...) sauf sur le champs <output name="Total">€ 100.00</output> qui conserve la valeur calculée précédemment.
    Ah oui très juste, il s'agit d'un <output> et non d'un <input> !

    Si l'on s'en réfère à la spécification cet élément est « resettable » mais non « sumittable » ce qui paraît logique vu son rôle.

    Il semblerait donc effectivement qu'il y ait un bogue, constaté sur Edge et FireFox mais pas sur Chrome.

    En recherchant sur Buzilla on retrouve bien :


    [EDIT] Ce qui suit n'est pas judicieux du tout, voir plus loin dans la discussion..

    Il me semble que dans ce cas il est préférable d'apporter un correctif au chargement de la page en initialisant la defaultValue des éléments <output> contenus dans un élément <form> .

    Je verrais bien quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /**
     * BUG sur élément <output> si reset pour FF et Edge
     * https://bugzilla.mozilla.org/show_bug.cgi?id=1422260
     * https://bugzilla.mozilla.org/show_bug.cgi?id=1537689
     */
    document.addEventListener("DOMContentLoaded", () => {
      const oOutputs = document.querySelectorAll("form ouput");
      oOutputs.forEach((elem) => {
        elem.defaultValue = elem.defaultValue || elem.value || elem.textContent;
      });
    });
    Je me la mets de côté pour le cas où.

  19. #19
    Expert confirmé Avatar de psychadelic
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    2 529
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 2 529
    Points : 4 740
    Points
    4 740
    Par défaut
    Ça ne résout pas le problème (sur Firefox):
    si ont rafraîchi la page (F5) ce script récupère la valeur courante présente dans le output ( issu du calcul ) et en fait une nouvelle valeur par défaut fausse.
    «La pluralité des voix n'est pas une preuve, pour les vérités malaisées à découvrir, tant il est bien plus vraisemblable qu'un homme seul les ait rencontrées que tout un peuple.» [ René Descartes ] - Discours de la méthode

  20. #20
    Futur Membre du Club Avatar de Saturos2k4
    Homme Profil pro
    Analyse système
    Inscrit en
    Juillet 2015
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Juillet 2015
    Messages : 21
    Points : 8
    Points
    8
    Par défaut
    Bonsoir, je vous lis dès que je suis à la maison j'ai loupé pas mal de choses, merci pour vos réponses

    EDIT : Merci encore à NoSmoking le modérateur pour ta participation, bon du coup je retourne à la lecture de vos codes

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réponses: 3
    Dernier message: 10/05/2007, 13h21
  2. Réponses: 7
    Dernier message: 23/02/2007, 15h33
  3. Réponses: 4
    Dernier message: 01/08/2006, 16h12
  4. Réponses: 4
    Dernier message: 12/06/2006, 11h46
  5. Comment charger un formulaire en fonction d'un bouton radio
    Par FredKéKé dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 31/01/2006, 13h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo