2

So, I have set up a payment method (Leasing) - when chosen, you have the choice between different leasing providers. It is working so far, as the providers are shown in the checkout, I can click them and "order".

But I failed to make those radio buttons to be required entries.

I used this tutorial to make a text field required: https://webkul.com/blog/how-to-add-custom-field-for-a-payment-method-in-magento2/ and tried to work from there.

But tbh. I still dont really know, what I am doing wrong and knockout gives me headaches xD

Here is my template:

<div class="payment-method payment-method-leasing" data-bind="css: {'_active': (getCode() == isChecked())}">
    <div class="payment-method-title field choice">
        <input type="radio"
               name="payment[method]"
               class="radio"
               data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()"/>
        <label data-bind="attr: {'for': getCode()}" class="label">
            <img data-bind="attr: {'src': logo, 'alt': $t('Payment Method Logo')}" class="leasing-logo payment-method-logo" />
            <span data-bind="text: getTitle()"></span>
        </label>
    </div>

    <div class="payment-method-content">
        <!-- ko foreach: getRegion('messages') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!--/ko-->
        <div class="payment-method-billing-address">
            <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
            <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->
        </div>
        <form id="leasing_form" class="form form-leasing" data-role="leasing_form">
            <fieldset class="fieldset payment method" data-bind='attr: {id: "payment_form_" + getCode()}'>

                <div class="field required">
                    <div class="control">
                        <div id="leasing-provider" class="leasing-provider-radio" data-bind="foreach: leasingProviders">
                            <input type="radio"
                            data-validate="{required:true}"
                            class="leasing-provider-radio-input"
                            data-bind="attr: {id: 'leasing-provider-' + value, name: 'payment[leasing-provider]', value: value}" />
                            <label data-bind="attr: {for: 'leasing-provider-' + value}">
                                <img data-bind="attr: {src: imgUrl, alt: label}" class="leasing-provider-image" />
                                <span data-bind="text: label"></span><br>
                            </label>
                        </div>
                    </div>

                </div>
            </fieldset>
        </form>
        <div class="checkout-agreements-block">
            <!-- ko foreach: $parent.getRegion('before-place-order') -->
                <!-- ko template: getTemplate() --><!-- /ko -->
            <!--/ko-->
        </div>
        <div class="actions-toolbar" id="review-buttons-container">
            <div class="primary">
                <button class="action primary checkout"
                        type="submit"
                        data-bind="
                        click: placeOrder,
                        attr: {title: $t('Place Order')},
                        enable: (getCode() == isChecked()),
                        css: {disabled: !isPlaceOrderActionAllowed()}
                        "
                        data-role="review-save">
                    <span data-bind="i18n: 'Place Order'"></span>
                </button>
            </div>
        </div>
    </div>
</div>

and here is the method-renderer js-file:

define(
    [
        'jquery',
        'Magento_Checkout/js/view/payment/default',
        'mage/url',
        'Magento_Checkout/js/model/error-processor',
        'Magento_Checkout/js/action/redirect-on-success',
        'Magento_Checkout/js/model/quote',
        'mage/validation'
    ],
    function ($,Component,url, errorProcessor,redirectOnSuccessAction, quote) {
        'use strict';

        return Component.extend({
            defaults: {
                template: 'Myvendor_LeasingPayment/payment/leasingtemplate',
                leasing: '',
                logo: "",
                leasingProviders: ""
            },
            /** @inheritdoc */
            initObservable: function () {
                this._super()
                    .observe(['leasing']);
                this.loadLeasingProviders();
                this.loadLogo();
                return this;
            },
            /**
         * @return {Object}
         */
        getData: function () {
            return {
                method: this.item.method,
                // 'mpesanumber': this.mpesaNumber(),
                'additional_data': {
                    'leasing': $("input.leasing-provider-radio-input:checked").val()
                }
            };
        },
        /**
         * @return {jQuery}
         */
        validate: function () {
            var form = 'form[data-role=leasing_form]';

            return $(form).validation() && $(form).validation('isValid');
        },

        loadLeasingProviders: function () {
            // Make an Ajax call to your backend to get the leasing providers
            $.ajax({
                url: '/myvendor_leasingpayment/payment/leasingProviders', // Replace with your actual backend URL
                method: 'GET',
                dataType: 'json',
                success: function (data) {
                    // Update the leasingProviders array with the received data
                    // console.log(data);
                    this.leasingProviders = data;
                }.bind(this),
                error: function () {
                    // Handle error
                }
            });
        },

        loadLogo: function () {
            // Make an Ajax call to your backend to get the leasing providers
            $.ajax({
                url: '/myvendor_leasingpayment/payment/Logo', // Replace with your actual backend URL
                method: 'GET',
                dataType: 'json',
                success: function (data) {
                    // Update the leasingProviders array with the received data
                    console.log(data);
                    this.logo = data.url;
                }.bind(this),
                error: function () {
                    // Handle error
                }
            });
        },

        });
    }
);

2 Answers 2

0

You have to added this code into page load event.

YOUR_RADIO_BUTTON_NAME: ko.observable().extend({
                    required: true
       }),

where YOUR_RADIO_BUTTON_NAME replace with your real radio button name.

2
  • could you clarify this a bit? As I dont have a page load event right now in my javascript file.
    – Mario
    Nov 27, 2023 at 8:07
  • You can added on your js file. Nov 27, 2023 at 10:06
0

Plot Twist: The validate function only validates, when the radio buttons are visible. If not, there is no validation. I set the buttons to "display:block" and the validation worked as expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.