How to set Wix to do a HTTP request upon an event - javascript

I have a Wix site and I have this JS code in the site:
import { fetch } from 'wix-fetch';
$w("#button1").onClick( (event) => {
var link = $w("#link").id;
console.log(link)
fetch("https://my-new-app-xyz.herokuapp.com?link="+link, {"method": 'get'})
.then((httpResponse) => {
if (httpResponse.ok) {
return httpResponse;
} else {
return Promise.reject("Failed");
}
} )
.catch( (err) => {
console.log(err);
} );
})
However, upon the click of button1 nothing happens. Hopefully, the code explains what I want to do, but, upon clicking button1. I want to get the value of the text box element with id link and send a GET request to "https://my-new-app-xyz.herokuapp.com?link=" + the link from the text box. I don't know much JavaScript - this code is from reading the Wix API docs.

Related

Page Leave Confirmation using React

I'm currently working on a project where I want to show a custom Dialogue box with my Own Content ("Save your data into drafts before leaving"). I have tried different methods but can't find a proper way to do it. I explore all the previous questions on StackOverflow but they didn't work properly in my case.
useEffect(() => {
return () => {
window.onbeforeunload = function() {
return "do you want save your data into drafts before leave?";
};
}
},[])
Currently, I've written the above code in Plain JavaScript to do, but it's just showing the dialogue box on tab close and reload while not showing on custom click events to navigate to other pages or window back button.
React can't help me in this because they remove useBlocker, usePrompt from new releases. How can I achieve it?
One way of doing this is :
import { Prompt } from 'react-router'
const MyComponent = () => (
<>
<Prompt
when={shouldBlockNavigation}
message='Do you want ot save data before leave?'
/>
{/* Component JSX */}
</>
)
If wants on page refresh or browser closing then add:
useEffect(() => {
if (shouldBlockNavigation) {
window.onbeforeunload = () => true
} else {
window.onbeforeunload = undefined
}
},[]);
Second way is to use history if using react-router
useEffect(() => {
let unblock = history.block((tx) => {
// Navigation was blocked! Let's show a confirmation dialog
// so the user can decide if they actually want to navigate
// away and discard changes they've made in the current page.
let url = tx.location.pathname;
if (window.confirm(`Are you sure you want leave the page without saving?`)) {
// Unblock the navigation.
unblock();
// Retry the transition.
tx.retry();
}
})
},[]);
useEffect(() => {
const unloadCallback = (event) => {
event.preventDefault();
event.returnValue = "";
return "";
};
window.addEventListener("beforeunload", unloadCallback);
return () => {
window.addEventListener("popstate", confirmation());
window.removeEventListener("beforeunload", unloadCallback);
}
}, []);
I just did it with this code sample (actually I combine two events to show dialogue whenever users leave a page) and it's working fine for me. Thanks to all of you guys ... Especially #DrewReese for the help

javascript ndefREADER doesn't load automatically

First of all, I have to say this is my first question on stack ;)
I am trying to implement a reading via NFC on my test web, but i dunno why, the ndefReader doesn't works on startup, i have to press any field on the web to get it loaded (or asked for permission).
BUT, if i wrote some alerts to check why it doen't reach the function on startup, it works!!! (of course, it show alerts before). I don't know if when I accept the alert, I am interacting with the web and that's why it works, but anyways, I dunno why this happens (I need to click anywhere before starting).
function iniciar() {
document.getElementById("input1").focus();
//alert("test before"); <--- IF i remove this, it doesnt works
document.getElementById("input1").addEventListener("blur", async () => {
try{
const ndef = new NDEFReader();
alert("before wait");
await ndef.scan();
alert("after wait");
ndef.addEventListener("readingerror", () => {
alert("Argh! Cannot read data from the NFC tag. Try another one?");
});
ndef.addEventListener("reading", ({ message, serialNumber }) => {
alert(`> Serial Number: ${serialNumber}`);
alert(`> Records: (${message.records.length})`);
});
} catch (error) {
alert("Argh! " + error);
}
},false);
To scan and write to NFC tags, you must first request the "nfc" permission while handling a user gesture (e.g a button click, or in your case the "alert" call). Once handled, the NDEFReader scan() and write() methods trigger a user prompt, if access was not previously granted.
Check out https://web.dev/nfc/#security-and-permissions to learn more.
Hopefully https://googlechrome.github.io/samples/web-nfc/ samples should help you as well.
scanButton.addEventListener("click", async () => {
console.log("User clicked scan button");
try {
const ndef = new NDEFReader();
await ndef.scan();
console.log("> Scan started");
ndef.addEventListener("readingerror", () => {
console.log("Argh! Cannot read data from the NFC tag. Try another one?");
});
ndef.addEventListener("reading", ({ message, serialNumber }) => {
console.log(`> Serial Number: ${serialNumber}`);
console.log(`> Records: (${message.records.length})`);
});
} catch (error) {
console.log("Argh! " + error);
}
});

Button Event not Triggering After Ajax Call

I'm working on a Kirby site and I followed the 'Load More' tutorial for a website blog I am working on. Everything is working; however, I am also using an AJAX call for my parent pages. (I'm using swup library).
Normally, I would bind an event after an AJAX request to the document using .on() in jQuery; however, I can't seem to figure out how to do the same within the template/new.js file in pure Javascript.
Here's my code as per the tutorial:
const element = document.querySelector('.articles');
const button = document.querySelector('.load-more');
let page = parseInt(element.getAttribute('data-page'));
console.log(element.getAttribute('data-page'))
const fetchArticles = async () => {
let url = 'news.json/page:2';
try {
const response = await fetch(url);
const {
html,
more
} = await response.json();
button.hidden = !more;
element.innerHTML += html;
page++;
} catch (error) {
console.log('Fetch error: ', error);
}
}
button.addEventListener('click', fetchArticles);
Any help is greatly appreciated.

Why IFrame does not load on a single click on container div?

Background:
Working on Cybersource Credit Card integration with React app. Need to show Masked card number coming from API response upon tabbing out (onBlur) of field.
Flow
Created a container-div in which IFrame gets loaded and I enter CC number. On blur event, doing API calls for validation and getting the masked card number (if successfully validated).
Upon setting maskedCardNumber, component gets re-rendered and shows the maskedCardNumber in the container-div. At this point I see in Elements tab, IFrame is gone which is perfectly fine to me. Now in my container div there is no IFrame but a masked card number.
I want to change CC number
I click on input alike div and masked card number gets removed because of setMaskedCardNumber("");. ( Not each character one by one but all in once as we do not have that card number). Till this point everything is fine.
Problem
After removal, it should show new Iframe because I am calling loadIFrame(); like I did for initial Iframe loading but weirdly it does not show until I click AGAIN. YES!! you read it right. I need to click AGAIN to load and IFrame which is very weird for me.
Tried so far
useState(),
useReducer(),
to make <label>{maskedCardNumber}</label> inside container-div.
Changing conatiner-div <div> to <input>
Relevant code
useEffect(() => {
if (apiKey) {
loadIFrame();
}
}, [apiKey])
const loadIFrame = () => {
let flex;
flex = new Flex(apiKey);
let microform = flex.microform();
let number = microform.createField('number', {
placeholder: 'Enter card number'
});
number.on('load', () => {
number.focus();
});
number.on('blur', () => {
//transient token call
microform.createToken({}, function(err, token) {
if (err) {
console.error(err);
setCardError({
...error,
token: "Please enter valid CC number"
})
} else {
setCardError({
...error,
token: ""
});
//permenant token call
setMaskedCardNumber(JSON.parse(atob(token.split('.')[1]))["data"]["number"]);
dispatch({
type: orderActions.GET_CC_TOKEN,
transientToken: JSON.parse(atob(token.split('.')[1]))['jti'],
callbacks: {
success: (ccToken) => {
updateCardDetail({
type: "token",
token: ccToken
})
},
failure: (err) => {
console.error(err);
setCardError({
...error,
token: "Please enter valid CC number"
})
}
}
})
}
})
});
number.load('#number-container');
}
<div id="number-container" className="form-control" onClick={() => {
setMaskedCardNumber("");
loadIFrame();
}}>
{maskedCardNumber}
</div>
Problem I see here is basically the response to your setMaskedCardNumber() call returns after the iFrame is loaded due to its async nature.
Try putting this effect
useEffect(()=>{
if(maskedCardNumber === ""){
loadIFrame()
}
}, [maskedCardNumber])
and remove loadIFrame(); from onClick() handler
this will make sure whenever you empty the cardNumber state, iFrame is loaded when it is successfully emptied.
UPDATE:
We can make use of single useEffect.
useEffect(() => {
if (apiKey && !maskedCardNumber) {
loadIFrame();
}
}, [apiKey, maskedCardNumber])
With this we can make sure to load IFrame only if apiKey present otherwise do not try to load because IFrame is dependant on apiKey.

CKEditor 5 Insert text on button click - Pure JS

I'm trying to create a sort of dropdown menu that a user can insert tokens into a CKEditor with. I've found that I can insert text in an editor with this code:
editorInstance.model.change( writer => {
let pos = editorInstance.model.document.selection.getFirstPosition();
writer.insertText( "TEST", pos,0);
});
It works when I put it in the ClassicEditor.create.then for testing but it does nothing when I place this in a $().click event. I can log something from inside the callback so I know the code is executed but nothing is inserted.
I've been trying to get this working for hours now but all the examples I can find is in angular or any other frameworks.
I Solved the issue you faced as follows
first defined new editor that is null and Then instatiate Ckeditor 5
let neditor = null;
ClassicEditor.create(document.querySelector('#editor'))
.then(editor => {
neditor = editor;
})
.catch(error => {
console.error(error);
});
using pure js
document.addEventListener("click", (event) => {
var button = event.target;
if (event.target.type === 'button' && event.target.className.includes('testtokenbutton')) {
neditor.model.change(writer => {
const insertPosition = neditor.model.document.selection.getFirstPosition();
writer.insertText(button.id, insertPosition);
});
}
});

Categories