How do I import html into another html document? - javascript

I'm trying to keep my nav in one html file rather than copying and pasting it into every file so I don't have to edit every file if I want to change something. I want to include the nav code into my files but nothing I've tried so far has worked the way I want it to. I would like to do this using only html/css/js, this is something that seems like there would be an easy way to do it because it's so practical in a lot of projects.
So far I've tried
object/iframe - Embedded the code into it's mini window, not the desired result.
javascript object.write - Deleted code already in file being imported to.
w3.includehtml - Works in firefox, but not chrome, I can't figure out why. Help with this would be appreciated as this seems like the best method.
php include- Didn't work, probably because I don't know php and most likely did something wrong, I'm open to it if someone could show me how or link a tutorial.

create the component as a template, like:
nav.template.html
<template>
<nav><!-- nav stuff here ... there has to be only one childNode of template because of how we will mount it, but you could change that -->
<style scoped>/* you can style only nav content directly here if you like */</style>
</nav>
</template>
Then, load that with javascript on domready, like:
site.js
document.addEventListener('DOMContentLoaded', function() { // there are more thorough, extensible ways of attaching to this event ..
let el = document.querySelector('.nav-mount-point')
// I'm doing to use axois, assuming you load it from a CDN or directly. You could also do this with plain AJAX, etc
axios.get('path/to/nav.template.html')
.then(res => {
let dt = document.createElement('div')
dt.innerHTML = res.data
el.appendChild(dt.children[0].content.cloneNode(true))
})
.catch(e => console.error(e))
}, false);

Related

React, loading a script inside a form (mercadopago)

I am trying to implement some payment system (MercadoPago).
According to the doc, it's just pasting this:
<form method="POST">
<script
src="https://www.mercadopago.com.pe/integrations/v1/web-payment-checkout.js"
data-preference-id="589788715-2e52aeec-8275-487c-88ee-1a08cff37c08"
></script>
</form>
Pasting it in a pure html file works fine: a button appears and clicking it opens a modal to pay with a credit card as expected. However this doesn't work in React since it's dynamically loading a script. Hence, I tried using an effect hook to insert the <script> on load as such:
const App = () => {
const setMercadoPagoPreferences = async () => {
const script = document.createElement('script');
script.src =
'https://www.mercadopago.com.ar/integrations/v1/web-payment-checkout.js';
script.async = true; // commenting or uncommenting seems to have no effect
script.setAttribute(
'data-preference-id',
'589788715-2e52aeec-8275-487c-88ee-1a08cff37c08'
);
document.getElementById('mercadoForm').appendChild(script);
};
useEffect(() => {
setMercadoPagoPreferences();
}, []);
return <form action='/procesar-pago' method='POST' id='mercadoForm' />;
};
This loads correctly the script, it seems, as a button to pay is appended to the page. Clicking it however opens a modal that says "oh no, something bad happened". This doesn't happen on my .html example above; so it must be because of how React is loading the script or something like that. It doesn't work on either the dev or the production build.
Edit: As suggested, I tried using refs instead of directly appending childs but this did not seem to have any impact, it still won't work.
I dont know this framework but maybe thats the way: It looks like this guy has similar problem right here.
I think there is problem because script does not load on time. So maybe lets try this:
script.onload = () => {
document.getElementById('mercadoForm').appendChild(script);
};
In addtion there is build in mechanism in react ref like HERE instead of document.getElementById
Your technique would've work if it weren't for mercadolibre.
Apparently, the use of the page you are trying to load is not allowed by mercadolibre. It's like you're trying to load mercadolibre inside an Iframe which they probably blocked using CSP header. Specifically they are setting the Content-Security-Policy tag to frame-ancestors 'self'. It's a security restriction standard that does not allow the use of pages from that domain within elements Iframe.

Handling onClick of a <a> tag inside of dangerouslySetInnerHTML/regular html

I am currently writing a reddit client inside of ReactJS plus electron. I am simply doing this to understand apis better and to understand programming a large scale program. However I am becoming stuck when trying to render markdown. I have imported markdown to jsx libraries but none of them (unless I am using them wrong) have allowed me to properly convert the reddit markdown into a component I can work with.
For example from the reddit api, I receive a comment like this:
Hi mi name is John Doe, and I want you guys to check out [Reddit](http://www.reddit.com) Also don't be afraid to check out [Google](http://www.google.com)
Now I have tried using npm modules that convert markdown into jsx, this works and will render the markdown, but I need to be able to interact with the onClick methods. Simple because this is running in an electron window, and navigating the whole browser window will navigate away from my program. Current I have it working with the following code, but this is very slow and calls the webview over 100 times.
...
// On click of an a, this gets called a couple hundred times. :(
componentDidMount() {
var self = this;
$('.linkHandler a').click(function (e) {
e.preventDefault();
// Opens my own custom electron webview
self.props.loadURL(e.target.href)
})}
...
render(){
return(
<div className="linkHandler">
{<ReactMarkdown source={comment.body} />}
</div>
)
}
}
I just want to be able to add an onClick handler to all of the tags in my markdown. Reddit also supplies the html of the markdown already, but alas I am still in the same spot. With the html version I also tried doing the following:
onClick(){
console.log('onClick Called');
}
...
getHTMl(){
// Quickly tpyed this from memory, just keep in mind the original replaced every <a with <a onClick=""
return comment.body_html.replace(/<a/g,'<a onClick="' + this.onClick + '"');
}
...
render(){
return(
<div setInnerHTMLDangerously={{"__html":this.getHTML()}}
)
}
}
Tried adding () to the onClick but it gets called (100s of times) before clicking the button. The way it is now, it returns error: null reference (or something like that) in the console on click.

Javascript/Jquery How to compare ID's and if true, not call a function

I have a Javascript imported a snow.js file that displays "Snow falling" across the screen for when it's winter. But If I choose a summer theme on the same page it will still display the Snow falling.
<script src="js/snow.js" type="text/javascript"><script>
Is their a way to create a Javascript code so if i click on a summer theme it will remove/comment the imported file and add/re-move commenting on the imported file when I click on a winter theme?
Edit:
I am using snowstorm.JS plugin realized I can call a function "snowStorm.toggleSnow()" via script. But I need to adjust it, so if they click on my css button "Summer" whilst on the theme summer it will do nothing.
I created this Jquery/JS code but it doesn't work. I believe it's the brackets but not sure. It should solve the problem.
Update:
I got it working, so If the user clicks a button it will "Toggle" the snowstorm effect on and off.
$("#Summer").click(function(){
snowStorm.toggleSnow()
});
$("#Winter").click(function(){
snowStorm.toggleSnow()
});
Is there a way of introducing if loops, so if the user clicks on the same button, eg: ID "Summer" whilst on the same ID/CSS "Summer" it will not toggle the snowstorm?
Use JS or jQuery to remove the tag.
For example, in jQuery:
$("#summerThemeButton").click(function() {
$("script[src=js/snow.js]").remove();
});
However, as #IgorRaush commented, there's probably a better way to change the theme (probably by a JS API) than to remove the script for it completely.
EDIT
As the comments suggest, it's not so easy to remove a JS file by removing the <script> tag. It is already executing code. The best way is to use the functions that came with it to stop it. Maybe you want to check if there are functions, such as:
var stopSnow = function() { /* ... */ };
var changeTheme = function(newTheme) { /* ... */ };
If there are truly no API functions (if you found an API; if you wrote it yourself just write a function!) then your best bet might be to remove all relevant/global variables and functions:
// for example, if you had a running function `snow()` or a global variable to make it snow:
snow = null;
theme = null;
Sorry there's no better way (I know of) to remove a script.
you can use $.getScript in jQuery to conditionally load the file. See more at http://api.jquery.com/jQuery.getScript/

JQuery load() will break facebook like button/comment box. How to workaround?

I am coding a big website but I have cut down my problem into the following tiny html file:
http://dl.dropbox.com/u/3224566/test.html
The problem is that if I (re)load with JQuery a content that features a facebook code, the latter won't appear, even if I reload the script (leading to a duplication of that all.js script, which is another issue).
How can I fix this?
Regards,
Quentin
Use the FB.XFBML.parse() docs after you load the new content
function loadPage() {
$('#test').load('test.html #test', function() {
FB.XFBML.parse( );
}).fadeOut('slow').fadeIn('slow');
}
Note, that loading a fragment with id test in a div with id test will create multiple (two) elements with the same id (nested in each other) in the page, which should never happen as it is invalid.
To avoid this use the more verbose $.get method
$.get('test.html',
function(data) {
var temp = $('<div>').html(data).find('#test');
$('#test').html(temp.html());
}
);

JQuery isn't recognising a #id selector, seems to be dependent on the URL

I'm writing a Ruby on Rails app. The following jQuery code is included in the head tag of the index.html.erb file, which is the template for all pages on the site.
<script>
$(document).ready(function() {
$("#select_mailshot").click(function () {
alert('mailshot');
document.location.href = "/products/1";
});
$("#select_blog").click(function () {
alert('blog');
document.location.href = "/messages";
});
$("#select_contact").click(function () {
alert('contact');
document.location.href = "/contacts/1";
});
});
</script>
(the alert steps are in there for debugging)
The following html code in index.html.erb
<ul>
<li id="select_mailshot">Mailshot</li>
<li id="select_blog">Blog</li>
<li id="select_contact">Contact us</li>
</ul>
The intention is that this effectively creates 3 buttons.
When clicking on any button from http://myurl.com/ it all works.
When clicking on any button from http://myurl.com/messages (get to this via the middle button) it all works
When starting from http://myurl.com/products/1 it all stops working (the alerts do not trigger). In fact when starting from http://myurl.com/anything/id it stops working.
I've been trying to solve this for hours now and the only difference between the working and non-working conditions is the url as far as I can see.
Can anyone shed any light as to what's going on here?
What does firebug tell you? Do you have javascript errors on the page? if so, what are they? Are you sure the jQuery library is included correctly in the deeper pages ( i.e. is it a relative path? )
Is this javascript inlined?
If not, then maybe the link is relative so when you try to load it from messages/40 you need ../script.js. Another solution is to use absolute URLs (http://myurl/script.js) or virtual (/script.js).
Thanks to cherouvim and digitaljoel.
This was due to javascript files being included relative to the current URL.
The following was included in the head tag
<script type="text/javascript" src="javascripts/jquery-1.3.2.js"></script>
I changed it to
<script type="text/javascript" src="/javascripts/jquery-1.3.2.js"></script>
(note the extra "/" in the src attribute) and everything works as expected.
I worked this out after checking the error logs on the server and in the browser.
Feeling a little dumb but a lesson well learned.
I was using FaceBox to create modal overlays and I couldn't figure out why I was having the same problem.
I turns out that the listener wasn't being attached to HTML elements until it was visible. (The items were available if I viewed source, but jQuery seemed not to attach a listener until it was visible.)
For anyone having the same problem, I'd suggest moving your click() code to a point where the HTML element you're attaching to is visible.
Also, I've found selecting by ID does give more problems than class. I have no idea why. (No, there were not duplicate IDs.)
Hope this helps someone with the same problem!

Categories