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
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.
- 
 could you clarify this a bit? As I dont have a page load event right now in my javascript file.Mario– Mario2023年11月27日 08:07:28 +00:00Commented Nov 27, 2023 at 8:07
 - 
 You can added on your js file.Dhiren Vasoya– Dhiren Vasoya2023年11月27日 10:06:20 +00:00Commented Nov 27, 2023 at 10:06
 
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.
Explore related questions
See similar questions with these tags.