Generating a table with jQuery with XML data - javascript

I am new to jQuery, and js for that matter. I am trying to create a table from XML data, but I can't get the output correct. Here is what I have so far:
HTML:
<table id="daily_fruit">
<tbody>
</tbody>
</table>
jQuery:
var xml = '<daily_fruit><day>Mon</day><type>apple</type><day>Tues</day><type>orange</type><day>Wed</day><type>banana</type><day>Thur</day><type>pear</type></daily_fruit>';
xmlDoc = $.parseXML(xml),
$xml = $(xmlDoc);
$($xml).each(function() {
var showTimes = $xml.find('daily_fruit').each(function() {
var $day = $(this).find('day').text();
var $type = $(this).find("type").text();
$("#daily_fruit").find('tbody')
.append($('<tr>')
.append($('<td>')
.append($day))
)
.append($('<td>')
.append($type))
});
});
Current Output:
MonTuesWedThur
appleorangebananapear
Desired Output:
Mon apple
Tues orange
Wed banana
Thur pear
I think I am close, but I just can't figure it out.

Try modifying your XML so that each fruit is within its own tag. Then instead of finding the "daily_fruit" tag for your each loop, use the "fruit" tag.
Here's a jsfiddle:
https://jsfiddle.net/57wgab88/
var xml = '<daily_fruit><fruit><day>Mon</day><type>apple</type></fruit><fruit><day>Tues</day><type>orange</type></fruit><fruit><day>Wed</day><type>banana</type></fruit><fruit><day>Thur</day><type>pear</type></fruit></daily_fruit>';
xmlDoc = $.parseXML(xml),
$xml = $(xmlDoc);
$($xml).each(function() {
var showTimes = $xml.find('fruit').each(function() {
var $day = $(this).find('day').text();
var $type = $(this).find("type").text();
$("#daily_fruit").find('tbody')
.append($('<tr>')
.append($('<td>')
.append($day))
.append($('<td>')
.append($type))
)
});
});

Given such XML structure, you're supposed to iterate through <day> elements instead. Assuming that each <day> is always followed by corresponding <type> element :
var xml = '<daily_fruit><day>Mon</day><type>apple</type><day>Tues</day><type>orange</type><day>Wed</day><type>banana</type><day>Thur</day><type>pear</type></daily_fruit>';
xmlDoc = $.parseXML(xml),
$xml = $(xmlDoc);
$($xml).each(function() {
var showTimes = $xml.find('day').each(function() {
var $day = $(this).text();
var $type = $(this).next("type").text();
$("#daily_fruit").find('tbody')
.append($('<tr>')
.append($('<td>')
.append($day))
.append($('<td>')
.append($type))
)
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="daily_fruit">
<tbody>
</tbody>
</table>

Related

How do you for each on XML data

Im trying to grab the channel display name and channel id from some XML data but it cant seem to get it to work. For each channel display name I what to grab the channel display name and channel id, this is what I have tried, it grabs the data but it puts them all into one string and I want them on separate lines.
var xml = "<tv generator-info-name='tvchannels' source-info-name='tvchannels'><channel id='1234'><display-name>Channel 1</display-name></channel><channel id='5678'><display-name>Channel 2</display-name></channel><channel id='543553'><display-name>Channel 3</display-name></channel><channel id='324324'><display-name>Channel 4</display-name></channel></tv>",
xmlDoc = $.parseXML( xml ),
$xml = $( xmlDoc );
$xml.find("display-name").each(
function (i,e) {
$('#title').append($xml.find("display-name"));
$('#channelid').append($xml.find("channel").attr("id"));
});
XPATH and XSL/XSLT do this, however they can be difficult to learn/use compared to javascript/JSON. JavaScript Object Notation, JSON, is preferred. Have a look at
XPath Examples from Microsoft
Introduction to using XPath in JavaScript from MDN.
Iterator Example
var iterator = document.evaluate('//phoneNumber', documentNode, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );
try {
var thisNode = iterator.iterateNext();
while (thisNode) {
alert( thisNode.textContent );
thisNode = iterator.iterateNext();
}
}
catch (e) {
alert( 'Error: Document tree modified during iteration ' + e );
}
When you're looping through $xml, you need to use $(this) or the second argument passed to .each() in order to access the individual channels as you're looping through. See the code below:
var xml = "<tv generator-info-name='tvchannels' source-info-name='tvchannels'><channel id='1234'><display-name>Channel 1</display-name></channel><channel id='5678'><display-name>Channel 2</display-name></channel><channel id='543553'><display-name>Channel 3</display-name></channel><channel id='324324'><display-name>Channel 4</display-name></channel></tv>",
xmlDoc = $.parseXML( xml ),
$xml = $( xmlDoc );
$xml.find('channel').each(function (i,e) {
$('#title').append($(this).find("display-name"));
$('#title').append($('<br />'));
$('#channelid').append($(this).attr("id"));
$('#channelid').append($('<br />'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Titles: <br />
<div id="title"></div><br />
Channel IDs: <br />
<div id="channelid"></div>
You are not using the results of the find method. I believe you need smth like
var xml = "<tv generator-info-name='tvchannels' source-info-name='tvchannels'><channel id='1234'><display-name>Channel 1</display-name></channel><channel id='5678'><display-name>Channel 2</display-name></channel><channel id='543553'><display-name>Channel 3</display-name></channel><channel id='324324'><display-name>Channel 4</display-name></channel></tv>",
xmlDoc = $.parseXML( xml ),
$xml = $( xmlDoc );
$xml.find("channel").each(function(index, e) {
$('#title').append($(e).find("display-name").text() + '<br />');
$('#channelid').append(e.getAttribute("id") + '<br />');
});
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<div id="title"></div>
<div id="channelid"></div>

Read XML node using ajax

I need to use ajax to read xml node values and use those values further in existing JavaScript function.
Sample XML -
<cars>
<car mfgdate="1 Jan 15" name="Ford" id="1">
<engine litres="3.0" cylinders="6"/>
</car>
<car mfgdate="1 Feb 15" name="Toyota" id="2">
<engine litres="2.2" cylinders="4"/>
</car>
</cars>
Here I need to display details of one car (Ex.Ford) at a time on screen.
There are separate fields on UI to display details like name, mfgdate, litres and cylinders.
If user press next button then next car(Ex. Toyota) details should appear on screen. I need to make ajax calls to do it.
Any help is much appreciated.
Thanks.
Ajax Call
$(document).ready(function(){
$.ajax({ type: "GET",
url: "Cars.xml",
dataType: "xml",
success: function (xml) {
var xmlDoc = $.parseXML(xml);
$xml = $(xmlDoc);
$xml.find('events event date').each(function () {
alert($(this).text() + "<br />");
});
}
});
});
You can find here an example but you have just to put the parse part inside your ajax response call (and also for use as you designed your style ) :
var xmlString = '<cars>'+
'<car mfgdate="1 Jan 15" name="Ford" id="1">'+
'<engine litres="3.0" cylinders="6"/>'+
'</car>'+
'<car mfgdate="1 Feb 15" name="Toyota" id="2">'+
'<engine litres="2.2" cylinders="4"/>'+
'</car>'+
'<car mfgdate="1 Jan 16" name="SONACOM" id="3">'+
'<engine litres="4.0" cylinders="8"/>'+
'</car>'+
'</cars>';
// used to inc or decrements throw cars
var i = 0;
$(document).ready(function(){
xml = $.parseXML( xmlString );
$xml = $( xml );
$cars = $xml.find( "car" );
getCar($cars)
$("#btnnext").click(function(){
i++;
getCar($cars);
})
$("#btnprev").click(function(){
i--;
getCar($cars);
})
function getCar(cars) {
var html ="";
if(cars.length != 'undefined') {
if(cars.length > 0) {
if(i<cars.length){
var name = $(cars[i]).attr('name');
var mfgdate = $(cars[i]).attr('mfgdate')
var $engine = $(cars[i]).find('engine');
var litres = $($engine).attr('litres');
var cylinders = $($engine).attr('cylinders');
html += "<div>Name : "+name+"</div>";
html += "<div>Mfgdate : "+mfgdate+"</div>";
html += "<div>Litres : "+litres+"</div>";
html += "<div>Cylinders : "+cylinders+"</div>";
$("#carinfo").html(html);
btnClick();
}
}
}
}
function btnClick() {
i == 0 ? $("#btnprev").attr("disabled","disabled") :$("#btnprev").removeAttr("disabled");
i == $cars.length-1 ? $("#btnnext").attr("disabled","disabled") : $("#btnnext").removeAttr("disabled");
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btnprev" disabled>prev</button>
<button id="btnnext" disabled>next</button>
<br> <br>
<div id ="carinfo">
</div>

Loop though xml and display values in alerts

I have a string that is set up as Xml. This was a data set which i filled and then returned as string getXml().
I would like to grab all values under Sub-categories and have a alert show displaying each sub category.
I tried something like this but could not come right:
$.parseXML(xml).find('Table').each(function(index){
var SubCategorySystem = $(this).find('SubCategorySystem').text();
var SubCategory = $(this).find('SubCategory').text();
alert(SubCategory);
});
This is how my string looks.
<NewDataSet>
<Table>
<SubCategorySystem>Building</SubCategorySystem>
<SubCategory>Building</SubCategory>
</Table>
<Table>
<SubCategorySystem>Electrical</SubCategorySystem>
<SubCategory>Electrical</SubCategory>
</Table>
<Table>
<SubCategorySystem>Engineering</SubCategorySystem>
<SubCategory>Engineering</SubCategory>
</Table>
<Table>
<SubCategorySystem>Inspection</SubCategorySystem>
<SubCategory>Inspection</SubCategory>
</Table>
<Table>
<SubCategorySystem>Landscaping</SubCategorySystem>
<SubCategory>Landscaping</SubCategory>
</Table>
<Table>
<SubCategorySystem>Mechanical</SubCategorySystem>
<SubCategory>Mechanical</SubCategory>
</Table>
<Table>
<SubCategorySystem>Painting</SubCategorySystem>
<SubCategory>Painting</SubCategory>
</Table>
<Table>
<SubCategorySystem>Plumbing</SubCategorySystem>
<SubCategory>Plumbing</SubCategory>
</Table>
<Table>
<SubCategorySystem>Safety & Security</SubCategorySystem>
<SubCategory>Safety & Security</SubCategory>
</Table>
</NewDataSet>"
Use this function to load the xml
function loadXMLString(txt) {
try {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.loadXML(txt);
return (xmlDoc);
}
catch (e) {
try {
parser = new DOMParser();
xmlDoc = parser.parseFromString(txt, "text/xml");
return (xmlDoc);
}
catch (e) {
alert(e.message)
}
}
return (null);
}
and then call the function like this:
var xmlData = loadXMLString(originalxml);
Now you can simply do this:
var data = xmlData.getElementsByTagName('SubCategory');
for(var i=0;i<data.length;i++)
{
alert(data[i].textContent);
}
Check out this fiddle
I think the wrong part is that $.parseXML(xml) creates a XML Document but it does not return it as an object, so you won't be able to use jQuery methods on it.
Wrap it in an object and it should work
$($.parseXML(xml)).find('Table')
you can reference this two functions first
function getExtendedNodeValue(nodeName, xmlNode, i)
{
var node = "";
if(typeof(xmlNode.getElementsByTagName(nodeName)[i]) != "undefined" && xmlNode.getElementsByTagName(nodeName)[i].hasChildNodes())
node = xmlNode.getElementsByTagName(nodeName)[i].firstChild.nodeValue;
return node;
}
function getNodeLength(nodeName, xmlNode){
return xmlNode.getElementsByTagName(nodeName).length;
}
And below you can loop through
var len = getNodeLength("Table",xml);
var SubCategorySystem = "";
var SubCategory = "";
for(i=0;i<len;i++)
{
SubCategorySystem = getExtendedNodeValue("SubCategorySystem",xml,i);
SubCategory = getExtendedNodeValue("SubCategory",xml,i);
console.log(SubCategorySystem + " == " + SubCategory);
}
You can find this FIDDLE

Loop through XML Parser?

I am developing an app, where on the click of a button, a list of the document information stored in an XML file is shown on screen in a <ul> tag. The current JavaScript in the function is;
function viewXMLFiles() {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "TestInfo.xml", false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
document.getElementById("docname").innerHTML = xmlDoc.getElementsByTagName("document_name")[0].childNodes[0].nodeValue;
document.getElementById("filetype").innerHTML = xmlDoc.getElementsByTagName("file_type")[0].childNodes[0].nodeValue;
document.getElementById("fileloc").innerHTML = pathToRoot + "/" + document.getElementById("docname").innerHTML;
document.getElementById("docname1").innerHTML = xmlDoc.getElementsByTagName("document_name")[1].childNodes[0].nodeValue;
document.getElementById("filetype1").innerHTML = xmlDoc.getElementsByTagName("file_type")[1].childNodes[0].nodeValue;
document.getElementById("fileloc1").innerHTML = pathToRoot + "/" + document.getElementById("docname1").innerHTML;
}
but i want to set it so that even if more file information is added, the function will display it too. i have already looked at Jquery xml parsing loops this question, but i couldn't get the function to work. Here's the XML file;
<document_list>
<document>
<document_name>Holidays.pdf</document_name><br />
<file_type>.pdf</file_type> <br />
<file_location>TEST</file_location> <br />
</document>
<document>
<document_name>iPhone.jsNotes.docx</document_name><br />
<file_type>.docx</file_type><br />
<file_location>TEST</file_location><br />
</document>
</document_list>
And this is the HTML i am using. There's a button and the <ul> tags i'm using;
<button onclick = "viewXMLFiles(); document.getElementById('showDocumentLink').style.display = 'block';">View Document Info</button><br>
<div id = "doclist">
<h2>Document 1;</h2>
<label>Document Name;</label><br><span id = "docname"></span><br>
<label>File Type</label><br><span id = "filetype"></span><br>
<label>File Location</label><br><span id = "fileloc"></span><br>
</div>
<div id = "doclist">
<h2>Document 2;</h2>
<label>Document Name;</label><br><span id = "docname1"></span><br>
<label>File Type</label><br><span id = "filetype1"></span><br>
<label>File Location</label><br><span id = "fileloc1"></span><br>
</div>
Can anyone help me put this into a loop? I have linked jQuery and jQTouch so i can use both of them.
Thank you so much in advance xx
Use following loop code.
<script>
xmlDoc = $.parseXML( xml ),
$xml = $( xmlDoc );
var documents = $xml.find('document_list');
documents.children('document').each(function() {
var name = $(this).find('document_name').text();
var file_type = $(this).find('file_type').text();
var file_location = $(this).find('file_location').text();
// now do whatever you like with above variable
});
</script>
Using Irfan's answer as a base, to get the values into your labels add a counter, then just insert the values grabbed from the XML parsing loop into the corresponding span.
<script>
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "TestInfo.xml", false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
$xml = $( xmlDoc );
var documents = $xml.find('document_list');
var doccount = 0;
//will be used to find the HTML elements
var namelabel = "docname";
var typelabel = "filetype";
var locationlabel = "fileloc";
documents.children('document').each(function() {
var name = $(this).find('document_name').text();
var file_type = $(this).find('file_type').text();
var file_location = $(this).find('file_location').text();
//after the first document we need to add the number to the span id
if(doccount > 0){
namelabel = "docname" + doccount;
typelabel = "filetype" + doccount;
locationlabel = "fileloc" + doccount;
}
//insert the XML values into the label
$('span#'+namelabel).html(name);
$('span#'+typelabel).html(file_type);
$('span#'+locationlabel).html(file_location);
//increment the counter
doccount++;
});
</script>
Here is a native JavaScript implementation so you can see how you'd do it that way and compare, etc.
function viewXMLFiles() {
// var everything
var xmlhttp = new XMLHttpRequest(),
xmlDoc,
nodes, i, j, counter = -1, suffix,
document_name, file_type, file_location;
// request page
xmlhttp.open("GET", "TestInfo.xml", false),
xmlhttp.send();
// false meant synchronous req. so can go straight to reading document
xmlDoc = xmlhttp.responseXML;
// loop over <document> nodes
nodes = xmlDoc.childNodes; // shorthand
j = nodes.length;
for (i = 0; i < j; ++i) {
if ('document' === nodes[i].tagName.toLowerCase()) {
// nodes[i] is a <document>, increment counter
++counter;
// get nodes of intrest
document_name = nodes[i].getElementsByTagName("document_name")[0];
file_type = nodes[i].getElementsByTagName("file_type")[0];
file_location = nodes[i].getElementsByTagName("file_location")[0];
// do what you want with these, e.g.
suffix = counter || ''; // don't append a number for 0
document.getElementById('docname'+suffix).textContent = document_name.textContent;
document.getElementById('filetype'+suffix).textContent = file_type.textContent;
document.getElementById('fileloc'+suffix).textContent = pathToRoot + "/" + file_location.textContent;
}
}
}
Furthermore, you should consider the validity of your HTML, as I mentioned in my comment;
there should be no spaces around the equals sign of an attribute name/value pair, i.e. <tag attrib="val"/> not <tag attrib = "val"/>
every id attribute should have a unique value, not shared with any other on the document, i.e. not <tag id="shared"/><tag id="shared"/>

is there a way to use javascript or jquery to add a color to the search keyword

the url is like this:
http://www.example.com/index.php?main_page=advanced_search_result&keyword=Sons+of+Anarchy
on the above the search keyword is Sons of Anarchy. now, is there a way to add a color to the keyword when in the search result content with js on the search result page . thank you.
ps:the search input box:<input type="text" class="keybg" id="keyword" name="keyword">
$sData['pfrom'] = (isset($_GET['pfrom']) ? zen_output_string($_GET['pfrom']) : '');
$sData['pto'] = (isset($_GET['pto']) ? zen_output_string($_GET['pto']) : '');
the above way is added a parameter to the url.
http://www.example.com/index.php?main_page=advanced_search_result&keyword=Sons+of+Anarchy&pfrom=...pto=..
You could do something like this:
document.body.innerHTML = document.body.innerHTML.replace(/Anarchy/ig, '<mark>Anarchy</mark>');
Try this (this assumes you are loading jQuery into the page):
myFile.php
==========
<?php
$sData['pfrom'] = (isset($_GET['pfrom'])
? zen_output_string($_GET['pfrom'])
: '');
$sData['pto'] = (isset($_GET['pto'])
? zen_output_string($_GET['pto'])
: '');
// ... your other code here
?>
<!-- PUT THIS SCRIPT AT THE END OF YOUR HTML BODY ELEMENT -->
<script type="text/javascript">
// get the current URL
var url = window.location.toString();
//get the parameters
url.match(/\?(.+)$/);
var params = RegExp.$1;
// split up the query string and store in an
// associative array
var params = params.split("&");
var queryStringList = {};
for (var i=0;i<params.length;i++) {
var tmp = params[i].split("=");
queryStringList[tmp[0]] = unescape(tmp[1]);
}
// get the body html and update it to have keyword colored
var searchKeyword = queryStringList.keyword;
var searchRegex = new Regexp('/'+searchKeyword+'/', 'gi');
var html = $('body').html();
var coloredHTML = html
.replace(searchRegex,
"<span style="color:green">"+html+"</span>");
$('body').html(coloredHTML);
</script>
I think what you want is something like this.
The solution will not mess up your html if you are searching for something that is probably inside html tags, e.g., span
The search key will be escaped in order to generate a correct reg exp object
code:
var searchKey = 'rray($';
highlight(searchKey, $('div'));
searchKey = '|| !';
highlight(searchKey, $('div'));
function highlight(word, $target){
var conts = $target.html().split('<').join('><').split('>');
var escapeRgx = /([\/\.\*\+\?\|\(\)\[\]\{\}\\\:\$\^])/g;
var searchRgx = new RegExp(word.replace(escapeRgx, '\\$1'), 'gi');
$.each(conts, function(idx, str){
if(str.charAt(0) != '<'){
conts[idx] = str.replace(searchRgx, '<span class="mark">' + word + '</span>') ;
} else {
conts[idx] = str + '>';
}
});
$target.html(conts.join(''));
}
For getting the search key, you can retrieve it at the backend, and echo it to the frontend. i.e.,
<? echo 'var searchKey = "'. $_GET['key'] .'"'; ?>
Here is the demo -
http://jsfiddle.net/jn7TC/4/

Categories

Resources