Reputation: 2645
I'm creating a integration with a payment service. The payment service provides me a form with a script tag inside.
My question is a continuation from Insert a script tag inside template Vue
The form with checkout of payment service:
<form action="http://localhost:8081/api/v1/payment/" method="POST">
<script
src="https://www.mercadopago.com.br/integrations/v1/web-tokenize-checkout.js"
data-public-key="KEY"
data-transaction-amount="14.90">
</script>
</form>
I can make the next on "mounted()" of vuejs:
<form ref="myform">
...
</form>
mounted() {
let foo = document.createElement('script');
foo.setAttribute("src","https://www.mercadopago.com.br/integrations/v1/web-tokenize-checkout.js");
foo.setAttribute("data-transaction-amount", this.newAmount)
this.$refs.myform.appendChild(foo);
}
But, my problem is that after the view has been mounted. the user can change "data-transaction-amount".
To solve it , I tried:
data:()=>({
newAmount:0
})
watch: {
newAmount() {
this.modifyScript();
},
},
methods: {
modifyScript() {
let scripts = document.getElementsByTagName("script");
for (let i = 0; i < scripts.length; i++) {
let script = scripts[i];
if (script.getAttribute("src") == 'https://www.mercadopago.com.br/integrations/v1/web-tokenize-checkout.js') {
// we've got a match
script.setAttribute("data-transaction-amount", this.newAmount);
}
}
},
The "data-transaction-amount" is changing to new value, but the window checkout of payment service shows the original value used in "mounted()".
Upvotes: 0
Views: 1196
Reputation: 10729
One solution should be let the browser force to reload the javascript file after the amount is changed.
Below is one steps:
script
element (src=...?old_amount
) already added beforescript
element (src=...?new_amount
)Below is one fiddle (open the browser console, then you will see the script web-tokenize-checkout.js
is redownloaded when the amount is changed).
Vue.component('v-loadjs',{
template:`
<div>
<p><button class="btn btn-info" v-on:click="changeAmount()">Change Amount: {{amount}}</button></p>
<p ref="test"></p>
</div>
`,
data () {
return {
amount: 0,
url: 'https://www.mercadopago.com.br/integrations/v1/web-tokenize-checkout.js'
}
},
mounted: function () {
this.loadJS(this.amount, this.amount)
},
watch: {
amount: function(newAmount, oldAmount) {
this.loadJS(newAmount, oldAmount)
}
},
methods: {
changeAmount: function () {
this.amount += 1
},
loadJS: function (newAmount, oldAmount) {
[...document.querySelectorAll('button.mercadopago-button')].forEach(item => item.remove())
let scripts = document.getElementsByTagName("script");
for (let i = 0; i < scripts.length; i++) {
if (scripts[i].getAttribute("src") == this.url + '?version=' + oldAmount) {
scripts[i].remove()
}
}
let foo = document.createElement('script');
foo.setAttribute("src", this.url + '?version=' + newAmount);
foo.setAttribute("data-transaction-amount", newAmount)
this.$refs.test.appendChild(foo);
}
}
})
new Vue ({
el:'#app'
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div class="container">
<div class="col-lg-offset-4 col-lg-4">
<v-loadjs></v-loadjs>
</div>
</div>
</div>
Upvotes: 2