I have issues firing this link (that triggers a script from Chargebee) when is added dynamically via JavaScript. When it's added directly in html it works normally.
The entire generated link is appearing correctly (populated with the variants) in browser when inspected just it doesn't fire.
Here are the pieces I have related to this:
The JavaScript part:
var checkout = document.getElementById("checkout");
var link = '<a href="javascript:void(0)" data-cb-type="checkout"' + data-cb-1 + data-cb-2 + data-cb-3'>Order</a>';
checkout.innerHTML = link;
A simple div:
<div id="checkout"></div>
The script from chargebee:
<script src="https://js.chargebee.com/v2/chargebee.js" data-cb-site="site-name"></script>
Once you've loaded chargebee.js script it starts to look for a tag a with specific data-cb attributes. The script does it one time only. If the tag a did not exist in the DOM then, the script does nothing. When you add the tag a later that makes no effect at all, because a "discovery phase" is over.
If you want to have more control over chargebee initialisation process, you should go for "Checkout via API" option provided by the developers.
P.S. There are two hacky solutions:
You may load Chargebee script after adding tag a to the DOM.
function loadChargebee() {
var script = document.createElement("script");
script.src = "https://js.chargebee.com/v2/chargebee.js";
script.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(script);
}
var checkout = document.getElementById("checkout");
var link = '<a href="javascript:void(0)" data-cb-type="checkout"' + data-cb-1 + data-cb-2 + data-cb-3'>Order</a>';
checkout.innerHTML = link;
loadChargebee(); // <=== add Chargebee.js
Leave the tag a in the DOM, load the script as usual but modify data attributes as needed after page load:
<a id="beecheckout" href="javascript:void(0)" data-cb-type="checkout" data-cb-1="" data-cb-2="" data-cb-3="">Order</a>
document.getElementById('beecheckout').setAttribute('data-cb-1','new data value');
Related
I am trying to add a github gist to my webpage on the click of a button however the gist is not appearing.
function createGist(gistId = "bd10e846c6eae4419c3041f3da1b82a0"){
var script = document.createElement("script");
script.src = "https://gist.github.com/snakifyanswers/" + gistId + ".js";
document.body.appendChild(script) }
I am left with nothing there even though in inspect element I can see the script object.
I'm trying to insert JavaScript to a WordPress page. I added this to functions.php:
function add_custom_code() {
if (is_front_page()) { ? >
< script >
(function() {
var randomId = Math.floor(Math.random() * 100000);
var targetElemId = ‘bcom_rwidget_’ + randomId;
document.write(‘ < div id = ”‘+targetElemId + ‘” > < /div>‘);
var script = document.createElement(‘script’);
script.type = ‘text / javascript’;
script.async = true;
script.src = ‘http: //www.booking.com/review_widget/gb/the-manor-house-bed-amp-breakfast-enter code here`trunch.en.html?tmpl=review_widget/review_widget&wid=’ + targetElemId + ‘&wtype=box_small&hotel_id=XXXXX&`enter code here`widget_language=en’;
var node = document.getElementsByTagName(‘script’)[0];
node.parentNode.insertBefore(script, node);
}()); < /script> < ? php
}
}
add_action('wp_footer', 'add_custom_code');
But when I add the script to the page, it disappears as soon as I
try to save it.
How can I run a secure JavaScript on a WordPress page?
Have you tried writing the javascript in a diffrent file, then enqueueing it in functions.php and calling it with in case of front page?
You could use one of the following..
1. Using the HTML view of the WYSIWYG Editor.
You need to change the writing mode from Visual to HTML and copy-paste your JavaScript code into the text box. There If you already have some content for the post, then you shall see the HTML for it, just type/paste your js at the bottom of the post content.
Remember to enclose the js code inside the <style> tags. This method will work most of the time, if it doesn't, then we have a plan B :)
2. Using Custom Fields + Short Codes
Here you create a new custom field and set the value of this custom field to the JavaScript code. Then insert a shortcode in your post content which will in turn fetch the value of that custom field.
I created a Web App for NavBar and located it on my template. It is working fine.
{module_webapps,28592,a,,,,false,20,false,1}
And this is the code for this WebApp:
<li>
<a id="{tag_href-id}" href="{tag_href-id}">{tag_title}</a>
</li>
Then, for showing the active page as highlighted, I coded this jQuery in my template:
window.onload = function(){
var url = window.location.pathname;
var index = url.lastIndexOf("/") + 1;
var filenameWithExtension = url.substr(index);
var filename = "#" + filenameWithExtension.split(".")[0];
$(filename).addClass('active');
};
The idea is adding class="active" inside of a tag; if its id equal to last part of the URL.
I used the same idea before, without WebApps. I wonder that, is there any limitation about using jQuery in a page, to change something about an element which comes from Web Apps? Could it be related page`s loading order. Or am I missing another thing?
I have an html file that I want to be loaded from various pages into a dijit.contentpane. The content loads fine (I just set the href of the contentpane), but the problem is that javascript within the html file specified by href doesn't seem to be executed at a consistent time.
The final goal of this is to load an html file into a contentpane at an anchor point in the file (i.e. if you typed in index.html#tag in order to jump to a certain part of the file). I've tried a few different methods and can't seem to get anything to work.
What I've tried:
1.
(refering to the href of the dijit.contentpane)
href="page.htm#anchor"
2.
(again, refering to the href of the dijit.contentpane -- didn't really expect this to work, but decided to try anyways)
href="#anchor"
3. (with this last try inside the html specified by href)
<script type="text/javascript">
setTimeout("go_to_anchor();", 2000);
function go_to_anchor()
{
location.href = "#anchor";
}
</script>
This last try was the closest to working of all of them. After 2 seconds (I put the delay there to see if something in the dijit code was possibly loading at the same time as my javascript), I could see the browser briefly jump to the correct place in the html page, but then immediately go back to the top of the page.
Dojo uses hashes in the URL to allow bookmarking of pages loaded through ajax calls.
This is done through the dojo.hash api.
So... I think the best thing you can do is use it to trigger a callback that you write inside your main page.
For scrolling to a given position in your loaded contents, you can then use node.scrollIntoView().
For example, say you have a page with a ContentPane named "mainPane" in which you load an html fragment called "fragment.html", and your fragment contains 2 anchors like this :
-fragment.html :
Anchor 1
<p>some very long contents...</p>
Anchor 2
<p>some very long contents...</p>
Now say you have 2 buttons in the main page (named btn1 and btn2), which will be used to load your fragment and navigate to the proper anchor. You can then wire that up with the following javascript, in your main page :
<script type="text/javascript">
require(['dojo/on',
'dojo/hash',
'dojo/_base/connect',
'dijit/layout/BorderContainer',
'dijit/layout/ContentPane',
'dijit/form/Button'],
function(on, hash, connect){
dojo.ready(function(){
var contentPane = dijit.byId('mainPane');
var btn1 = dijit.byId('btn1');
var btn2 = dijit.byId('btn2');
btn1.on("Click", function(e){
if (!(contentPane.get('href') == 'fragment.html')) {
contentPane.set("href", "fragment.html");
}
hash("anchor1");
});
btn2.on("Click", function(e){
if (!(contentPane.get('href') == 'fragment.html')) {
contentPane.set("href", "fragment.html");
}
hash("anchor2");
});
// In case we have a hash in the URL on the first page load, load the fragment so we can navigate to the anchor.
hash() && contentPane.set("href", "fragment.html");
// This callback is what will perform the actual scroll to the anchor
var callback = function(){
var anchor = Array.pop(dojo.query('a[href="#' + hash() + '"]'));
anchor && anchor.scrollIntoView();
};
contentPane.on("DownloadEnd", function(e){
console.debug("fragment loaded");
// Call the callback the first time the fragment loads then subscribe to hashchange topic
callback();
connect.subscribe("/dojo/hashchange", null, callback);
});
}); // dojo.ready
}); // require
</script>
If the content you're loading contains javascript you should use dojox.layout.ContentPane.
I have a page that loads with initially just a form within an iframe, something like this:
<iframe id="oIframe" ...src='somePage>'
<form ... />
</iframe>
When you click a button in the form, some javascript is invoked that builds a url and then I want to do the following:
frame.src = 'somePage?listId=1';
This works in IE to "reload" the frame with the new contents.
However, in Safari this does not work.
I have jQuery available, but I don't want to replace the existing iframe because there are events attached to it. I also can not modify the id of the iframe because it is referenced throughout the application.
I have seen some similar issues but no solutions that seem to work well for my exact issue.
Any assistance anyone can provide would be great!
Some browsers don't use "src" when calling the javascript object directly from the javascript hierarchy and others use "location" or "href" instead of "src" to change the url . You should try these two methods to update your iframe with a new url.
To prevent browser cache add a pseudo-random string like a number and timestamp to the url to prevent caching. For example add "new Date().getTime()" to your url.
Some calling examples:
document.getElementById(iframeId).src = url;
or
window.frames[iframeName].location = url;
I recommend the first option using document.getElementById
Also you can force the iframe to reload a page using
document.getElementById(iframeId).reload(true);
So the answer is very simple:
1. put a <div id="container"> </div> on your page
2. when reload needed use following jQuery:
$("#container").empty();
$("#container").append("<iframe src='" + url + "' />");
and that's it.
Of course there is more elegant way of creating DOM with jQuery but this gives the idea of "refreshing" iframe.
Works in FF18, CH24, IE9, O12 (well it's jQuery so it will work almost always :)
I found a better solution (albeit not paticularly eloquent) for this using jQuery.ajax:
jQuery.ajax({
type: 'GET',
url: "/somePage?someparms",
success: function() {
frameObj.src = "/somePage?someparms";
}
});
This forces the DOM to be read within the frame object, and reloads it once the server is ready to respond.
Try this
form.setAttribute('src', 'somePage?listId=1');
Well, I was able to find what appears to be a feasible solution -- it's a work in progress, but this is basically what I ended up doing:
var myFrame = document.getElementById('frame'); // get frame
myFrame.src = url; // set src attribute of original frame
var originalId = myFrame.id; // retain the original id of the frame
var newFrameId = myFrame.id + new Date().getTime(); // create a new id
var newFrame = "<iframe id=\"" + newFrameId + "\"/>"; // iframe string w/ new id
myFrameParent = myFrame.parentElement; // find parent of original iframe
myFrameParent.innerHTML = newFrame; // update innerHTML of parent
document.getElementById(newFrameId).id = originalId; // change id back
I ran into this issue using React, passing the key as props.src solved it
const KeyedIframe = ({children, ...props}) => <iframe key={props.src} { ...props}>
{children}
</iframe>