How to call a function which defined in external script in react - javascript

I am new to reactjs.
I am trying to add a external script and trying to use a function which defined inside that script.
Script is
<script src="https://pi-test.sagepay.com/api/v1/js/sagepay.js"></script>
<script>
document.querySelector('[type=submit]').addEventListener(
'click',
function (e) {
e.preventDefault(); // to prevent form submission
sagepayOwnForm({
merchantSessionKey: '5528D329-A83B-435F-B6A7-E38A2BC60DC9',
}).tokeniseCardDetails({
cardDetails: {
cardholderName: document.querySelector(
'[data-card-details="cardholder-name"]'
).value,
cardNumber: document.querySelector(
'[data-card-details="card-number"]'
).value,
expiryDate: document.querySelector(
'[data-card-details="expiry-date"]'
).value,
securityCode: document.querySelector(
'[data-card-details="security-code"]'
).value,
},
onTokenised: function (result) {
if (result.success) {
document.querySelector('[name="card-identifier"]').value =
result.cardIdentifier;
document.querySelector('form').submit();
} else {
alert(JSON.stringify(result));
}
},
});
},
false
);
</script>
I tried with useScript. When user click the submit button the script will loaded and should call
sagepayOwnForm ( this is a defined in their script.js)
I create a useScript
export const useScript = (url: string) => {
useEffect(() => {
const script = document.createElement('script');
script.src = url;
script.async = true;
// script.on
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
}
}, [url]);
};
I don't know how to use this. I want to know How can I call their function.
Can anyone help me.

Related

clevertap event not trigger in javascript

I have to create subscribe and unsubscribe email page. all functionality is working fine. but when I call clevertap event, CT event is not triggered in CT dashboard.
<script type="text/javascript">
var clevertap = {
event: [],
profile: [],
account: [],
onUserLogin: [],
notifications: [],
privacy: [],
};
// replace with the CLEVERTAP_ACCOUNT_ID with the actual ACCOUNT ID value from your Dashboard -> Settings page
clevertap.account.push({ id: "TEST-000-000-001Z" });
clevertap.privacy.push({ optOut: false });
clevertap.privacy.push({ useIP: true });
(function () {
var wzrk = document.createElement("script");
wzrk.type = "text/javascript";
wzrk.async = true;
wzrk.test = 'page';
wzrk.src =
("https:" == document.location.protocol
? "https://d2r1yp2w7bby2u.cloudfront.net"
: "http://static.clevertap.com") + "/js/a.js";
var s = document.getElementsByTagName("script")[0];
console.log('s.parentNode : ', s.parentNode)
s.parentNode.insertBefore(wzrk, s);
wzrk.onerror = (e) => reject(new Error(`Failed to load script '${src}'. Error: ${e.toString()}`));
})();
</script>
onload I have call page view event
<script>
window.onload = function () {
console.log('on load');
var isReEncode = false; //Should be true only if your server is url encoding the URL on unsubscribe landing page
var withGroups = true; // Should be true if the unsubscribe groups should be displayed on the landing page.
var stageName;
$WZRK_WR.getEmail(false, withGroups);
showSectionBaseOnStage();
setTimeout(() => {
clevertap.event.push("Page viewed", {
"ProductName": "ABC",
"PageTitle": "Unsubscribe",
"Page": 'Group Unsubscribe',
"PageURL": window.location.href,
"SourceURL":""
});
console.log("on load ct event call", clevertap);
}, 5000);
};
</script>
Page viewed event not trigger
Please let me know where I do a mistake.
Thank you

CK Editor Laravel Livewire

Is there anyway for Laravel Livewire to make my CKEditor the same behavior as a wire:model.lazy? currently I have a script tag that listens for any changes. Which causes for every type a request towards the component..
<script>
ClassicEditor
.create(document.querySelector('#body'))
.then(editor => {
editor.model.document.on('change:data', () => {
#this.set('body', editor.getData());
})
})
.catch(error => {
console.error(error);
});
</script>
The behavior I want is either a button or everytime I lose focus on the CKEditor the $body will be updated.
Just listen to the submit button and update the value on click:
let editor;
ClassicEditor.create(document.getElementById('post'), {
// configs
})
.then(newEditor => {
editor = newEditor;
})
.catch(error => {});
document.querySelector('button[type="submit"]').addEventListener('click', function () {
#this.set('post', editor.getData());
});
For me and anybody else who have the same issue
The main issue here is on.change this piece of code on( 'change:data'... will make the editor send post request on every single key press.
Solving the issue.
<script>
let body_changed = false;
ClassicEditor
.create(document.getElementById('body'), {})
.then(editor => {
window.body = editor;
detectTextChanges(editor);
detectFocusOut(editor);
})
function detectFocusOut(editor) {
editor.ui.focusTracker.on('change:isFocused', (evt, name, isFocused) => {
if (!isFocused && body_changed) {
body_changed = false;
#this.set('body', editor.getData());
}
})
}
function detectTextChanges(editor) {
editor.model.document.on('change:data', () => {
body_changed = true;
});
}
</script>
Hope this will help me and others in future :)

Cannot get instance of CKEditor

I have several fields which need to be initialized with CKEditor, for this I have created an helper class that contains the initEditor method.
The method below should return the initialized editor but it doesn't:
window.CKEditorHelper = window.CKEditorHelper || {};
(function (exports) {
exports.initEditor = function (input, myEditor) {
ClassicEditor
.create(document.querySelector(input), {
language: {
ui: 'en'
content: 'en'
}
})
.then(editor => {
myEditor = editor;
});
};
})(window.CKEditorHelper);
this is called in the following way:
let editor = null;
CKEditorHelper.initEditor('#description', editor);
so when I click on a button:
$('#save').on('click', function(){
console.log(editor.getData());
});
I get:
Cannot read property 'getData' of null
what I did wrong?
There are some issues on your code
let editor = null;
the let keyword only define a variable within function scope, when you use editor on another scope (your click handle event), it could be undefined
Another line
myEditor = editor;
This just simple made the reference to your original editor object will gone
Here is my solution to fix it
Change the way you init an editor like bellow
window.editorInstance = {editor: null};
CKEditorHelper.initEditor('#description', editorInstance);
Change your CKEditorHelper to
window.CKEditorHelper = window.CKEditorHelper || {};
(function (exports) {
exports.initEditor = function (input, myEditorInstance) {
ClassicEditor
.create(document.querySelector(input), {
language: {
ui: 'en'
content: 'en'
}
})
.then(editor => {
myEditorInstance.editor = editor;
});
};
})(window.CKEditorHelper);
And when you want to use your editor
console.log(editorInstance.editor.getData());
You can give this in javascript
$(document).ready(function () {
CKEDITOR.replace('tmpcontent', { height: '100px' })
})
take the value by using following
$('#save').on('click', function(){
var textareaValue = CKEDITOR.instances.tmpcontent.getData();
});
<label class="control-label">Message</label>
<textarea name="tmpcontent" id="tmpcontent" class="form-control"></textarea>
//OR in latest version
var myEditor;
ClassicEditor
.create( document.querySelector( '#description' ) )
.then( editor => {
console.log( 'Editor was initialized', editor );
myEditor = editor;
} )
.catch( err => {
console.error( err.stack );
} );
and then get data using
myEditor.getData();

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>
);
}
}

Firefox Extension trouble using port.emit and port.on

I can't seem to get port.emit working correctly with my Firefox extension. From the init() function in popup.js the messages are correctly sent to main.js using addon.port.emit. Once they've been sent, the giveStorage message is correctly received in popup.js. However, this only works correctly when the original message is sent in the init function.
When I try sending the messages using using the jQuery change listener, the logs "Storage has been set." and "Sending storage to popup.js" come through, so popup.js is just not receiving it, but I have no idea why not. Only messages are logged correctly when ran from the init function.
If anyone has any ideas, or if you need any more information, please let me know and I'll see what I can do. Any help is greatly appreciated!
main.js
panel.port.on("setStorage", function (text) {
console.log("Storage has been set.");
ss.storage[text[0]] = text[1];
})
panel.port.on("getStorage", function (text) {
console.log("Sending storage to popup.js");
panel.port.emit("giveStorage", [text, ss.storage[text]])
})
popup.js
function init(){
$(".panel").hide();
addon.port.emit("getStorage", "username");
addon.port.emit("getStorage", "volume");
setInterval(function(){following();}, 60000);
}
addon.port.on("giveStorage", function (text) {
console.log("Message received from main.js");
if (text[1] !== null) {
if (text[0] === "username") {
username = text[1];
$('#menuFollowing').click();
}
else if (text[0] === "volume"){
volume = text[1];
$("#volume").val(volume);
$('#volumeValue').empty();
$('#volumeValue').append('Volume: ' + volume);
}
}
})
$('#volume').change(function(){
volume = $('#volume').val();
addon.port.emit("setStorage", ["volume", volume]);
addon.port.emit("getStorage", "volume");
});
Complete main.js
var { ToggleButton } = require('sdk/ui/button/toggle');
var panels = require("sdk/panel");
var self = require("sdk/self");
var ss = require("sdk/simple-storage");
var notifications = require("sdk/notifications");
var panel = panels.Panel({
width: 500,
height: 500,
contentURL: self.data.url("popup.html"),
onHide: handleHide,
});
var button = ToggleButton({
id: "hitbox-plus",
label: "hitbox Plus",
icon: {
"16": "./icon16.png",
"48": "./icon48.png",
},
onChange: handleChange,
});
function handleChange(state) {
panel.contentURL = self.data.url("popup.html");
if (state.checked) {
panel.show({
position: button
});
}
}
function handleHide() {
button.state('window', {checked: false});
}
panel.port.on("getStorage", function (text) {
console.log("Sending storage to popup.js");
panel.port.emit("giveStorage", [text, ss.storage[text]])
})
panel.port.on("setStorage", function (text) {
console.log("Storage has been set.");
ss.storage[text[0]] = text[1];
})

Categories

Resources