I've a menu on the left side of a frame.
I'm trying to call a javascript that will load a new html in the right side of the frame generated from XML data and XSL template.
The code to do it in one page with fixed parameters works fine. The two issues I struggle with is:
How to make it flexible so I can use a different xml data and template on the call to the script
How to present the data in the right hand frame pane.
This is the code for the left hand pane:
<html>
<head>
<script>
function loadXMLDoc(filename)
{
if (window.ActiveXObject)
{
xhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
else
{
xhttp = new XMLHttpRequest();
}
xhttp.open("GET", filename, false);
try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11
xhttp.send("");
return xhttp.responseXML;
}
function displayResult(xmlid,xslid)
{
xml = loadXMLDoc("XMLDATA/xmlid");
xsl = loadXMLDoc("XMLDATA/xslid");
// code for IE
if (window.ActiveXObject || xhttp.responseType == "msxml-document")
{
ex = xml.transformNode(xsl);
document.getElementById("example").innerHTML = ex;
}
// code for Chrome, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument)
{
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(xml, document);
document.getElementById("example").appendChild(resultDocument);
}
}
</script>
</head>
<body>
<p>TEST</p>
<p>TEST</p>
<div id="example" />
</body>
</html>
If I omit the both arguments in the script call:
TEST
and assign the data sources in the parameters here:
xml = loadXMLDoc("XMLDATA/cdcatalog.xml");
xsl = loadXMLDoc("XMLDATA/cdcatalog.xsl");
Then it works on the same page.
I'm not a programmer so some help would be great.
You're not using the variables that you're passing in, you're simply using static text.
At the start of function displayResult(xmlid,xslid) change...
xml = loadXMLDoc("XMLDATA/xmlid");
xsl = loadXMLDoc("XMLDATA/xslid");
To...
xml = loadXMLDoc(xmlid);
xsl = loadXMLDoc(xslid);
Update - in response to the OPs comments...
If you want to move elements around the page, I would seriously consider looking at jquery which will easily allow you to detach the items and append them to another area.
For example...
$(function(){
var $rightArea = $("#rightarea");
$("#leftarea *").each(function(){
$(this).detach().appendTo($rightArea);
});
});
Related
On an already loaded HTML page I want to load a XML file and append the resultig HTML to the loaded page. The XML file is linked with an XSL file. When I open it in the browser (Firefox) the XSL transformation is correctly applied. The result is HTML without html, head and body tags. That’s what I want.
Loading the XML with Ajax gives me the untransformed XML, not the HTML I wish.
My workaround so far is to load the XML file in a hidden iframe. In there the XSL transformation is correctly carried out.
I now fail to copy the HTML form the iframe and append it to an existing div in the page outside the iframe. I only manage to:
Get an HTML Collection (with jquery or plain JS):
iframe = $('#iframe');
iframeHtml = iframe.contents()[0].children;
iframe = document.getElementById('bausteine__liste__zwischenspeicher');
resultHtml = iframe.contentDocument || temp.contentWindow.document;
Get all HTML but only starting below the first div (with jquery). The uppermost div which contains everything is left out.
iframe = $('#iframe');
resultHtml = iframe.contents().find('div').html();
This is the iframe as I see it in the dev toolbar of Firefox
<iframe id="iframe" src="file-with-xslt.xml">
<div class="uppermost-element">
<div>
…
</div>
<div>
…
</div>
</div>
</iframe>
How can I get the HTML including the uppermost element? Either via the iframe or – even better – via Ajax.
Thanks for your help!
The solution is to load both the XML and XSL with an XMLHttpRequest and to do the transformation with Javascript. documentElement.outerHTML will output the resulting HTML.
function XMLtransformation(xsl, xml) {
var xslStylesheet;
var xsltProcessor = new XSLTProcessor();
var xmlDoc;
// load XSL file
var myXMLHTTPRequest = new XMLHttpRequest();
myXMLHTTPRequest.open('GET', urlXSL, false);
myXMLHTTPRequest.send(null);
xslStylesheet = myXMLHTTPRequest.responseXML;
xsltProcessor.importStylesheet(xslStylesheet);
// load XML file
myXMLHTTPRequest = new XMLHttpRequest();
myXMLHTTPRequest.open('GET', urlXML, false);
myXMLHTTPRequest.send(null);
xmlDoc = myXMLHTTPRequest.responseXML;
var htmlDocument = xsltProcessor.transformToDocument(xmlDoc, document);
return htmlDocument.documentElement.outerHTML;
}
XMLtransformation('file.xsl', 'file.xml');
I liked #Moritz's solution above, but it needed a bit of tweaking so here's my version:
function XMLtransformation(xslUrl, xmlUrl) {
const errorMessage = 'Unable to load the content';
const parser = new DOMParser();
// attempt to load the XSL file
const xslRequest = new XMLHttpRequest();
xslRequest.open('GET', xslUrl, false); // `false` makes the request synchronous
xslRequest.send(null);
if (xslRequest.status < 300) {
const xslStylesheet = parser.parseFromString(xslRequest.response, "application/xml");
const xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(xslStylesheet);
const xmlRequest = new XMLHttpRequest();
xmlRequest.open('GET', xmlUrl, false);
xmlRequest.send(null);
if (xmlRequest.status < 300) {
const htmlDocument = xsltProcessor.transformToDocument(
parser.parseFromString(xmlRequest.response, "application/xml"),
document
);
return htmlDocument.documentElement.outerHTML;
} else {
console.error('xml load failure:');
console.error(xmlRequest.status, xmlRequest.responseText);
}
} else {
console.error('xsl load failure:');
console.error(xslRequest.status, xslRequest.responseText);
}
return errorMessage;
}
i want the new html file to be created in the same folder in which HTML is present. please help me. am searching a lot , no luck
<script>
function makeDocument() {
var doc = document.implementation.createHTMLDocument("newdoc");
var p = doc.createElement("p");
p.innerHTML = "This is a new paragraph.";
try {
doc.body.appendChild(p);
} catch(e) {
console.log(e);
}
var opened = window.open("");
opened.document.write(doc);
}
</script>
Use a back-end server. Because the HTML page and the scripts are executed on the client-side. You can't really create a file on the client-side while the page is loaded in a browser.
The other way around, you won't want the client to create arbitrary files on the server as well. It poses a great security risk and might lead to possible remote code execution (RCE).
You do not have a closing brace on your function
<script>
function makeDocument() {
var doc = document.implementation.createHTMLDocument("newdoc");
var p = doc.createElement("p");
p.innerHTML = "This is a new paragraph.";
try {
doc.body.appendChild(p);
} catch(e) {
console.log(e);
}
var opened = window.open("");
opened.document.write(doc);
}
</script>
As for the wording of your question, if you are asking to create a new file that gets saved, then Aviv Lo's answer is what you need
Im looking for a bit of Yoda like guidance on a project im working on. Im trying to dynamically generate div's in a web page based around XML data which is read in from a php server. Im punching a bit above my experience weight which is good for learning.
Was wondering if someone could point me in the right direction as far a tutorials or give me some guidance to see if im on the right track etc.
The XML im loading in is...
<item>
<id>1</id>
<name>Johnothan</name>
<message>hello world</message>
</item>
<item>
<id>2</id>
<name>Fredrico</name>
<message>hello world</message>
</item>...etc
My Ajax function to call.
function ajax(site, params){
var xmlhttp;
var i;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
xmlDoc=xmlhttp.responseXML;
}
}
xmlhttp.open("POST", site, false);
xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xmlhttp.send(params);
}
JS Div generation
function information(){
xmlReturned = xmlDoc.getElementsByTagName("item");
for (i=0; i<xmlReturned.length; i++){
newDiv(i);
}
function newDiv(i){
var id = xmlReturned[i].getElementsByTagName("id")[0].firstChild.nodeValue;
var name = xmlReturned[i].getElementsByTagName("name")[0].firstChild.nodeValue;
var message = xmlReturned[i].getElementsByTagName("message" [0].firstChild.nodeValue;
//Now im trying to place the dynamic XML information within a table with in a new DIV in the HTML.
}
My HTML is pretty basic it calls the information() function with the body tag loads.
Am I looking in the right direction?? Can someone help me out or recommend a tutorial?
Thanks for your time
Try using jQuery. It simplifies the task that you are trying to do.
http://api.jquery.com/category/manipulation/
Eg.
var newDiv = $('<div/>').text(sampleText);
parentDiv.append(newDiv);
Useful example of using jquery to do your task:
http://think2loud.com/224-reading-xml-with-jquery/
i have this code in a jquery popup here is the code
jQuery(document).ready(function(){
var showmask = function() {
var dialogLeft = ((jQuery(window).width() - jQuery("#outerFbDialog").outerWidth()) / 2) + jQuery(window).scrollLeft() + "px";
var dialogTop = "100px";
/* uncomment this to place dialog in the center of window.
var dialogTop = ((jQuery(window).height() - jQuery("#outerFbDialog").outerHeight()) / 2) + jQuery(window).scrollTop() +"px";
*/
jQuery("#themask").css({'width':jQuery(window).width(),'height':jQuery(document).height()});
jQuery("#themask").fadeTo('slow',0.7);
jQuery("#outerFbDialog").css({'left': dialogLeft,'top':dialogTop});
jQuery("#outerFbDialog").show();
$('#themask').click(function () {
jQuery(this).hide();
jQuery("#outerFbDialog").hide();
});
}
// check for escape key
$(document).click(function(e) {
jQuery("#themask").hide();
jQuery("#outerFbDialog").hide();
});
showmask();
});
I need to get whole content of iframe from the same domain. Whole content means that I want everything starting from <html> (including), not only <body> content.
Content is modified after load, so I can't get it once again from server.
I belive I've found the best solution:
var document = iframeObject.contentDocument;
var serializer = new XMLSerializer();
var content = serializer.serializeToString(document);
In content we have full iframe content, including DOCTYPE element, which was missing in previous solutions. And in addition this code is very short and clean.
If it is on the same domain, you can just use
iframe.contentWindow.document.documentElement.innerHTML
to get the content of the iframe, except for the <html> and </html> tag, where
iframe = document.getElementById('iframeid');
$('input.test').click(function(){
$('textarea.test').text($('iframe.test').contents());
});
You can get the literal source of any file on the same domain with Ajax, which does not render the html first-
//
function fetchSource(url, callback){
try{
var O= new XMLHttpRequest;
O.open("GET", url, true);
O.onreadystatechange= function(){
if(O.readyState== 4 && O.status== 200){
callback(O.responseText);
}
};
O.send(null);
}
catch(er){}
return url;
}
function printSourceCode(text){
var el= document.createElement('textarea');
el.cols= '80';
el.rows= '20';
el.value= text;
document.body.appendChild(el);
el.focus();
}
fetchSource(location.href, printSourceCode);
Hallo,
I'm new to objective-j and cappuccino and just have tried to create a
small application, that creates the gui dynamically from a xml file.
Unfortunately it works only partially. It seems that the button
regions are disorder. This means, that the buttons also response if
I click besides the button....
Please help me. I dont get it..
- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
mControlList = [CPArray alloc];
theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero()
styleMask:CPBorderlessBridgeWindowMask],
contentView = [theWindow contentView];
[contentView setFrame:[[contentView superview] bounds]];
[contentView setAutoresizingMask:CPViewWidthSizable |
CPViewHeightSizable];
// Loadxmlfile
var xhttp;
if (window.XMLHttpRequest)
{
xhttp=new XMLHttpRequest()
}
else
{
xhttp=new ActiveXObject("Microsoft.XMLHTTP")
}
xhttp.open("GET","test.xml",false);
xhttp.send("");
xmlDoc = xhttp.responseXML;
//Get controls nodeand iterate through all controls
var node = xmlDoc.getElementsByTagName("controls")[0];
for (var i=0; i<node.childNodes.length; i++) {
if(node.childNodes[i].nodeName=="button"){
var item = node.childNodes[i];
var name = item.attributes["name"].nodeValue;
var text = item.getElementsByTagName("text")
[0].childNodes[0].nodeValue;
var x= item.getElementsByTagName("rect")
[0].attributes["x"].nodeValue;
var y= item.getElementsByTagName("rect")
[0].attributes["y"].nodeValue;
var width= item.getElementsByTagName("rect")
[0].attributes["width"].nodeValue;
var height= item.getElementsByTagName("rect")
[0].attributes["height"].nodeValue;
var b = [[Button alloc] InitWithParent:contentView Text:text X:x
Y:y Width:width Height:height];
[mControlList addObject:b];
}
}
[theWindow orderFront:self];
}
#implementation Button : CPObject
{
CPButton _button;
}
- (Button)InitWithParent:(CPView)contentView Text:(CPString)text X:
(int)x Y:(int)y Width:(int)width Height:(int)height
{
_button = [[CPButton alloc] initWithFrame:
CGRectMake(x,y,width,height)];
[_button setTitle:text];
[_button setTarget:self];
[_button setAction:#selector(cmdNext_onClick:)];
[contentView addSubview:_button];
return self;
}
- (void)cmdNext_onClick:(id)sender
{
}
#end
Cappuccino gives you most of this functionality for free.
You can load files by using a CPURLConnection.
Also Atlas (or Interface Builder and nib2cib) will automatically create cib files for you, Cappuccino itself already knows how to build up it's UI from a cib files.
If you really want to implement your own system to do this, could you please provide the actual XML you are trying to load? Also try loading the button without using the XML. For example:
var myButton = [CPButton buttonWithTitle:#"My Cool Button"];
[contentView addSubview:myButton];
+ buttonWithTitle: will automatically call - sizeToFit on the initialized button, so you can just add it to your contentView and it should be visible with the appropriate size.