Javascript onclick do not execute until click - javascript

I am working in Microsoft Framework to create an application customizer which can only contain html code as a string. I created the html I want to render and need to add some functionality to open a link via a javascript method givien by Microsoft Teams. The main problem though is that it fires directly. I usually add an addListener to the method, but since it has to be HTML in a .ts file I cannot do that. So I am wondering except for that method what else would prevent the browser from triggering my openLink function from executing immediately.
I also cannot use React code where it would be as simple as onClick={() => sth(1)}.
My Code:
private _renderTopBar(navData, context) {
const { logoUrl, navigation } = navData;
let logo = logoUrl.replace('-my', '');
function openLink(url) {
console.log('got executed...')
}
return `
<section class="${styles.top}">
<div class="${styles.headerRow}">
<div class="${styles.mainHeader}">
<div class="${styles.logoCell}"><img src="${'https://one365demo.sharepoint.com/:i:/r/Style%20Library/hublogo.png'}" /></div>
<div class="${styles.titleCell}">
Start
</div>
</div>
</section>
`;
}
Any help would be much appreciated. Cheers!

Related

How do I fire a function from when a button is clicked on one html page, to load content dynamically on another html page?

I am building an app using HTML, CSS and vanilla JS to help learn my way around the languages and I have been stuck on a problem for a while.
Basically I have an index.html page that populates with football fixtures when a button is clicked. This works fine.
Then, when a certain fixture button is clicked, I want to pull specific data for that specific fixture and display it on a different page when loaded. The button click loads a new html page, but then should populate that page with the relevant fixture data.
Through lots of trial and error, only part of the function works. There is quite a lot of code from between HTML and JS so I don't want to share too much to make this more complex, as I am sure I am probably missing something simple.
But, here is the code that picks up the unique fixture id from the fixture card that is clicked on the index.html page.
const matchButton = document.querySelectorAll(".match-button");
for (i = 0; i < matchButton.length; i++) {
matchButton[i].addEventListener("click", (e) => {
let matchID = localStorage.setItem("matchID", e.target.id);
stats
.getFixture(e.target.id)
.then((fixtureData) => {
updateQuizMatchData(fixtureData);
})
.catch((err) => {
console.log(err);
});
document.location.href = "/quiz.html";
});
}
};
Originally, I did not store anything in localStorage, I just tried to call the function that makes an API call from the id directly. But the function doesn't seem to fire. it seems to break at setting the localStorage part. Is this because of the page load to a new page?
I stored the id in localStorage thinking that I could pull from that via another js file attached to the quiz.html page. As you can probably see, I am overcomplicating things maybe?
Anyhow, this is code above is meant to load the quiz.html page and then display the specific fixture related data from the fixture button that is clicked.
The code fires and updates localStorage and loads the quiz.html page. So I know it works to that point. But the other code does not fire. The other code that is meant to fire is an API call, followed then by this to update the quiz.html page dynamically...(not sure if this code is relevant to the issue I am seeing, as the API function call is not being fired either, which is why this below may not fire)
const updateQuizMatchData = (fixtureData) => {
console.log(fixtureData);
let date = "11-11-2001";
console.log(date);
teams.innerHTML = `
<div class="home-team m-4 pl-6">
<img
class="team-badge w-40 h-40"
src="${fixtureData.teams.home.logo}"
alt="home-team"
/>
<p
class="home-score text-center text-6xl m-6 bg-red-500 rounded-lg text-white p-6 shadow-xl"
>
${fixtureData.goals.home}
</p>
</div>
<div class="vs-text pt-20">
<p class="text-center text-6xl font-extrabold p-4">VS</p>
<p class="location text-center">${fixtureData.fixture.venue.name}</p>
<p class="date text-center">${date}</p>
</div>
<!-- Away team detail section -->
<div class="away-team m-4 pr-6">
<img
class="team-badge w-40 h-40"
src="${fixtureData.teams.away.logo}"
alt="away-team"
/>
<p
class="away-score text-center text-6xl m-6 bg-lime-500 rounded-lg text-white p-6 shadow-xl"
>
${fixtureData.goals.away}
</p>
</div>
`;
};
I know this doesnt fire because the console does not log the data at the top. All that happens is my quiz.html page loads my dummy content.
I have been battling this for a while and getting frustrated. What am I missing? Or not doing correctly?
I have tried moving code onto a separate js file but this has no impact. I also have attempted to fire the above function via window.load, but this doesn't fire it either. The introduction of localStorage was also to see if I could just fire a function from page load using localStorage ID that I set from button click as the parameter in the API call I make to get the specific fixture data. I hope this makes sense.
What am I missing?
How can I update the quiz.html from a specific fixture button that is clicked?

how can i use ejs variables from other file

i am trying to do spa and i am kind of stacking in this code
import AbstractView from "./AbstractView.js";
export default class extends AbstractView {
constructor(params) {
super(params);
this.setTitle("Profile");
}
async getHtml() {
return `
<main>
<center>
<div class="profile-page">
<img src="" alt="astro" style="border-radius: 50%;margin-right: 15px;">
<h1 style="font-size: 20px;"><%= client.user.username %></h1>
<h3>Select server to start managing</h3>
<br>
<button class="button_support">Support</button>
</div>
</center>
</main>
`;
}
}
This is taking from github source and what i am trying to do is i want to show ejs variable in the html and this what happen:
problem
if you have any question about the code ask and a will text you back thank you!
Since I don't see where you are rendering from with ejs, I can't see much;
These are some key things to check:
Make sure the variable in the ejs file matches very well with what you have rendered in the server. It's case sensitive and you should in fact copy and paste. Also, don't keep those variables or const in quotes ", it's also a common mistake;
It will be very helpful if you can share the exact error message you are getting.

Facebook event plugin in react.js disappears after click to another page link

I've been trying to get the Facebook event plugin to work in my create-react-app and can't figure it out.
In my Events.js file I added this:
<div id="fb-root"></div>
<div className="fb-page" data-href="https://www.facebook.com/[artistname]" data-tabs="events"
data-width="" data-height="" data-small-header="true" data-adapt-container-width="true"
data-hide-cover="false" data-show-facepile="true">
<div className="fb-xfbml-parse-ignore">
<blockquote cite="https://www.facebook.com/[artistname]/events">
[artistname] - coming events
</blockquote>
</div>
</div>
The SDK is imported in index.html
Everything works fine when I load the actual events page, but after clicking on "Start" and going back to "Events" the plugin disappears.
Some say to put
componentDidMount(){
window.FB.XFBML.parse()};
}
in the component, but my Event.js is a function.
I'm running out of google links now, any help is appreciated.
Easiest solution is to use the iframe option, but that doesn't directly answer your question.
Answer 1: use the useEffect hook
Example CodeSandbox here
Instead of using the componentDidMount lifecycle method from class components, you can use the useEffect hook:
useEffect(() => {
window.FB.XFBML.parse();
}, []);
This will call window.FB.XFBML.parse once per render.
Note: You may want to wrap that with an if (window.FB) to catch instances where window.FB didn't load
Answer 2: Convert to class component
You can of course convert your component to the old class based style:
export default class Events {
componentDidMount() {
window.FB.XFBML.parse();
}
render() {
return (
<>
{/* ... */}
<div
className="fb-page"
data-href={`https://www.facebook.com/${artistName}`}
data-tabs="events"
data-width=""
data-height=""
data-small-header="true"
data-adapt-container-width="true"
data-hide-cover="false"
data-show-facepile="true"
>
<div className="fb-xfbml-parse-ignore">
<blockquote cite={`https://www.facebook.com/${artistName}/events`}>
<a
href={`https://www.facebook.com/${artistName}/events`}
target="_blank"
>
{artistName} - coming events
</a>
</blockquote>
</div>
</div>
</>
);
}
}

React: How to use same component twice in same page but loading one script tag for both just one time

I created a react component that I want to use twice(or more) inside my page, and I need to load a script tag for it inside the head of my page but just once! I mean even if I use the component twice or more in the page it should add the script tag just once in the head.
The Problem is that this script tag should be absolutely a part of the component and not statically inserted in the head of my page.
Can anyone help me to make the magic happens? Thanks a lot in advance!
You can give react-helmet a try for managing changes to your <head> from within React components.
In particular, you can check this example where rendering the same element four times only adds the script tag once.
For completeness, the relevant code from the example (although the interesting part is to see how it executes):
import { Helmet } from "react-helmet";
function ComponentWithHeader() {
return (
<div>
<div>Oh hi</div>
<Helmet>
<script src="fake-url.js" />
</Helmet>
</div>
);
}
const App = () => (
<div>
<ComponentWithHeader />
<ComponentWithHeader />
<ComponentWithHeader />
<ComponentWithHeader />
</div>
);
You can set the state of the parent component to keep in memory that the script is already added.
if (!this.state.scriptAdded) {
// Add script tag
this.setState({ scriptAdded: true });
}

What is an elegant way to initialize multiple react-live components from a static website?

I'm currently creating a react component library that i want to provide as an npm package. I also want to provide a documentation that features fancy live rendering of the available components on e.g. github pages.
For the live editing feature i'm planning to use react-live which provides multiple react components to display a live editor and a preview. See an example from the styled-components docs how this looks like.
The react-live component accepts a string code containing the initial code that should be displayed in the editor and a list of components scope that can be used inside the live editor.
Now i want to use gohugo or a similar static site generator to deploy my documentation. I thought i could maybe provide a <div> inside my static site that has a special class react-live-demo and i will get these containers with document.getElementsByClassName('react-live-demo'), loop over them and render the react-live component into it.
I created a code snippet that shows a little example:
const {LiveProvider, LiveEditor, LiveError, LivePreview} = window['react-live'];
// a random component that i want to render in the live editor
const MyComponent = () => (
<div>
<h1>react live demo</h1>
<p>This is a component from the script tag.</p>
</div>
);
// a wrapper for the react-live editor
const Editor = ({code, scope}) => (
<LiveProvider code={code} scope={scope}>
<div className="live-example row">
<div className="col-xs">
<LiveEditor />
<LiveError />
</div>
<div className="col-xs">
<LivePreview />
</div>
</div>
</LiveProvider>
);
// get all containers that have the initial code as innerHTML
const examples = document.querySelectorAll('script[data-name="react-live"]');
examples.forEach(example => {
// insert a new div before the script tag
const container = document.createElement('div');
example.parentNode.insertBefore(container, example.nextSibling);
// render the editor with the code from the script tag
const code = example.innerHTML.trim();
ReactDOM.render(<Editor code={code} scope={{MyComponent}} />, container);
});
.static-content {
background-color: papayawhip;
}
.live-example {
border: 1px solid orange;
}
.react-live-demo.code {
display: none;
}
.invalid {
color: red;
}
<p class="static-content">HERE IS SOME STATIC HTML CONTENT</p>
<script type="text/html" data-name="react-live">
<div>
<h1>react live demo</h1>
<p>This code is editable.</p>
</div>
</script>
<p class="static-content">SOME MORE STATIC HTML CONTENT</p>
<script type="text/html" data-name="react-live">
<MyComponent />
</script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/flexboxgrid/6.3.1/flexboxgrid.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://unpkg.com/react-live#1.7.0/dist/react-live.min.js"></script>
The question is now:
How do embed the code string into my static site so that i can grab it with my js code and pass it to my react-live component?
I thought about <pre> or something like that. Or should i just embed it as inner html and read that? But then it would be displayed for short when the react component hasn't rendered yet. Or should i use some sort of script tag and make it available as globals? The key goal is to make it as easy as possible to add live editing examples to the documentation without touching any javascript code.
However if i pass something like <MyComponent /> as innerHTML this does of course not work as you can see in the code snippet.
Any best practice for that use case appreciated.
EDIT:
Based on the suggestion of #Daniel Alexandrov i edited the code snippet. The solution now reads the innerHTML of script tags with type="text/html set and creates a <div> container to insert the editor. This seems to work quite well. Any more ideas?
In my opinion the best choice is to use the <script> tag with a custom type attribute. Take a look at the Knockout.js template binding which uses type="text/html or the Angular <script type="text/ng-template">
This way the browser will ignore the script tag completely, because it doesn't know how to interpret it.

Categories

Resources