problems with javascript function loading content from other files - javascript

Basically I'm trying to build a functionality in which I only really edit my index.php, I got a lot of other php files with just a form in them or just a few lines of text.
What I want to achieve is to load these other files in the contentwrapper of my index.php.
I have been successfull on doing this with an iframe and with a html <object>.
The problem with these though is that first of all they load an all new #document in the DOM, and also my webpage has no set height so height: 100% won't work on those and I would get these ugly scrollbars and stuff.
after searching a lot on SO today I found a few interesting solutions which I combined, this is what I'm trying now:
<script type="text/javascript" href="js/csi.min.js"></script>
<script type="text/javascript">
function load_content(target){
document.getElementById('contentwrapper').innerHTML='<div data-include="' + target + '" ></div>';
return false;
}
</script>
now you may question what data-include is, this is a very nice workaround I found on SO.
THIS is what it does, it basically calls a .js file that replaces the containing element with the data that is in the file (target in the above example)
I call this functionality like this:
Update profile
It works as far as adding this to the DOM:
<div id="contentwrapper">
<div data-include="update.php" ></div>
</div>
but besides that it does nothing, I think that it doesn't call the .js file for the data-include attribute. But I can't find a solution for this nowhere.
(BTW: the data-include attribute does work if I put it in a tag manually without javascript)
I Hope I didn't overexplain the situation, and I thank everyone that tries to help in advance!

The csi.js script is only run once after the page is loaded. It just goes over all the elements with the data-include attribute and runs the fragment function.
<script type="text/javascript">
function fragment(el, url) {
var localTest = /^(?:file):/,
xmlhttp = new XMLHttpRequest(),
status = 0;
xmlhttp.onreadystatechange = function() {
/* if we are on a local protocol, and we have response text, we'll assume
* things were sucessful */
if (xmlhttp.readyState == 4) {
status = xmlhttp.status;
}
if (localTest.test(location.href) && xmlhttp.responseText) {
status = 200;
}
if (xmlhttp.readyState == 4 && status == 200) {
el.outerHTML = xmlhttp.responseText;
}
}
try {
xmlhttp.open("GET", url, true);
xmlhttp.send();
} catch(err) {
/* todo catch error */
}
}
function load_content(target){
fragment(document.getElementById('contentwrapper'), target);
return false;
}
</script>
Then call it like this:
Update profile
So, the only thing you need is to call this function for the new created element. Pass the DOM element and the url to this function and it will take care of loading the contents of the requested resource in the corresponding element.

May we assume that you followed this advise from the repository: The only caveat is Chrome, which restricts access to local files via AJAX. To resolve this, simply add --allow-file-access-from-files to your Chrome runtime.
If you didn't, and you're using Chrome, then this stands out to me, and you didn't indicate that you'd corrected the security block that Chrome puts in place.

The csi.js only runs on window.onload.
Try
<a href="#" onclick="function() {load_content('update.php'); window.onload(); }">
Update profile</a>

Related

Button not showing in Plone, onclick also not working

I am editing a plone page to open an Excel document on a specific sheet. I created two buttons to see if either would appear as actual buttons and use the JS function I reference. With this code the exact part of the page looks like the image below.
Why is only text showing instead of the button and why is the onclick attribute not working?
Note: I have changed to links to the spreadsheet for posting it on here but the link has been tested on other webpages
<script type="text/javascript">
function Open_Excel_File(path,sheet)
{
fso = new ActiveXObject("Scripting.FileSystemObject");
if (!fso.FileExists(path))
alert("Cannot open file.\nFile '" + path + "' doesn't exist.");
else
{
var myApp = new ActiveXObject("Excel.Application");
if (myApp != null)
{
myApp.visible = true;
Book = myApp.workbooks.open(path);
var excel_sheet = Book.Worksheets(sheet).Activate;
myApp.range(f_range).Select;
}
else {
alert ("Cannot open Excel application");
}
}
}
</script>
<div>
<button onclick='Open_Excel_File("file://///fs-01\Departments\Underwriting\Statistical%20Data%20and%20Medical%20Information\Statistics\Cancers\Cancer%20Statistics%\Cancer%20Statistics%.xlsx", "Vulvar Ca");'>Open File</button>
<input type="button" onclick="Open_Excel_File('file://///fs-01\deps\uw\stat%20Data%20and%20Medical%20Information\Statistics\Cancers\Cancer%20Statistics%202018\Cancer%20Statistics%.xlsx', 'VCA');'>OPEN FILE</input>
</div>
your onclick value is not a function, it is the result of a function call. Try to change that to onclick="Open_Excel_File"; You'll have to provide the file path at some point
Accessing file system from browser is super restricted for security matters, the only way I see fit is to have a file input and using what user provides
Also Plone filter out a bounce of potential "nasty" tags through a specific configurable tool.
It seems to me that you have injected the in the source HTML of a Page (document) type.
If so, you will see in your browser that in, the page source code, the script tag has been totally stripped away.
So,
a correct way to inject some js in your page, is to load it as portal_javascript resource (plone<=4) or in resource_registry (plone>=5).
tha nasty way is to access, in the ZMI, at https://yourseite:8080/Plone/portal_transforms/safe_html/ and configure it to accept script tags inside a document (all document in your site actually).
If this answer does not satisfy you try to ask in the official community:
http://community.plone.org
hth,
alessandro

JavaScript ignore missing DOM element/event

I am developing a new application where different pages has different DOM element like Map page has some map specific element and Message page has message specific. To reduce the number of requests, I am combining all scripts to one file and put into footer.
But the problem is that when I am on Map Page, getting error for the missing elements that are only exists on Message page, I believe I am missing something very easy but I could not figure it out.
You can use try and catch if you don't want your script stops.
i.e.
try{
var test = document.getElementById("someelementthatdontexsist");
alert(test.innerHTML);
}
catch(err){};
so as Esko suggested you need to use "if" to check if you are on right page to run appropriate code.
sample:
var PageName = document.getElementsByTagName('body');
document.getElementById("check_button").addEventListener('click', function () {
if (PageName[0].getAttribute('id') == "map_page") {
//do map_page things
document.getElementById("page_name").innerText = PageName[0].getAttribute('id');
}
if (PageName[0].getAttribute('id') == "message_page") {
//do message_page things
document.getElementById("page_name").innerText = PageName[0].getAttribute('id');
}
});
<body id="map_page">
<button id="check_button">Check page</button>
<span id="page_name">test
</span>
</body>

Javascript video won't load in my small widget app

I'm trying to build out a pretty basic widget system that renders some content and videos depending on the widget's ID. I thought I had a pretty solid method of doing this until I've run into a bug that is preventing my videos from loading.
I'd like to know if 1) the method I'm using is an ideal approach and 2) if the bug I'm experiencing is something on my end that can be fixed. Here's how I have it setup.
You place the following code on your website where you want the widget to render:
<script type="text/javascript" src="http://testing.womensforum.com/widgets/example.js"></script>
<div id="wf_widget"></div>
<script>Widget.Load('098f6bcd4621d373cade4e832627b4f6', 'wf_widget');</script>
That'll call the JS code below, which sends an AJAX request to the server asking for the HTML code that it should render. Once I have that, I insert a blank iframe into the div element (wf_widget) which I use to write the HTML code I got from the server into the iframes document.
var host = 'http://testing.womensforum.com/widgets/example.php';
var Widget = {
Load: function(widget_hash, element_id) {
var http = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP");
http.onreadystatechange = function() {
if (http.readyState == 4 && http.status == 200) {
var html = http.responseText;
var iframe = "<iframe allowtransparency=\"false\" style=\"border: 1px solid #8c8b8b; z-index:10;\" width=\"300\" height=\"600\" marginwidth=\"0\" marginheight=\"0\" frameborder=\"0\" scrolling=\"no\"></iframe>";
var div = document.getElementById(element_id);
div.innerHTML = iframe;
var frame = div.getElementsByTagName("iframe")[0];
var doc = frame.contentDocument || frame.contentWindow.document || frame.contentWindow.window.document;
doc.write(html);
}
}
http.open("POST", host, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.send("widget_hash=" + encodeURIComponent(widget_hash));
}
};
This seems to work really well up until I tried loading a video. To see a live example, you can go here:
http://testing.womensforum.com/widgets/example.html
You'll notice that the video player loads, but no video is playing. But if you check out the HTML that the JS code is getting here:
http://testing.womensforum.com/widgets/example.php
You see that the video is loading just fine, it's only when I pipe that HTML code through our JS that it stops working.
Can anyone give any insight as to what the issue is and if there is a better approach for something like this?
Possibly this reason?? With Ajax - it has cross-domain policy where ajax will function/operate given that the file or callback is within the same domain of server. If you are trying to achieve the cross-domain approach, then explore different avenue, not ajax - if I am correct.

Calling external HTML page inside Javascript

i am trying to call a external HTML page to be displayed on website based on javascript conditions.
The code is like this
<script language="JavaScript" src="http://j.maxmind.com/app/country.js"></script>
<script type="text/javascript">
var country = geoip_country_code();
if (country == "US")
{
document.write("http://www.mywebsite.com/1.html");
}
else if (country == "GB")
{
document.write("<a href='#'><img src='http://www.image2.com' ><a/>");
}
else
{
document.write("<a href='#'><img src='http://www.image3.com' ><a/>");
}
</script>
Now, instead of showing the content of HTML page to US visitors, it just display "http://www.mywebsite.com/1.html" as plain text.
I am missing a function to call external HTML. Can someone help? Thanks
Do you mean the <iframe> element?
document.write('<iframe src="http://www.mywebsite.com/1.html"></iframe>');
Since <iframe> cannot resize itself to match the size of its content, be sure to give it a width/height attribute or style (if you know the actual size of content).
Spitting the text of a URL into a page doesn't magically grab the contents of that page. This type of activity usually happens on the SERVER where your server will fetch the content from another page and serve it up as part of YOUR page. JavaScript is the wrong tool for this job.
this kind of thing is really better to do server-side with stuff like php but here's a function I use in a lot of my commercial jobs. Again, I don't condone the use of this function for loading entire pages, but it's a really handy one to have in your toolbox. If anyone says you have to use JQuery to do this, kick them for me. ^_^
function fetchHTML(url)
{
if( 'undefined' == typeof(url) ) return false;
if( document.all ){
p = new ActiveXObject("Microsoft.XMLHTTP");
}
else
{
p = new XMLHttpRequest();
}
rnd = Math.random().toString().substring(3);
if( url.indexOf('?') > -1 )
{
url+='&rnd='+rnd;
}
else
{
url+='?rnd='+rnd;
}
p.open("GET",url,false);
p.send(null);
return p.responseText;
}
well, you are giving a string to document.write() function, and that's why it is displaying the string that it was supposed to display. If you want to display content of some other page you have two choices either you can use an <iframe> or use ajax.

Insert HTML into a page with AJAX

I am currently developing a website and i need that the pages loads dynamically based on what actions the user does.
Example: If the user clicks on the button 'Settings' an ajax function will load from an external page the code and will put into the div with tag 'settings'.
This is the code i use to make the Ajax request:
function get_page_content(page, target_id)
{
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById(target_id).innerHTML = xmlhttp.responseText;
// After getting the response we have to re-apply ui effects or they
// won't be available on new elements coming from request.
$('button').sb_animateButton();
$('input').sb_animateInput();
}
}
xmlhttp.open('GET', 'engine/ajax/get_page_content.php?page=' + page, true);
xmlhttp.send();
}
And this is where the ajax results will be put by first snippet:
<div id="settings_appearance">
</div>
The code is called from a function here:
<div class="left_menu_item" id="left_menu_settings_appearance" onclick="show_settings_appearance()">
Appearance
</div>
And this is the html that the ajax function will put into the settings_appearance div:
<script type="text/javascript">
$(function()
{
$('#upload_hidden_frame').hide();
show_mybrain();
document.getElementById('avatar_upload_form').onsubmit = function()
{
document.getElementById('avatar_upload_form').target = 'upload_hidden_frame';
upload_avatar();
}
});
</script>
<div class="title">Appearance</div>
<iframe id="upload_hidden_frame" name="upload_hidden_frame" src="" class="error_message"></iframe>
<table class="sub_container" id="avatar_upload_form" method="post" enctype="multipart/form-data" action="engine/ajax/upload_avatar.php">
<tr>
<td><label for="file">Avatar</label></td>
<td><input type="file" name="file" id="file" class="file_upload" /></td>
<td><button type="submit" name="button_upload">Upload</button></td>
</tr>
<tr>
<td><div class="hint">The image must be in PNG, JPEG or GIF format.</div></td>
</tr>
</table>
I would like to know if there's a way to execute also the javascript code that's returned by the ajax function (upload button in the returncode doesn't work because of this) and if it's possible to apply some customized ui effects i build that are loaded with the main page.
Thanks for helping.
P.S. This is the script that applies the UI effects:
<script type="text/javascript">
// UI effects
$(document).ready(function()
{
$('button').sb_animateButton();
$('input').sb_animateInput();
$('.top_menu_item').sb_animateMenuItem();
$('.top_menu_item_right').sb_animateMenuItem();
$('.left_menu_item').sb_animateMenuItem();
});
</script>
P.P.S. ui effects are not applied to html elements (such as input and buttons) returned by the Ajax function. I used a little workaround by applying again ui-effects after ajax function returns the response. Probably there's another way of doing it... the same that will help me solve this problem.
If you use the jQuery ajax function (or the simplified jQuery get function), and set the datatype to html, then jQuery will evaluate the contents of any script tags included in the results.
Your $.get call would look something like:
$.get('engine/ajax/get_page_content.php?page=' + page,null,function(result) {
$("#"+target_id).html(result); // Or whatever you need to insert the result
},'html');
I also suggest you don't, but after loading the content in the div, pass the element ID to this function. This will even handle document.write
function do_JS(e){
var Reg = '(?:<script.*?>)((\n|.)*?)(?:</script>)';
var match = new RegExp(Reg, 'img');
var scripts = e.innerHTML.match(match);
var doc = document.write;
document.write = function(p){ e.innerHTML = e.innerHTML.replace(scripts[s],p)};
if(scripts) {
for(var s = 0; s < scripts.length; s++) {
var js = '';
var match = new RegExp(Reg, 'im');
js = scripts[s].match(match)[1];
js = js.replace('<!--','');
js = js.replace('-->','');
eval('try{'+js+'}catch(e){}');
}
}
document.write = doc;
}
A better solution will be to add a function that you can call at the end of the update to show the effects.
I recommend you not to, it might lead to a security breach.
If you already use jquery, use it's ajax functionallity instead of the raw one.
When the ajax request completes execute the animation code (just leave it on the page that does the ajax call).
In your content HTML (the one you get from the call) make a common javascript function for every content page, that will be called every time the content is loaded on the master page...
the function name will be something like: loadContentJavascript() {}
and this function is in charge of loading all the functionalities that it will be load on a onload event.

Categories