I have a JSON witch looks something like this
{
"English": "en",
"Francais": "fr",
"German": "gm"
}
Now I need to print this data in HTML structure witch looks like this
<ul id="links">
<li class="home">
</li>
<li class="languages">
EN ------ > FIRST LANGUAGE FROM JSON
<ul class="available"> ----> OTHERS
<li>DE</li>
<li>IT</li>
<li>FR</li>
</ul>
</li>
</ul>
In javascript I know how to get data and print all data in the same structure but how to do it in structure shown in example ?
in Javascript I'm getting data with
$.getJSON('js/languages.json', function(data) {
console.log(data);
/* $.each(data, function(key, val) {
console.log(val);
});*/
});
Use jQuery template to bind the Html. Some Sample
Something like that:
var getBlock = function(skipLang) {
var str = '\
<ul id="links">\
<li class="home">\
\
</li>\
<li class="languages">\
' + data[skipLang] + '\
<ul class="available">\
';
for(var lang in data) {
if(lang != skipLang) {
str += '<li>' + lang + '</li>';
}
}
str += '</ul></li></ul>';
return str;
}
var html = '';
for(var lang in data) {
html += getBlock(lang);
}
Although using templating engine is an option for simpler code, for this case you can directly run a for loop and assign HTML within javascript code easily.
HTML part is going to be something like this
<ul id="links">
<li class="home">
home
</li>
<li class="languages">
<ul class="available">
</ul>
</li>
</ul>
And JS part is like this:
var data = {
"English": "en",
"Francais": "fr",
"German": "gm"
};
var $liLanguages = $('li.languages');
var $ulAvailable = $('ul.available');
var selectedLanguage = '';
for(var index in data) {
if(selectedLanguage == '') {
selectedLanguage = data[index];
$liLanguages.prepend("<a href='#'>" + data[index].toUpperCase() + "</a>");
}
else {
$ulAvailable.append("<li><a href='#'>" + data[index].toUpperCase() + "</a></li>");
}
}
Here is the jsfiddle related.
Hope this helps.
Here is a bit that will get you two new objects, one for the first object property/value and another for the remaining. Still not clear what is done with it once you have it, but let me know if it helps:
// This can be replaced with existing data or updated to var langs = data;
var langs = {"English": "en", "Francais": "fr","German": "gm" };
// jQuery map only works on objects after 1.6, heads up
var lang_keys = $.map( langs, function( value, key ) {
return key;
});
// Now that you have an array of the keys, you can use plain-ol shift()
var primary_lang_key = lang_keys.shift();
// create and populate an object just for your first language:
var primary_lang = {};
primary_lang[primary_lang_key] = langs[primary_lang_key];
// Thanks to shift, we know that populating this object with lang_keys will
// only have remaining items:
var other_langs = {};
$.map( lang_keys, function( lang_key ) {
other_langs[lang_key] = langs[lang_key];
});
console.log(other_langs);
Related
I have multiple <ul>-s which has attributes id, data-type and data-value. All id-s have a same prefix.
<ul id='req-*****' data-type='***' data-value='***'>
some <li>-s here
</ul>
. . .
many <ul>-s here
. . .
I have Javascript function where I want to loop through this <ul>-s whose ids starting with 'req' and collect data-type and data-value attribute values like that:
function collect(){
var data = [];
$.each( uls_starting_with_req, function( key, value ) {
data.push({data_type: 'ul_data_type', data_value: 'ul_data_value'});
});
}
So how can I achieve this?
function collect(){
var data = [];
$('ul').each(function(){
var id = $(this).attr('id');
if(id.startsWith('req') ) {
var dataType = $(this).data('type');
var dataValue = $(this).data('value');
data.push({data_type: dataType, data_value: dataValue})
}
})
}
Following is a way to do it:
var data = [];
$("ul[id^='req-']").each(function() {
data.push({ data_type: $(this).data('type'), data_value: $(this).data('value') });
});
The selector selects all the uls which have ID starting with req- and then each loops on them. In each iteration, the value of the data attributes can be fetched using jQuery's data method, which are then pushed to the array data.
Working example:
var data = [];
$("ul[id^='req-']").each(function() {
data.push({
data_type: $(this).data('type'),
data_value: $(this).data('value')
});
});
console.log(data);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id='req-1' data-type='1' data-value='1'>
<li></li>
</ul>
<ul id='req-2' data-type='2' data-value='2'>
<li></li>
</ul>
<ul id='req-3' data-type='3' data-value='3'>
<li></li>
</ul>
using attribute starts with selector:
function collect(){
var data = [];
$('ul[id^="req-"]').each(function(){
data.push({data_type: '+ $(this).data("type") +', data_value: '+ $(this).data("value") +'});
})
}
Use jquery attribute selector
function collect() {
var data = [];
var getUL = $('ul[id^="req-"]');
$.each(getUL, function(key, value) {
data.push({
data_type: $(value).data('type'),
data_value: $(value).data('value')
});
});
console.log(data)
}
collect()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id='req-1' data-type='x' data-value='y'></ul>
<ul id='somOtherId' data-type='x2' data-value='y2'></ul>
<ul id='req-3' data-type='x3' data-value='y3'></ul>
Modified brk's answer to use map off of the jQuery object
function collect() {
var getUL = $('ul[id^="req-"]');
var data = getUL.map(function(key, value) {
return {
data_type: $(value).data('type'),
data_value: $(value).data('value')
};
});
console.log(data.get())
}
collect()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id='req-1' data-type='x' data-value='y'></ul>
<ul id='somOtherId' data-type='x2' data-value='y2'></ul>
<ul id='req-3' data-type='x3' data-value='y3'></ul>
jQuery is relevant if you have to deal with browsers different implementations/incompatibilities or if what you would like to achieve is quite verbose using vanilla JavaScript.
But if you target recent browsers, you should consider vanilla JavaScript instead since the required code in this case looks pretty the same.
function collect() {
return Array.prototype.slice.call(document.querySelectorAll('ul[id^="req-"]'))
.map(function(x) {
return {data_type: '+ '+x.dataset.type+' +', data_value: '+ '+x.dataset.value+' +'}
});
}
// ES6 version
function collectES6() {
return Array.from(document.querySelectorAll('ul[id^="req-"]'), x => {
return {data_type: `+ ${x.dataset.type} +`, data_value: `+ ${x.dataset.value} +`}
});
}
console.log('Vanilla version (JavaScript 1.6):', collect());
console.log('Es6 version', collectES6());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="req-x" data-type="XX" data-value="xxvalue"></ul>
<ul id="req-y" data-type="YY" data-value="ffvalue"></ul>
<ul id="req-z" data-type="ZZ" data-value="zzvalue"></ul>
I know there are many similar questions posted, and have tried a couple solutions, but would really appreciate some guidance with my specific issue.
I would like to remove the following HTML markup from my string for each item in my array:
<SPAN CLASS="KEYWORDSEARCHTERM"> </SPAN>
I have an array of json objects (printArray) with a printArray.header that might contain the HTML markup.
The header text is not always the same.
Below are 2 examples of what the printArray.header might look like:
<SPAN CLASS="KEYWORDSEARCHTERM">MOST EMPOWERED</SPAN> COMPANIES 2016
RECORD WINE PRICES AT <SPAN CLASS="KEYWORDSEARCHTERM">NEDBANK</SPAN> AUCTION
I would like the strip the HTML markup, leaving me with the following results:
MOST EMPOWERED COMPANIES 2016
RECORD WINE PRICES AT NEDBANK AUCTION
Here is my function:
var newHeaderString;
var printArrayWithExtract;
var summaryText;
this.setPrintItems = function(printArray) {
angular.forEach(printArray, function(printItem){
if (printItem.ArticleText === null) {
summaryText = '';
}
else {
summaryText = '... ' + printItem.ArticleText.substring(50, 210) + '...';
}
// Code to replace the HTML markup in printItem.header
// and return newHeaderString
printArrayWithExtract.push(
{
ArticleText: printItem.ArticleText,
Summary: summaryText,
Circulation: printItem.Circulation,
Headline: newHeaderString,
}
);
});
return printArrayWithExtract;
};
Try this function. It will remove all markup tags...
function strip(html)
{
var tmp = document.createElement("DIV");
tmp.innerHTML = html;
return tmp.textContent || tmp.innerText || "";
}
Call this function sending the html as a string. For example,
var str = '<SPAN CLASS="KEYWORDSEARCHTERM">MOST EMPOWERED</SPAN> COMPANIES 2016';
var expectedText = strip(str);
Here you find your expected text.
It can be done using regular expressions, see below:
var s1 = '<SPAN CLASS="KEYWORDSEARCHTERM">MOST EMPOWERED</SPAN> COMPANIES 2016';
var s2 = 'RECORD WINE PRICES AT <SPAN CLASS="KEYWORDSEARCHTERM">NEDBANK</SPAN> AUCTION';
function removeSpanInText(s) {
return s.replace(/<\/?SPAN[^>]*>/gi, "");
}
$("#x1").text(removeSpanInText(s1));
$("#x2").text(removeSpanInText(s2));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
1 ->
<span id="x1"></span>
<br/>2 ->
<span id="x2"></span>
For more info, see e.g. Javascript Regex Replace HTML Tags.
And jQuery is not needed, just used here to show the output.
I used this little replace function:
if (printItem.Headline === null) {
headlineText = '';
}
else {
var str = printItem.Headline;
var rem1 = str.replace('<SPAN CLASS="KEYWORDSEARCHTERM">', '');
var rem2 = rem1.replace('</SPAN>', '');
var newHeaderString = rem2;
}
I'm trying to create a menu from an xml file, via jquery.
I need to run the script for this, on window-load.
It's a dropdown menu with some jquery code to it in my plugins.js
I'm trying to completely add all the items of the xml to the UL of the menu list class...
Here's the code in which I need to add my menu to:
HTML
<li class="w-nav-item level_1 has_sublevel">
<a class="w-nav-anchor level_1" href="#">
<span class="w-nav-icon"><i class="fa fa-files-o"></i></span>
<span class="w-nav-title">Animals</span>
<span class="w-nav-arrow"></span>
</a>
<!-- level 2 -->
<ul class="w-nav-list level_2">
<!---------------1 START animals with sublevel---------------->
<li class="w-nav-item level_2 has_sublevel">
<a class="w-nav-anchor level_2" href="javascript:void(0);">
<span class="w-nav-title">Birds </span>
<span class="w-nav-arrow"></span>
</a>
<!-- level 3 -->
<ul class="w-nav-list level_3">
<li class="w-nav-item level_3">
<a class="w-nav-anchor level_3" href="animals/1_sparrow.html">
<span class="w-nav-title">Sparrow</span>
<span class="w-nav-arrow"></span>
</a>
</li>
<li class="w-nav-item level_3">
<a class="w-nav-anchor level_3" href="animals/1_crow.html">
<span class="w-nav-title">Crow</span>
<span class="w-nav-arrow"></span>
</a>
</li>
</ul>
</li>
<!---------------END animals with sublevel------------------>
<!---------------2 START animals with sublevel---------------->
<li class="w-nav-item level_2 has_sublevel">
<a class="w-nav-anchor level_2" href="javascript:void(0);">
<span class="w-nav-title">Carnivorous Animals</span>
<span class="w-nav-arrow"></span>
</a>
<!-- level 3 -->
<ul class="w-nav-list level_3">
<li class="w-nav-item level_3">
<a class="w-nav-anchor level_3" href="animals/2_tiger.html">
<span class="w-nav-title">Tiger</span>
<span class="w-nav-arrow"></span>
</a>
</li>
</ul>
</li>
<!---------------END animals with sublevel------------------>
<!---------------3 START animals with sublevel---------------->
</li>
<!---------------END animals with sublevel------------------>
And here's the XML From which I need to create the menu..:
XML
<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<item>
<animal_id>1_1</animal_id>
<animal_title>Sparrow </animal_title>
<animal_generic>A Sparrow Bird</animal_generic>
<animal_category>Birds </animal_category>
<animal_code>Code 152</animal_code>
<animal_img>images_animals/1_1_sparrow.png</animal_img>
<animal_url>1_sparrow.html</animal_url>
</item>
<item>
<animal_id>1_2</animal_id>
<animal_title>Crow</animal_title>
<animal_generic>A Crow Bird</animal_generic>
<animal_category>Birds </animal_category>
<animal_code>Code 153</animal_code>
<animal_img>images_animals/1_2_crow.png</animal_img>
<animal_url>1_crow.html</animal_url>
</item>
<item>
<animal_id>2_1</animal_id>
<animal_title>Tiger </animal_title>
<animal_generic>A Wild Tiger</animal_generic>
<animal_category>Carnivorous Animals </animal_category>
<animal_code>Code 151</animal_code>
<animal_img>images_animals/2_1_tiger.png</animal_img>
<animal_url>2_tiger.html</animal_url>
</item>
...
...
...
I'm trying to append all the "items" in the xml to the menu, as per the div format of li list. After the <ul class="w-nav-list level_2">
I have this code, that I was using to add "countries" to in my contact form, but I don't know how to change it to add the required divs.
not related to the question, but a simple code
var cList = $('ul.w-nav-list.level_2')
$.each(data, function(i)
{
var cat_no = data.id.split('_');
var opt = $('<option/>')
.attr('value', countries[i])
.text(countries[i])
.appendTo(cList);
});
I have the XML id in the format of:
XML ID format
1_1: first item, category 1,
1_2: second item, category 1,
1_3: third item, category, 1,
2_1: fourth item, category 2,
3_1: fifth item, category 3,
..... like this there are about 10-13 categories with about 100 xml items.
I believe something of this sort should do:
ajax: xml_url, etc
xml response, data ,
data.xml_id.split('_'); //to get the first element of the xml id, but I guess this would only return the last element. Don't know how to change it to return first element.
function add_menu(){
$('ul.w-nav-list level_2').append(data, function ( ){ for(i=0;i<=data.length) for all data.xml_id==i: add category + item divs, li, ul, /li, /ul) }
The above is just a kindof alogrithm or a way of how I think this can be done... I don't know how to do this in jquery/javascript.
Here's what I'm trying to do in javasacript/jquery:
Javascript
var animalsXMLurl = 'http://dl.dropboxusercontent.com/u/27854284/Stuff/Online/XML_animals.xml';
$(function() {
$.ajax({
url: animalsXMLurl, // name of file you want to parse
dataType: "xml",
success: function parse(xmlResponse){
var data = $("item", xmlResponse).map(function() {
return {
id: $("animal_id", this).text(),
title: $("animal_title", this).text(),
url: $("animal_url", this).text(),
category: $("animal_category", this).text().split('/'),
};
}).get();
var categnumber = new Array();
for(i=0;i<=data.length;i++) //for splitting id, and getting 0 for category_number (1 or 2 or 3...and so on)
{ categnumber[i] = data[i].id.split('_');
console.log(categnumber[i][0]);
for(j=0;j<=data.length;j++) //appending via a function.
{ var data_text = category_or_animal(data, categnumber, j);
console.log(data_text);
$('ul.w-nav-list.level_2').append( data_text );
}
}
function category_or_animal(d, catg, k){
var catg1 = new Array();
var catg2 = new Array();
var catg1 = d[k].id.split('_');
if(d[k-1]){
var catg2 = d[k-1].id.split('_');
//if(d[k-1].id)
if (catg1[0] != catg2[0])
return category_gen(d,k);
} else return '</ul>' + animal_gen(d,k);
}
function category_gen(d,z){
var category_var = '<li class="w-nav-item level_2 has_sublevel"><a class="w-nav-anchor level_2" href="javascript:void(0);"><span class="w-nav-title">' + d[z].category + '</span><span class="w-nav-arrow"></span></a><ul class="w-nav-list level_3">';
return category_var;
}
function animal_gen(d,z){
var animal_var = '<li class="w-nav-item level_3"><a class="w-nav-anchor level_3" href="animals/' + d[z].url + '"><span class="w-nav-title">' + d[z].title + '</span><span class="w-nav-arrow"></span></a></li>';
return animal_var;
}
}, error: function(){console.log('Error: Animals info xml could not be loaded.');}
});
});
Please could someone provide help regarding this?
Here's the jsfiddle WITHOUT the menu filled in html: http://jsfiddle.net/mohitk117/d7XmQ/2/
And here's the jsfiddle, WITH the menu filled in html, this is the a general idea of what I'm trying to get in the menu, but only being created dynamically via jquery+xml and not hardcoded like the html example here: http://jsfiddle.net/mohitk117/r6LQg/
I didn't know how to upload the xml to the fiddle, and also didn't know what javascript code to write down, so I kept the code similar to an alogrithm.
EDIT:
Updated the javascript code... +
Updated jsfiddle: http://jsfiddle.net/mohitk117/d7XmQ/4/
Thanks..
I asked another question for the same problem, but the new question was different. And I received a reply from DannyFritz with the answer. His code perfectly exhausts the xml file and puts the revelant fields into a list format. That was not completely what I was trying to do, but after some additions and minor easier changes, I got the menu functioning.
Here's the complete edited code of my version of the xml based menu: [ ::: JsFiddle ::: ]
"use strict";
var animalsXMLurl = 'http://dl.dropboxusercontent.com/u/27854284/Stuff/Online/XML_animals.xml';
$(function () {
var $menu = $('.w-nav-list.level_2');
$.ajax({
url: animalsXMLurl, // name of file you want to parse
dataType: "xml",
success: handleResponse,
error: function () {
console.log('Error: Animals info xml could not be loaded.');
}
});
function handleResponse(xmlResponse) {
var $data = parseResponse(xmlResponse);
createMenu($data);
}
function parseResponse(xmlResponse) {
return $("item", xmlResponse).map(function () {
var $this = $(this);
return {
id: $this.find("animal_id").text(),
title: $this.find("animal_title").text(),
url: $this.find("animal_url").text(),
category: $this.find("animal_category").text()
};
});
}
function createMenu($data) {
var categories = {};
$data.each(function (i, dataItem) {
if (typeof categories[dataItem.category] === 'undefined') {
categories[dataItem.category] = [];
}
categories[dataItem.category].push(dataItem);
});
for (var category in categories) {
var categoryItems = categories[category];
$menu.append($('<li class="w-nav-item level_2 has_sublevel">').html('<a class="w-nav-anchor level_2" href="javascript:void(0);"><span class="w-nav-title">' + category + '</span><span class="w-nav-arrow"></span></a>' + createCategory(categoryItems) + '</li>'));
} //console.log($menu.html());
}
function createCategory(categoryItems) {
var $list = $('<p>');
$.each(categoryItems, function (i, dataItem) {
var $item = $('<li class="w-nav-item level_3"></li>')
.html('<a class="w-nav-anchor level_3" href="' + dataItem.url + '"><span class="w-nav-title">' + dataItem.title + '</span><span class="w-nav-arrow"></span></a>');
$list.append($item);
});
var list_array = ['<ul class="w-nav-list level_3">' , '</ul>'];
return list_array[0] + $list.html() + list_array[1];
}
function createItem() {}
});
I found a solution using an AJAX request and jQuery.parseXML based on this question:
Load xml from javascript
$(function() {
$.get(
'animals.xml',
{},
function(data) {
xml = $.parseXML(data);
populateMenu(xml);
});
function populateMenu(xml) {
xml_items = xml.getElementsByTagName('item');
for(var i in xml_items) {
var animal_id = xml_items[i].childNodes[1].innerHTML;
var animal_title = xml_items[i].childNodes[3].innerHTML;
var animal_generic = xml_items[i].childNodes[5].innerHTML;
var animal_category = xml_items[i].childNodes[7].innerHTML;
var animal_code = xml_items[i].childNodes[9].innerHTML;
var animal_img = xml_items[i].childNodes[11].innerHTML;
var animal_url = xml_items[i].childNodes[13].innerHTML;
$('.w-nav-list.level_3').append('<li class="w-nav-item level_3"><a class="w-nav-anchor level_3" href="'+animal_img+'"><span class="w-nav-title">'+animal_title+'</span><span class="w-nav-arrow"></span></a></li>');
}
}
});
The code can be highly optimized, but it can help you to figure out how to do it.
Here is a working jsfiddle.
Im strating to implement ember in my project and i cant find a way to support basic handlebars functions.
What I need is a list with a < br> tag after first 4 < li> items.
The Handlebars site suggets such function
Ember.Handlebars.registerHelper('list', function(context, options) {
var ret = "<ul>";
for(var i=0, j=context.length; i<j; i++) {
ret = ret + "<li>" + options.fn(context[i]) + "</li>";
if(i==3){
ret += '<br id="ok">'
}
}
return ret + "</ul>";
});
The object:
var Test = [
{ url: "http://www.yehudakatz.com", title: "Katz Got Your Tongue" },
{ url: "http://www.sproutcore.com/block2", title: "SproutCore Blog" },
{ url: "http://www.sproutcore.com/block", title: "ssss Blog" },
{ url: "http://www.Blog.com/block", title: "BlogBlog" },
];
Ember code:
App.TestRoute = Ember.Route.extend({
model: function() {
return Test;
}
});
Template:
<script type="text/x-handlebars" id="Test">
<div>
<span>test</span>
</div>
{{#each model}}
{{title}}
{{/each}}
</script>
But as a result, the object is either parsed as string, giving 5 (5 letters in 'model' word) empty iterations (with < br> though).
However, if I use #each, the object is parsed, But my links look like this:
< a href="<script id='metamorph-7-start' type='text/x-placeholder'></script>http://www.yehudakatz.com<script id='metamorph-7-end' type='text/x-placeholder'></script>"><script id="metamorph-8-start" type="text/x-placeholder"></script>Katz Got Your Tongue<script id="metamorph-8-end" type="text/x-placeholder"></script>< /a>
Please give me a hint how to solve the case.
Ember change some things in handlebars helpers to enable binding, so this is why your html have that metamorph tags. To use plain handlebars helpers without ember stuff you can change your template type to text/x-raw-handlebars:
<script type="text/x-raw-handlebars" id="Test">
<div>
<span>test</span>
</div>
{{#list content}}
{{title}}
{{/list}}
</script>
And use Handlebars.registerHelper instead of Ember.Handlebars.registerHelper:
Handlebars.registerHelper('list', function(context, options) {
var ret = "<ul>";
for(var i=0, j=context.length; i<j; i++) {
ret = ret + "<li>" + options.fn(context[i]) + "</li>";
if(i==3){
ret += '<br id="ok">'
}
}
return ret + "</ul>";
});
You can see this in action in that fiddle http://jsfiddle.net/marciojunior/vzsUN/
If your url doesn't need to update by bindings you can use the unbound view helper:
<a {{unbound url}}>{{title}}</a>
Otherwise you can use the bindAttr view helper:
<a {{bindAttr href="url"}}>{{title}}</a>
This wil create a data attribute instead of a metamorph tag, and your html will not break.
Try this
<a {{bind-attr href="url"}}>{{title}}</a>
I am trying to use JQuery to parse a sitemap.xml to look like this HTML: http://astuteo.com/slickmap/demo/
After working on it for a few hours I decided I really need some help in the right direction.
the main template it has is this, where each indent is a different directory level:
<ul id="primaryNav" class="col4">
<li id="home">Home</li>
<li>Services
<ul>
<li>Graphic Design</li>
<li>Web Development</li>
<li>Internet Marketing
<ul>
<li>Social Media</li>
<li>Search Optimization</li>
<li>Google AdWords</li>
</ul>
</li>
<li>Copywriting</li>
<li>Photography</li>
</ul>
</li>
</ul>
I am using a google sitemap.xml which looks like this:
http://meyers.ipalaces.org/sitemap_000.xml
<url>
<loc>http://meyers.ipalaces.org/</loc>
<lastmod>2011-02-26T09:32:18Z</lastmod>
<changefreq>hourly</changefreq>
<priority>0.4</priority>
</url>
<url>
<loc>http://meyers.ipalaces.org/meyers/photos/Explorer</loc>
<lastmod>2011-02-26T09:31:33Z</lastmod>
<changefreq>hourly</changefreq>
<priority>0.2</priority>
</url>
The method I came up with avoids setting everything exactly how it is on the css template, but instead I just focused on getting it to have the correct levels:
What it does is takes the level of a URL goes through each level trying to create the list based on the previous level. So with the example www.example.com/brand/model/product/:
it gets the first [0] element, www.example.com this is level 1 so it checks is there a ul[id=1], if not then run create_ul and append it to #content. Now attach a li to the ul it just made..level 1 is "special" because it has to be created first, thats why I have a lot of if level==1 in the code.
For the next element [1] it gets brand which is level 2. This time it checks
is there a li[id=www.example.com] ul[id=2] if there exist, it will create one and then attach a li to the ul.
This method isn't working out for me at all, it also messes up if say level 8 has the same id and something from level 4. I just need a new idea on how to approach this.
Here is my functions as of now, but im sure I should just scrap most of the code:
function create_ul(level, id, prev_id) {
var ul = $('<ul/>',{
id: level
});
if(level==1) {
$('#content').append(ul);
} else {
$('ul[id='+(level-1)+'] li[id='+prev_id+']').append(ul);
}
}
function create_li(level, id, prev_id){
if (level ==1){
if ($('ul[id='+level+']').length == 0) {
create_ul(level, id, prev_id);
} else if ($('ul[id='+level+'] li[id='+id+']').length > 0) {
return;
}
var li = $('<li/>',{
id: id
});
var a = $('<a/>',{
text: level + " - " + id,
href: "nothing yet"
});
$('ul[id='+level+']').append(li);
return;
}
// If there is no UL for the LI, create it
if ($('li[id='+prev_id+'] ul[id='+level+']').length == 0) {
create_ul(level, id, prev_id);
} else if ($('ul[id='+level+'] li[id='+id+']').length > 0) {
return;
}
var li = $('<li/>',{
id: id
});
var a = $('<a/>',{
text: level + " - " + id,
href: "nothing yet"
});
li.append(a);
$('li[id='+prev_id+'] ul[id='+level+']').append(li);
}
$.ajax({
type: "GET",
url: "/sitemap_000.xml",
dataType: "xml",
success: parseXml
});
function parseXml(xml) {
URLS = new Array(new Array(), new Array(), new Array());
$(xml).find("loc").each(function(){
var url = $(this).text();
URLS[1].push(url);
url = url.replace("http://", "")
var url_array = url.split("/");
URLS[0].push(url_array);
var rawLastMod = $(this).parent().find('lastmod').text();
var timestamp = rawLastMod.replace(/T.+/g, '');
var lastMod = formatDate(timestamp);
URLS[2].push(lastMod);
});
$(URLS[0]).each(function(i, url_array){
$(url_array).each(function(index, fragment){
var level = index+1;
var id = fragment;
if(index!=0) {
var prev_id = URLS[0][i][index-1];
} else {
var prev_id = null;
}
if(id != "") {
create_li(level, id, prev_id);
}
});
});
}
I have decided to reply on a PHP solution instead of Javascript. I am using this PHP script: http://www.freesitemapgenerator.com/xml2html.html
This is my try to it.
Basically it uses an array to store all the urls' pieces.
For example, the url mytest.url.com/sub1/othersub2.html is handled as:
var map = ['mytest.url.com']['sub1']['othersub2.html'];
This is possible because javascript allows you to index arrays using strings.
Full code (just replace your parseXml function and test it on chrome or firefox with firebug):
<script type="text/javascript">
function parseXml(xml) {
//here we will store nested arrays representing the urls
var map = [];
$(xml).find("loc").each(function () {
//some string cleaning due to bad urls provided
//(ending slashes or double slashes)
var url = this.textContent.replace('http://', '').replace('//', ''),
endingInSlash = (url.substr(url.length - 1, 1) == '/'),
cleanedUrl = url.substr(0, url.length - (endingInSlash ? 1 : 0)),
splittedUrl = cleanedUrl.split('/'), //splitting by slash
currentArrayLevel = map; //we start from the base url piece
for (var i = 0; i < splittedUrl.length; i++) {
var tempUrlPart = splittedUrl[i];
//in javascript you can index arrays by string too!
if (currentArrayLevel[tempUrlPart] === undefined) {
currentArrayLevel[tempUrlPart] = [];
}
currentArrayLevel = currentArrayLevel[tempUrlPart];
}
});
var currentUrlPieces = []; //closure to the recursive function
(function recursiveUrlBuilder(urlPiecesToParse) {
//build up a DOM element with the current URL pieces we have available
console.log('http://' + currentUrlPieces.join('/'));
for (var piece in urlPiecesToParse) {
currentUrlPieces.push(piece);
//recursive call passing the current piece
recursiveUrlBuilder(urlPiecesToParse[piece]);
}
//we finished this subdirectory, so we step back by one
//by removing the last element of the array
currentUrlPieces.pop();
})(map);
}
</script>