Reputation: 1
I am really new to knockoutjs and find it kind of hard to work with it. Things that were very easy for me with jQuery, don't work at all with knockout...
On a Magento 2 Shop I want to display summarized data from the selected shipping method. The "checked" binding is already in use for Magento setting the shipping method to the quote. Now I have some custom data at my input elements (eg. Shipping Name, Shipping Timerange etc.) which I want to display in a "Summarize" Box
it should look like this
<div id="selected-method-summary">
<span class="method-name" data-bind="text: selectedMethod.name"></span>
<span class="method-timerange" data-bind="text: selectedMethod.timerange"></span>
<span class="method-price" data-bind="text: selectedMethod.price"></span>
</div>
<fieldset class="fieldset rate" data-bind="visible: (rates().length > 0)">
<dl class="items methods" data-bind="foreach: shippingRateGroups, mageInit: {'accordion':{'openedState': 'active', 'collapsible': true, 'active': [2], 'multipleCollapsible': true}} ">
<div class="method-group" attr="'id': $data" data-role="collapsible">
<dt class="item-title" data-role="title"><span data-bind="text: $data"></span> <span class="accordion-toggle"></span></dt>
<dd class="item-options" data-role="content" attr="'id': $data + 'content'" data-bind="foreach: { data:$parent.getRatesForGroup($data), as: 'method' }">
<div click="element.selectShippingMethod" attr="'data-date': method.extension_attributes.date, 'data-timerange': method.extension_attributes.time_range" data-bind="css: {'field choice item': available, 'message error': !available} ">
<!-- ko ifnot: (available) -->
<div data-bind="text: error_message"></div>
<!-- /ko -->
<!-- ko if: (available) -->
<input type="radio"
class="radio"
data-bind="
click: $parents[1].selectShippingMethod,
checked: element.isSelected,
attr: {
value: carrier_code + '_' + method_code,
id: 's_method_' + carrier_code + '_' + method_code
}
"/>
<label class="label" data-bind="attr: {for: 's_method_' + carrier_code + '_' + method_code}">
<!-- ko text: $data.method_title --><!-- /ko -->
<each args="element.getRegion('price')" render="" />
</label>
<!-- /ko -->
</div>
</dd>
</div>
</dl>
</fieldset>
and then I want that the data inside the summary block change depending on the method which is selected. the "data-bind="checked: element.isSelected" only gives one value back
isSelected: ko.computed(function () {
return quote.shippingMethod() ?
quote.shippingMethod()['carrier_code'] + '_' + quote.shippingMethod()['method_code'] :
null;
}),
I've tried to extend this "isSelected" method, but I don't know how to do that without destroying magento functionality
how can I realize that?
thank you in advance
Upvotes: 0
Views: 553
Reputation: 2797
You need to change your mindset when using KO :) You need to have everything in your ViewModel class. Here is simple example which list all payment methods and display summary.
P.S. You need to play a bit with radio checked attribute :)
// Model for payments
class PaymentMethod {
constructor(id, name, price) {
this.id = id;
this.name = name;
this.price = price;
}
}
class AppViewModel {
constructor() {
// Add payments to display them
this.paymentMethods = [
new PaymentMethod(1, "First", 100),
new PaymentMethod(2, "Second", 200),
new PaymentMethod(3, "Third", 300),
];
// No selected payment method
this.selectedMethod = ko.observable(new PaymentMethod(0, "", 0));
}
onPaymentClicked = (method) => {
this.selectedMethod(method);
}
}
ko.applyBindings(new AppViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="visible: selectedMethod().id != 0">
<span class="method-name" data-bind="text: selectedMethod().name"></span>
<span class="method-price" data-bind="text: selectedMethod().price"></span>
</div>
<div data-bind="foreach: paymentMethods">
<input type="radio" name="paymentGroup" data-bind="click: $root.onPaymentClicked"> <span data-bind="text: name"></span><br />
</div>
Upvotes: 0