Try rerender ads in vuejs - javascript

Hey i'm new here so please dont blame me if i do something stupid :D
So yeah my question! I have a site with vuejs and i want to put some ads on my site. So i created some components:
<template>
<div class="ad-wrapper">
<div ref="ad"></div>
<div id='div-gpt-ad-1407836229438-0' ref="adGpt"></div>
</div>
</template>
<script>
export default {
name: 'Ad-top',
props: {
},
components: {
},
data() {
return {
};
},
methods: {
setAd() {
const adScript = document.createElement('script');
adScript.type = 'text/javascript';
adScript.text = `googletag.cmd.push(function() {
googletag.defineSlot('/53015287/aniflix.tv_d_970x90_1', [970, 90], 'div-gpt-ad-1407836229438-0').addService(googletag.pubads());
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});`;
this.$refs.ad.appendChild(adScript);
const adGptScript = document.createElement('script');
adGptScript.type = 'text/javascript';
adGptScript.text = `googletag.cmd.push(function() { googletag.display('div-gpt-ad-1407836229438-0'); });`;
this.$refs.adGpt.appendChild(adGptScript);
},
refreshAd() {
this.$refs.ad.innerHTML = '';
this.$refs.adGpt.innerHTML = '';
this.setAd();
},
},
mounted() {
this.setAd();
this.$eventBus.$on('refreshAds', () => {
this.refreshAd();
});
},
beforeDestroy() {
this.$eventBus.$off('refreshAds');
},
};
</script>
Well that works just fine but if i try to go to another page on my sites the ads doesnt refresh and disappear.
I tried to just clear the tags
refreshAd() {
this.$refs.ad.innerHTML = '';
this.$refs.adGpt.innerHTML = '';
this.setAd();
},
But doesnt work
Does anyone have an idea?

Ok i figured it out so instead of clearing the inner HTML google provides a refresh attribute
so i just replaced
refreshAd() {
this.$refs.ad.innerHTML = '';
this.$refs.adGpt.innerHTML = '';
this.setAd();
},
with:
refreshAd() {
googletag.cmd.push(function() { googletag.pubads().refresh(); });
},

Related

How to get Paypal Checkout to work with Vue.JS 3

I am trying to make Paypal Checkout work with Vue.JS 3 (using the loader)
Right now I got this far:
setPaypal() {
const script = document.createElement('script');
script.src = 'https://www.paypal.com/sdk/js?client-id=AdlvqGHWrrwVpGXreZuf5VHBXjIeUWGLHBJmDzbI44Ib2w1MMN7P-UJysCHFb_W7BWTvpz0ofji0SiYB';
document.body.appendChild(script);
script.addEventListener('load', this.setLoaded())
}
This function is called in the mounted(): and inserts the script tag in my page.
setLoaded() {
window.paypal.Buttons({
createOrder: (actions) => {
return actions.order.create({
purchase_units: [
{
description: this.prestation.courtedescription,
amount: {
currency_code: "EUR",
value: this.total
}
}
]
});
},
onApprove: async () => {
this.paidFor = true;
this.loading = false;
},
onError: err => {
console.log(err)
}
})
.render(this.$refs.paypal)
}
This is the setLoaded() function called when the script is loaded.
Well obviously window.paypal is undefined
I tried using the official docs and same shit, they ask you to
const PayPalButton = paypal.Buttons.driver("vue", window.Vue);
But hey, paypal is not defined
For reference, this is the official docs
Add the SDK <script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID"></script>
Vue integration
<div id="container">
<app></app>
</div>
<script>
const PayPalButton = paypal.Buttons.driver("vue", window.Vue);
Vue.component("app", {
template: `
<paypal-buttons :on-approve="onApprove" :create-order="createOrder" />
`,
components: {
"paypal-buttons": PayPalButton,
},
computed: {
createOrder: function () {
return (data, actions) => {
return actions.order.create({
purchase_units: [
{
amount: {
value: "10",
},
},
],
});
}
},
onApprove: function () {
return (data, actions) => {
return actions.order.capture();
}
},
},
});
const vm = new Vue({
el: "#container",
});
</script>
Instead of using this in your setPaypal() function
script.addEventListener('load', this.setLoaded())
Use this
script.addEventListener('load', () => this.setLoaded())

Vuejs - show autocomplete suggestions while user digit

I have this js fiddle code. I want to create a suggestions autocomplete using vuejs. At the moment I've achived only in part the scope, I have a problem with the suggestions. They will be placed under the user input chars and it's not exactly what I was expecting, I want to do something similar to the autocompleto of a smartphone keyboard where the suggested words will be displayed while the user digit a word. Can anyone help me?
<div id="app">
<textarea id="input" v-model="input" #input="predictWord()"></textarea>
<span id="suggestion" ref="suggestion"></span>
</div>
#app {
.input {
position: relative;
}
#suggestion {
position: absolute;
left: 0;
}
}
Vue prototype code
new Vue({
el: "#app",
data() {
return {
input: null,
t9: null,
words: []
}
},
mounted() {
this.init();
},
methods: {
init() {
axios({
method: 'GET',
url: 'https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt'
}).then( (res) => {
this.words = res.data.split('\n');
this.t9 = Predictionary.instance();
this.t9.addWords(this.words);
});
},
predictWord() {
let suggestion;
this.countChars();
suggestion = this.t9.predict(this.input);
this.$refs.suggestion.innerText = suggestion[0];
},
countChars() {
console.log(this.input.length);
}
}
});
I created a working snippet: simplified it a bit, added a loading state (as the dictionary is quite large), updated the resulting output, so it's not dependent on any DOM element.
new Vue({
el: "#app",
data() {
return {
loading: false,
input: null,
t9: null,
suggestion: [],
}
},
mounted() {
this.init();
},
methods: {
async init() {
this.loading = true
try {
const {
data = ''
} = await axios({
method: 'GET',
url: 'https://raw.githubusercontent.com/napolux/paroleitaliane/master/paroleitaliane/660000_parole_italiane.txt'
})
this.t9 = Predictionary.instance();
const a = data.split('\n').filter(e => e)
this.t9.addWords(a)
} catch (err) {
console.error(err)
} finally {
this.loading = false
}
},
predictWord: _.debounce(function() {
this.suggestion = this.input ? this.t9.predict(this.input) : [];
}, 300),
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios#0.21.1/dist/axios.min.js"></script>
<script src="https://unpkg.com/predictionary/dist/predictionary.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.21/lodash.min.js"></script>
<div id="app">
<textarea id="input" v-model="input" #input="predictWord" :disabled="loading"></textarea><br />
<span id="suggestion">{{ suggestion.join(', ') }}</span>
</div>
Also added a debounce function, so the prediction doesn't have to run so many times - 300ms is a reasonable delay in my experience.

How to remove external JS when navigate to another page VUEJS

I have java script component in home component with external js. I need to remove external js when page navigate to another page. Page does not refresh.
<script>
function initFreshChat() {
window.fcWidget.init({
token: "***",
host: "https://wchat.freshchat.com"
});
}
function initialize(i,t){var e;i.getElementById(t)?initFreshChat():((e=i.createElement("script")).id=t,e.async=!0,e.src="https://wchat.freshchat.com/js/widget.js",e.onload=initFreshChat,i.head.appendChild(e))}function initiateCall(){initialize(document,"freshchat-js-sdk")}window.addEventListener?window.addEventListener("load",initiateCall,!1):window.attachEvent("load",initiateCall,!1);
</script>
This is the external js: https://wchat.freshchat.com/js/widget.js
I need this because i need to keep this freshchat window in one page.
This can be done by putting any condition. But it will works if we refresh the page. Here pages are not refreshing at all.
Therefore I need to remove the external js when navigate to another pages. And mount back when came to this page.
You can wrap the script in side a Vue component life circle,
render
remove
refresh
whenever you need.
I found this code on codepen https://codepen.io/akccakcctw/pen/LBKQZE
Vue.component("fc-button", {
template: "#fcButton",
props: {
fc: {
type: Object,
default: {},
}
},
methods: {
openWidget: function() {
document.getElementById("fc_frame").style.visibility = "visible";
window.fcWidget.open();
}
}
});
const vm = new Vue({
el: "#app",
data: function() {
return {
fc: {
isInit: false,
},
};
},
mounted: function() {
var self = this;
window.fcSettings = {
token: "8d3a4a04-5562-4f59-8f66-f84a269897a1",
host: "https://wchat.freshchat.com",
config: {
cssNames: {
widget: "custom_fc_frame",
open: "custom_fc_open",
expanded: "custom_fc_expanded"
},
headerProperty: {
hideChatButton: true
}
},
onInit: function() {
window.fcWidget.on("widget:loaded", function() {
self.fc.isInit = true;
window.fcWidget.on("unreadCount:notify", function(resp) {
console.log(resp);
test = resp;
if (resp.count > 0) {
// document.getElementById('notify').classList.add('h-btn-notify');
document.getElementById("notify").style.visibility = "visible";
} else if (resp.count == 0) {
// document.getElementById('notify').classList.remove('h-btn-notify');
document.getElementById("notify").style.visibility = "hidden";
}
});
window.fcWidget.on("widget:closed", function() {
document.getElementById("fc_frame").style.visibility = "hidden";
document.getElementById("open_fc_widget").style.visibility =
"visible";
});
window.fcWidget.on("widget:opened", function(resp) {
document.getElementById("open_fc_widget").style.visibility =
"hidden";
});
});
}
};
}
});

Dynamically binding title tag in vuejs

I'm new to vuejs.
I try to bind data on the title tag dynamically. I used vue-head to do this on a simple html page. I do not use webpack and npm.
This is how I bind the title tag :
var app = new Vue({
el: 'html',
head: {
title: function () {
return {
inner: this.remaining + ' Tâches',
separator: ' ',
complement: ' '
}
}
}
In the vue-head documentation, they suggest to do this :
methods: {
getAsyncData: function () {
var self = this
window.setTimeout(function () {
self.title = 'My async title'
self.$emit('updateHead')
}, 3000)
}
},
I also tried to set it in the watch prop, but it didn't work.
Here is my entire code : https://jsfiddle.net/5d70s0s6/1/
Thanks
Use a computed property.
computed: {
title: {
get() {
document.title = this.remaining
return this.remaining
},
set(val) {
document.title = val
}
}
}
You don't need to use <title>{{title}}</title>. If you change title in your Vue, it will be applied automatically to the page.
Also, you should not bind a Vue instance to html, head or body tags. Use regular elements only like <div id="app"></div> and set your Vue el: '#app'
Or you could use this:
data: {
title: '',
},
watch: {
title(val) {
document.title = val
}
}
Update:
While the code above can solve your problem. I created this tiny vue-title component that can be used in your project easily.
Example:
<vue-title>{{title}}</vue-title>

React js Stripe checkout is not working

I am trying to render a stripe checkout default form in React js application.
<form action="/your-server-side-code" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" className="stripe-button"
data-key="pk_test_oDALA0jNyxDzbRz5RstV4qOr"
data-amount="999"
data-name="test"
data-description="Widget"
data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
data-locale="auto">
</script>
</form>
Its not displaying anything and not getting error also.
How do i get that pay button and form.
The main issue you are probably having is loading a script within React.
One approach is to load the checkout script only when needed (assuming some form of spa), then just directly call it. This is akin to the "custom" version on the documentation page: https://stripe.com/docs/checkout#integration-custom
If you are already loading checkout.js (for example before your "app.js"), then the below can be simplified a bit by not manually loading in the script.
import React from 'react';
export default class Cards extends React.Component {
constructor(props:Object) {
super(props);
this.state = {
loading: true,
stripeLoading: true,
};
}
loadStripe(onload:Function) {
if(! window.StripeCheckout) {
const script = document.createElement('script');
script.onload = function () {
console.info("Stripe script loaded");
onload();
};
script.src = 'https://checkout.stripe.com/checkout.js';
document.head.appendChild(script);
} else {
onload();
}
}
componentDidMount() {
this.loadStripe(() => {
this.stripehandler = window.StripeCheckout.configure({
key: 'pk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
locale: 'auto',
token: (token) => {
this.setState({ loading: true });
axios.post('/your-server-side-code', {
stripeToken: token.id,
});
}
});
this.setState({
stripeLoading: false
});
});
}
componentWillUnmount() {
if(this.stripehandler) {
this.stripehandler.close();
}
}
onStripeUpdate(e:Object) {
this.stripehandler.open({
name: 'test',
description: 'widget',
panelLabel: 'Update Credit Card',
allowRememberMe: false,
});
e.preventDefault();
}
render() {
const { stripeLoading, loading } = this.state;
return (
<div>
{(loading || stripeLoading)
? <p>loading..</p>
: <button onClick={this.onStripeUpdate}>Add CC</button>
}
</div>
);
}
}
Chris's answer was excellent, however I had to make a few minor changes in order for the code to function. I've also removed the TypeScript function types (for those of us not using TypeScript). Comments are added where changes to the answer have been made. FYI this is my first post, please let me know if this should be a Comment instead of an Answer.
export default class Cards extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
stripeLoading: true,
};
// onStripeUpdate must be bound or else clicking on button will produce error.
this.onStripeUpdate = this.onStripeUpdate.bind(this);
// binding loadStripe as a best practice, not doing so does not seem to cause error.
this.loadStripe = this.loadStripe.bind(this);
}
loadStripe(onload) {
if(! window.StripeCheckout) {
const script = document.createElement('script');
script.onload = function () {
console.info("Stripe script loaded");
onload();
};
script.src = 'https://checkout.stripe.com/checkout.js';
document.head.appendChild(script);
} else {
onload();
}
}
componentDidMount() {
this.loadStripe(() => {
this.stripeHandler = window.StripeCheckout.configure({
key: 'pk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
locale: 'auto',
token: (token) => {
this.setState({ loading: true });
// use fetch or some other AJAX library here if you dont want to use axios
axios.post('/your-server-side-code', {
stripeToken: token.id,
});
}
});
this.setState({
stripeLoading: false,
// loading needs to be explicitly set false so component will render in 'loaded' state.
loading: false,
});
});
}
componentWillUnmount() {
if(this.stripeHandler) {
this.stripeHandler.close();
}
}
onStripeUpdate(e) {
this.stripeHandler.open({
name: 'test',
description: 'widget',
panelLabel: 'Update Credit Card',
allowRememberMe: false,
});
e.preventDefault();
}
render() {
const { stripeLoading, loading } = this.state;
return (
<div>
{(loading || stripeLoading)
? <p>loading..</p>
: <button onClick={this.onStripeUpdate}>Add CC</button>
}
</div>
);
}
}

Categories

Resources