Magento 2 How to bind knockout event on ajax html response












1















I have created custom functionality on item form on cart page like increment/decrement qty, remove product with a custom popup, custom move to wishlist by knockout js.



For knockout events, I created custom js and initialize it on form.phtml



<div data-bind="scope: 'remove-product'" id="cart-item-table">
<form action="<?= /* @escapeNotVerified */ $block->getUrl('checkout/cart/updatePost') ?>"
method="post"
id="form-validate"
data-mage-init='{"validation":{}}'
class="form form-cart">

....
....
</form>
</div>

<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"remove-product": {
"component": "Vendor_Module/js/removeproduct"
}
}
}
}
}
</script>


enter image description here



Now I have a third-party coupon code module which adds free gift product by applying the coupon code on cart page. For that, I just re-render item form layout on ajax response.



Everything is working fine except knockout events on item form. All knockout events stop working after re-render item form.



After some R&D, I found that we need to rebind knockout events after ajax response.



ko.applyBindings(removeproduct, $('#cart-item-table'));


It's showing error like parameter should ViewModel and element. I already defined it.



Any help would be appreciated...!










share|improve this question























  • Same issue i face before few days. This link is helpful for me. Hope, you can get solution from this answer :)

    – Rohan Hapani
    3 hours ago
















1















I have created custom functionality on item form on cart page like increment/decrement qty, remove product with a custom popup, custom move to wishlist by knockout js.



For knockout events, I created custom js and initialize it on form.phtml



<div data-bind="scope: 'remove-product'" id="cart-item-table">
<form action="<?= /* @escapeNotVerified */ $block->getUrl('checkout/cart/updatePost') ?>"
method="post"
id="form-validate"
data-mage-init='{"validation":{}}'
class="form form-cart">

....
....
</form>
</div>

<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"remove-product": {
"component": "Vendor_Module/js/removeproduct"
}
}
}
}
}
</script>


enter image description here



Now I have a third-party coupon code module which adds free gift product by applying the coupon code on cart page. For that, I just re-render item form layout on ajax response.



Everything is working fine except knockout events on item form. All knockout events stop working after re-render item form.



After some R&D, I found that we need to rebind knockout events after ajax response.



ko.applyBindings(removeproduct, $('#cart-item-table'));


It's showing error like parameter should ViewModel and element. I already defined it.



Any help would be appreciated...!










share|improve this question























  • Same issue i face before few days. This link is helpful for me. Hope, you can get solution from this answer :)

    – Rohan Hapani
    3 hours ago














1












1








1


1






I have created custom functionality on item form on cart page like increment/decrement qty, remove product with a custom popup, custom move to wishlist by knockout js.



For knockout events, I created custom js and initialize it on form.phtml



<div data-bind="scope: 'remove-product'" id="cart-item-table">
<form action="<?= /* @escapeNotVerified */ $block->getUrl('checkout/cart/updatePost') ?>"
method="post"
id="form-validate"
data-mage-init='{"validation":{}}'
class="form form-cart">

....
....
</form>
</div>

<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"remove-product": {
"component": "Vendor_Module/js/removeproduct"
}
}
}
}
}
</script>


enter image description here



Now I have a third-party coupon code module which adds free gift product by applying the coupon code on cart page. For that, I just re-render item form layout on ajax response.



Everything is working fine except knockout events on item form. All knockout events stop working after re-render item form.



After some R&D, I found that we need to rebind knockout events after ajax response.



ko.applyBindings(removeproduct, $('#cart-item-table'));


It's showing error like parameter should ViewModel and element. I already defined it.



Any help would be appreciated...!










share|improve this question














I have created custom functionality on item form on cart page like increment/decrement qty, remove product with a custom popup, custom move to wishlist by knockout js.



For knockout events, I created custom js and initialize it on form.phtml



<div data-bind="scope: 'remove-product'" id="cart-item-table">
<form action="<?= /* @escapeNotVerified */ $block->getUrl('checkout/cart/updatePost') ?>"
method="post"
id="form-validate"
data-mage-init='{"validation":{}}'
class="form form-cart">

....
....
</form>
</div>

<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"remove-product": {
"component": "Vendor_Module/js/removeproduct"
}
}
}
}
}
</script>


enter image description here



Now I have a third-party coupon code module which adds free gift product by applying the coupon code on cart page. For that, I just re-render item form layout on ajax response.



Everything is working fine except knockout events on item form. All knockout events stop working after re-render item form.



After some R&D, I found that we need to rebind knockout events after ajax response.



ko.applyBindings(removeproduct, $('#cart-item-table'));


It's showing error like parameter should ViewModel and element. I already defined it.



Any help would be appreciated...!







magento2 javascript knockoutjs






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 4 hours ago









Prince PatelPrince Patel

13.4k54777




13.4k54777













  • Same issue i face before few days. This link is helpful for me. Hope, you can get solution from this answer :)

    – Rohan Hapani
    3 hours ago



















  • Same issue i face before few days. This link is helpful for me. Hope, you can get solution from this answer :)

    – Rohan Hapani
    3 hours ago

















Same issue i face before few days. This link is helpful for me. Hope, you can get solution from this answer :)

– Rohan Hapani
3 hours ago





Same issue i face before few days. This link is helpful for me. Hope, you can get solution from this answer :)

– Rohan Hapani
3 hours ago










2 Answers
2






active

oldest

votes


















2














We need to re-bind js component by knockout applyBindings function on ajax response.



ko.applyBindings(new removeproduct(), $('#cart-item-table')[0]);


While removeproduct is viewModel Vendor_Module/js/removeproduct and cart-item-table is the element which I need to re-bind knockout events.






share|improve this answer





















  • 1





    yes you are right

    – Rakesh Donga
    1 hour ago











  • Vah raka vah hase bhai hase ayo baki

    – Prince Patel
    1 hour ago













  • yes bhai!! hahaahaa

    – Rakesh Donga
    1 hour ago



















1














It's better way to use data-mage-init into specific div instead of using <script type="text/x-magento-init">



x-magento-init will be call when module will be initialized. So, when module will be initialized at that time, x-magento-init script will be call. So, it will be not used for ajax response.



data-mage-init will be working same as like x-magento-init except it will call when that particular div will be load.



Example :



<div data-mage-init='{"Pulsestorm_JavascriptInitTutorial/example": {"another":"example"}}'>A single div</div>


Here, You can see on above code that when above div will be load at that time, js file will be execute. It's better way as per my view.





EDIT :



<div id="ko-example" data-bind="scope:'ko-example'">
<!-- ko if: isVisible-->
<div class="rh-module" data-mage-init='{"Rh_Module/js/kotemplate": {"another":"example"}}'>
<div >A single div</div>
<div id="rh-buttons" class="actions">
<button type="submit" title="Select" class="action primary" id="rh-module-select-btn" data-bind="click:addCustomValue">
<span>Select</span>
</button>
<button type="button" title="Cancel" class="action" id="rh-module-cancel-btn">
<span>Cancel</span>
</button>
</div>
</div>
<!-- /ko -->
</div>

<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"ko-example": {
"component": "Vendor_Module/js/kotemplate",
"template" : "Vendor_Module/kotemplate"
}
}
}
}
}
</script>


Here, rh-module only visible when isVisible true and that will be get only in ajax respose. So, when <div class="rh-module"> visible kotemplate js will be call and you can bind data.



More reference






share|improve this answer


























  • Thanks for the answer :). There are only difference between data-mage-init and text/x-magento-init is that data-mage-init adds js component on specific HTML element while text/x-magento-init is no relation to a certain HTML element. Both types, initialized js component on DOM ready so it's not working on ajax response.

    – Prince Patel
    1 hour ago






  • 1





    I just found the solution to my issue. We need to re-bind the js component by knockout applyBindings function check my answer for more details.

    – Prince Patel
    1 hour ago













  • Thanks for new solution @Prince +1 from mine. Can you please elaborate more in your answer?

    – Rohan Hapani
    1 hour ago








  • 1





    Thanks @Rohan I will update the answer soon :)

    – Prince Patel
    1 hour ago











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "479"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f258660%2fmagento-2-how-to-bind-knockout-event-on-ajax-html-response%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














We need to re-bind js component by knockout applyBindings function on ajax response.



ko.applyBindings(new removeproduct(), $('#cart-item-table')[0]);


While removeproduct is viewModel Vendor_Module/js/removeproduct and cart-item-table is the element which I need to re-bind knockout events.






share|improve this answer





















  • 1





    yes you are right

    – Rakesh Donga
    1 hour ago











  • Vah raka vah hase bhai hase ayo baki

    – Prince Patel
    1 hour ago













  • yes bhai!! hahaahaa

    – Rakesh Donga
    1 hour ago
















2














We need to re-bind js component by knockout applyBindings function on ajax response.



ko.applyBindings(new removeproduct(), $('#cart-item-table')[0]);


While removeproduct is viewModel Vendor_Module/js/removeproduct and cart-item-table is the element which I need to re-bind knockout events.






share|improve this answer





















  • 1





    yes you are right

    – Rakesh Donga
    1 hour ago











  • Vah raka vah hase bhai hase ayo baki

    – Prince Patel
    1 hour ago













  • yes bhai!! hahaahaa

    – Rakesh Donga
    1 hour ago














2












2








2







We need to re-bind js component by knockout applyBindings function on ajax response.



ko.applyBindings(new removeproduct(), $('#cart-item-table')[0]);


While removeproduct is viewModel Vendor_Module/js/removeproduct and cart-item-table is the element which I need to re-bind knockout events.






share|improve this answer















We need to re-bind js component by knockout applyBindings function on ajax response.



ko.applyBindings(new removeproduct(), $('#cart-item-table')[0]);


While removeproduct is viewModel Vendor_Module/js/removeproduct and cart-item-table is the element which I need to re-bind knockout events.







share|improve this answer














share|improve this answer



share|improve this answer








edited 1 hour ago

























answered 1 hour ago









Prince PatelPrince Patel

13.4k54777




13.4k54777








  • 1





    yes you are right

    – Rakesh Donga
    1 hour ago











  • Vah raka vah hase bhai hase ayo baki

    – Prince Patel
    1 hour ago













  • yes bhai!! hahaahaa

    – Rakesh Donga
    1 hour ago














  • 1





    yes you are right

    – Rakesh Donga
    1 hour ago











  • Vah raka vah hase bhai hase ayo baki

    – Prince Patel
    1 hour ago













  • yes bhai!! hahaahaa

    – Rakesh Donga
    1 hour ago








1




1





yes you are right

– Rakesh Donga
1 hour ago





yes you are right

– Rakesh Donga
1 hour ago













Vah raka vah hase bhai hase ayo baki

– Prince Patel
1 hour ago







Vah raka vah hase bhai hase ayo baki

– Prince Patel
1 hour ago















yes bhai!! hahaahaa

– Rakesh Donga
1 hour ago





yes bhai!! hahaahaa

– Rakesh Donga
1 hour ago













1














It's better way to use data-mage-init into specific div instead of using <script type="text/x-magento-init">



x-magento-init will be call when module will be initialized. So, when module will be initialized at that time, x-magento-init script will be call. So, it will be not used for ajax response.



data-mage-init will be working same as like x-magento-init except it will call when that particular div will be load.



Example :



<div data-mage-init='{"Pulsestorm_JavascriptInitTutorial/example": {"another":"example"}}'>A single div</div>


Here, You can see on above code that when above div will be load at that time, js file will be execute. It's better way as per my view.





EDIT :



<div id="ko-example" data-bind="scope:'ko-example'">
<!-- ko if: isVisible-->
<div class="rh-module" data-mage-init='{"Rh_Module/js/kotemplate": {"another":"example"}}'>
<div >A single div</div>
<div id="rh-buttons" class="actions">
<button type="submit" title="Select" class="action primary" id="rh-module-select-btn" data-bind="click:addCustomValue">
<span>Select</span>
</button>
<button type="button" title="Cancel" class="action" id="rh-module-cancel-btn">
<span>Cancel</span>
</button>
</div>
</div>
<!-- /ko -->
</div>

<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"ko-example": {
"component": "Vendor_Module/js/kotemplate",
"template" : "Vendor_Module/kotemplate"
}
}
}
}
}
</script>


Here, rh-module only visible when isVisible true and that will be get only in ajax respose. So, when <div class="rh-module"> visible kotemplate js will be call and you can bind data.



More reference






share|improve this answer


























  • Thanks for the answer :). There are only difference between data-mage-init and text/x-magento-init is that data-mage-init adds js component on specific HTML element while text/x-magento-init is no relation to a certain HTML element. Both types, initialized js component on DOM ready so it's not working on ajax response.

    – Prince Patel
    1 hour ago






  • 1





    I just found the solution to my issue. We need to re-bind the js component by knockout applyBindings function check my answer for more details.

    – Prince Patel
    1 hour ago













  • Thanks for new solution @Prince +1 from mine. Can you please elaborate more in your answer?

    – Rohan Hapani
    1 hour ago








  • 1





    Thanks @Rohan I will update the answer soon :)

    – Prince Patel
    1 hour ago
















1














It's better way to use data-mage-init into specific div instead of using <script type="text/x-magento-init">



x-magento-init will be call when module will be initialized. So, when module will be initialized at that time, x-magento-init script will be call. So, it will be not used for ajax response.



data-mage-init will be working same as like x-magento-init except it will call when that particular div will be load.



Example :



<div data-mage-init='{"Pulsestorm_JavascriptInitTutorial/example": {"another":"example"}}'>A single div</div>


Here, You can see on above code that when above div will be load at that time, js file will be execute. It's better way as per my view.





EDIT :



<div id="ko-example" data-bind="scope:'ko-example'">
<!-- ko if: isVisible-->
<div class="rh-module" data-mage-init='{"Rh_Module/js/kotemplate": {"another":"example"}}'>
<div >A single div</div>
<div id="rh-buttons" class="actions">
<button type="submit" title="Select" class="action primary" id="rh-module-select-btn" data-bind="click:addCustomValue">
<span>Select</span>
</button>
<button type="button" title="Cancel" class="action" id="rh-module-cancel-btn">
<span>Cancel</span>
</button>
</div>
</div>
<!-- /ko -->
</div>

<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"ko-example": {
"component": "Vendor_Module/js/kotemplate",
"template" : "Vendor_Module/kotemplate"
}
}
}
}
}
</script>


Here, rh-module only visible when isVisible true and that will be get only in ajax respose. So, when <div class="rh-module"> visible kotemplate js will be call and you can bind data.



More reference






share|improve this answer


























  • Thanks for the answer :). There are only difference between data-mage-init and text/x-magento-init is that data-mage-init adds js component on specific HTML element while text/x-magento-init is no relation to a certain HTML element. Both types, initialized js component on DOM ready so it's not working on ajax response.

    – Prince Patel
    1 hour ago






  • 1





    I just found the solution to my issue. We need to re-bind the js component by knockout applyBindings function check my answer for more details.

    – Prince Patel
    1 hour ago













  • Thanks for new solution @Prince +1 from mine. Can you please elaborate more in your answer?

    – Rohan Hapani
    1 hour ago








  • 1





    Thanks @Rohan I will update the answer soon :)

    – Prince Patel
    1 hour ago














1












1








1







It's better way to use data-mage-init into specific div instead of using <script type="text/x-magento-init">



x-magento-init will be call when module will be initialized. So, when module will be initialized at that time, x-magento-init script will be call. So, it will be not used for ajax response.



data-mage-init will be working same as like x-magento-init except it will call when that particular div will be load.



Example :



<div data-mage-init='{"Pulsestorm_JavascriptInitTutorial/example": {"another":"example"}}'>A single div</div>


Here, You can see on above code that when above div will be load at that time, js file will be execute. It's better way as per my view.





EDIT :



<div id="ko-example" data-bind="scope:'ko-example'">
<!-- ko if: isVisible-->
<div class="rh-module" data-mage-init='{"Rh_Module/js/kotemplate": {"another":"example"}}'>
<div >A single div</div>
<div id="rh-buttons" class="actions">
<button type="submit" title="Select" class="action primary" id="rh-module-select-btn" data-bind="click:addCustomValue">
<span>Select</span>
</button>
<button type="button" title="Cancel" class="action" id="rh-module-cancel-btn">
<span>Cancel</span>
</button>
</div>
</div>
<!-- /ko -->
</div>

<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"ko-example": {
"component": "Vendor_Module/js/kotemplate",
"template" : "Vendor_Module/kotemplate"
}
}
}
}
}
</script>


Here, rh-module only visible when isVisible true and that will be get only in ajax respose. So, when <div class="rh-module"> visible kotemplate js will be call and you can bind data.



More reference






share|improve this answer















It's better way to use data-mage-init into specific div instead of using <script type="text/x-magento-init">



x-magento-init will be call when module will be initialized. So, when module will be initialized at that time, x-magento-init script will be call. So, it will be not used for ajax response.



data-mage-init will be working same as like x-magento-init except it will call when that particular div will be load.



Example :



<div data-mage-init='{"Pulsestorm_JavascriptInitTutorial/example": {"another":"example"}}'>A single div</div>


Here, You can see on above code that when above div will be load at that time, js file will be execute. It's better way as per my view.





EDIT :



<div id="ko-example" data-bind="scope:'ko-example'">
<!-- ko if: isVisible-->
<div class="rh-module" data-mage-init='{"Rh_Module/js/kotemplate": {"another":"example"}}'>
<div >A single div</div>
<div id="rh-buttons" class="actions">
<button type="submit" title="Select" class="action primary" id="rh-module-select-btn" data-bind="click:addCustomValue">
<span>Select</span>
</button>
<button type="button" title="Cancel" class="action" id="rh-module-cancel-btn">
<span>Cancel</span>
</button>
</div>
</div>
<!-- /ko -->
</div>

<script type="text/x-magento-init">
{
"*": {
"Magento_Ui/js/core/app": {
"components": {
"ko-example": {
"component": "Vendor_Module/js/kotemplate",
"template" : "Vendor_Module/kotemplate"
}
}
}
}
}
</script>


Here, rh-module only visible when isVisible true and that will be get only in ajax respose. So, when <div class="rh-module"> visible kotemplate js will be call and you can bind data.



More reference







share|improve this answer














share|improve this answer



share|improve this answer








edited 3 hours ago

























answered 3 hours ago









Rohan HapaniRohan Hapani

6,08021662




6,08021662













  • Thanks for the answer :). There are only difference between data-mage-init and text/x-magento-init is that data-mage-init adds js component on specific HTML element while text/x-magento-init is no relation to a certain HTML element. Both types, initialized js component on DOM ready so it's not working on ajax response.

    – Prince Patel
    1 hour ago






  • 1





    I just found the solution to my issue. We need to re-bind the js component by knockout applyBindings function check my answer for more details.

    – Prince Patel
    1 hour ago













  • Thanks for new solution @Prince +1 from mine. Can you please elaborate more in your answer?

    – Rohan Hapani
    1 hour ago








  • 1





    Thanks @Rohan I will update the answer soon :)

    – Prince Patel
    1 hour ago



















  • Thanks for the answer :). There are only difference between data-mage-init and text/x-magento-init is that data-mage-init adds js component on specific HTML element while text/x-magento-init is no relation to a certain HTML element. Both types, initialized js component on DOM ready so it's not working on ajax response.

    – Prince Patel
    1 hour ago






  • 1





    I just found the solution to my issue. We need to re-bind the js component by knockout applyBindings function check my answer for more details.

    – Prince Patel
    1 hour ago













  • Thanks for new solution @Prince +1 from mine. Can you please elaborate more in your answer?

    – Rohan Hapani
    1 hour ago








  • 1





    Thanks @Rohan I will update the answer soon :)

    – Prince Patel
    1 hour ago

















Thanks for the answer :). There are only difference between data-mage-init and text/x-magento-init is that data-mage-init adds js component on specific HTML element while text/x-magento-init is no relation to a certain HTML element. Both types, initialized js component on DOM ready so it's not working on ajax response.

– Prince Patel
1 hour ago





Thanks for the answer :). There are only difference between data-mage-init and text/x-magento-init is that data-mage-init adds js component on specific HTML element while text/x-magento-init is no relation to a certain HTML element. Both types, initialized js component on DOM ready so it's not working on ajax response.

– Prince Patel
1 hour ago




1




1





I just found the solution to my issue. We need to re-bind the js component by knockout applyBindings function check my answer for more details.

– Prince Patel
1 hour ago







I just found the solution to my issue. We need to re-bind the js component by knockout applyBindings function check my answer for more details.

– Prince Patel
1 hour ago















Thanks for new solution @Prince +1 from mine. Can you please elaborate more in your answer?

– Rohan Hapani
1 hour ago







Thanks for new solution @Prince +1 from mine. Can you please elaborate more in your answer?

– Rohan Hapani
1 hour ago






1




1





Thanks @Rohan I will update the answer soon :)

– Prince Patel
1 hour ago





Thanks @Rohan I will update the answer soon :)

– Prince Patel
1 hour ago


















draft saved

draft discarded




















































Thanks for contributing an answer to Magento Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f258660%2fmagento-2-how-to-bind-knockout-event-on-ajax-html-response%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Ponta tanko

Tantalo (mitologio)

Erzsébet Schaár