<link href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!------ Include the above in your HEAD tag ---------->
<div class="container">
<div id="qablock_src_ref" class="qablock hide">
<div class="row">
<div id="colw" class="col-md-6">
<div id="panel" class="panel panel-primary">
<div class="panel-heading">
</div>
<div id="radiopanel" class="panel-body">
<p id="basequestion">question</p>
<div id="radioblock_ref" class="radio">
<label>
<input type="radio" id="baseradio" name="radioname" value="option1">radio text
</label>
</div>
</div>
</div>
</div>
</div>
<p class="help">*** child qa blocks get here***</p>
</div>
</div>
var baseQA;
var radioRef;
var sibling;
function xmlParser(data, ht_qablock, level) {
var baseSibling = sibling;
level = level + 1;
$(data).children('question').each( function(qidx, qitm) {
var qv = $(qitm).children('qvalue').text();
var jbookmark = $(qitm).children('bookmark').text();
var ht_q = $(ht_qablock).find('#basequestion');
ht_q.attr('id', 'question_' + level + '_' + sibling);
ht_q.text(qv);
if (jbookmark.length) {
ht_qablock.addClass("jbookmark_" + jbookmark);
}
var rdpanel = ht_qablock.find("#radiopanel");
rdpanel.attr('id', "radiopanel_" + level + '_' + sibling);
$(qitm).children('answer').each(function(aidx, aitm) {
sibling = sibling + 1;
var av = $(aitm).children('avalue').text();
var rd = radioRef.clone();
rd.attr('id', level + '_' + sibling);
var rdd = rd.find("#baseradio");
rdd.attr('id', "radio_" + level + '_' + sibling);
rdd.attr('name', "radioname_" + level + '_' + baseSibling);
rdd[0].nextSibling.nodeValue = av;
rdpanel.append(rd);
var bqa = baseQA.clone();
bqa.attr('id', "qablock_for_" + level + '_' + sibling);
var final = $(aitm).children('final').text();
if (final != '') {
bqa.find("#radiopanel").remove();
//bqa.find("#panel").append("<p>final</p>");
bqa.find("#panel").append("<p>" + final + "</p>");
ht_qablock.append(bqa);
} else {
var jump = $(aitm).children('jump').text();
if (jump != '') {
rdd.addClass("jump");
rdd.attr('value', jump);
} else {
ht_qablock.append(bqa);
xmlParser(aitm, bqa, level);
}
}
});
});
}
function getClosestCommonNode(node1, node2) {
var commonNode = null;
var p1 = node1.parents();
var p2 = node2.parents();
var i = p1.length-1;
var j = p2.length-1;
for (; i>=0 && j>=0; i--, j--) {
if (p1[i] == p2[j])
commonNode = $(p1.get(i));
}
return commonNode;
/*
var parentEls = node.parents().map(function() { return this.tagName;}).get().join( ", " );
parentEls = node.parents().each(function(aidx, aitm) { return this.tagName;}).get().join( ", " );
node.parent().each(function(aidx, aitm) {
*/
}
function processXML(xml) {
sibling = 0;
var baseQAsrc = $('#qablock_src_ref');
var outMark = baseQAsrc.parent();
baseQA = baseQAsrc.clone();
baseQAsrc.remove();
baseQA.attr('id', 'qablock_for_ref');
//baseQA.removeClass('hide');
baseQA.children().remove(".help");
var radioRefSrc = baseQA.find('#radioblock_ref');
radioRef = radioRefSrc.clone();
radioRefSrc.remove();
var out = baseQA.clone();
out.removeClass('hide');
xmlParser(xml, out, 0);
outMark.append(out);
/*
var n1 = out.find('#qablock_for_1_5');
var n2 = out.find('#qablock_for_2_6');
getClosestCommonNode(n1, n2);
*/
$('input[type="radio"]').change(function(){
//$(this).closest(".qablock").children("[id^=qablock_for]").hide();
$(this).closest(".qablock").children("[id^=qablock_for]").addClass('hide');
if ($(this).hasClass("jump")) {
// uncheck jump source
$(this).prop('checked', false);
var jtargetname = ".jbookmark_" + $(this).attr("value");
var target = $(":root").find(jtargetname);
//fix this: target.removeClass('hide');
// uncheck target
target.children().first().find("input").prop('checked', false);
// hide target children
target.children("[id^=qablock_for]").addClass('hide');
// walk from target to root checking the proper choices until common ancestor
var commonAncest = getClosestCommonNode($(this), target);
var wlk = target;
while (wlk.attr("id") != commonAncest.attr("id")) {
// show question block for the answer. Firstr my siblings, then make sure to show me
wlk.siblings("[id^=qablock_for]").addClass('hide');
wlk.removeClass('hide');
// check the answer
var bn = $(wlk).attr("id").replace(/qablock_for_/g, "#radio_");
$(bn).prop('checked', true);
// proceed to parent block
wlk = wlk.parent().closest(".qablock")
}
// scroll to target
var toppos = target.offset().top;
$('body,html').animate({scrollTop: stop}, 1000);
} else {
var blockname = $(this).attr("id").replace(/radio_/g, "");
blockname = "#qablock_for_" + blockname;
//$(blockname).show();
$(blockname).removeClass('hide');
}
});
}
$(document).ready(function() {
/*
$.ajax({
type: "GET" ,
url: "qa.xml",
dataType: "text",
success: function(xmldata) {
xml = $.parseXML(xmldata);
processXML(xml);
},
error: function(a, b, c) {
alert("An error occurred while processing XML file.");
alert(a.status);
}
});
*/
var xmldata = ['<?xml version="1.0" encoding="UTF-8"?>',
'<question xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="qa.xsd">',
' <qvalue>q1</qvalue>',
' <answer>',
' <avalue>a1</avalue>',
' <question>',
' <qvalue>q11</qvalue>',
' <answer>',
' <avalue>a11</avalue>',
' <jump>b21</jump>',
' </answer>',
' <answer>',
' <avalue>a12</avalue>',
' <final>end</final>',
' </answer>',
' <answer>',
' <avalue>a13</avalue>',
' <final>end</final>',
' </answer>',
' </question>',
' </answer>',
' <answer>',
' <avalue>a2</avalue>',
' <question>',
' <qvalue>q21</qvalue>',
' <bookmark>b21</bookmark>',
' <answer>',
' <avalue>a21</avalue>',
' <question>',
' <qvalue>q211</qvalue>',
' <answer>',
' <avalue>a211</avalue>',
' <final>end</final>',
' </answer>',
' <answer>',
' <avalue>a212</avalue>',
' <final>end</final>',
' </answer>',
' <answer>',
' <avalue>a213</avalue>',
' <jump>b21</jump>',
' </answer>',
' </question>',
' </answer>',
' <answer>',
' <avalue>a22</avalue>',
' <final>end</final>',
' </answer>',
' <answer>',
' <avalue>a23</avalue>',
' <final>end</final>',
' </answer>',
' </question>',
' </answer>',
' <answer>',
' <avalue>a3</avalue>',
' <final>end</final>',
' </answer>',
'</question>'].join('\n');
xml = $.parseXML(xmldata);
processXML(xml);
});