Child's child in XML - javascript

i have a simple XML file which is loaded on page by a script posted below. It converts from a string to a XML file without any problems, but what complicates everything is the fact, that I can't get to a child's child.
I'd like to know why my code doesn't work and what should I do to get the tag name.
function load_xml() {
$.ajax({
type: "GET",
url: "file.xml",
dataType: "xml",
success: function (xmlData) {
var $first_child = $(xmlData).children()[0];
var first_name = $first_child.nodeName; // returns a proper name of a node
var $second_child = $first_child.children()[0]; // doesn't work
var $second_name = $second_child.nodeName; // returns nothing (don't know why)
},
error: function () {
alert("Could not retrieve XML file.");
}
});
}

In your case $first_child is not a jQuery collection. You need to wrap it with $(). Here is a corrected version.
var first_child = $(xmlData).children()[0]; // [0] actually returns the first "raw" node
var first_name = first_child.nodeName;
var $first_child = $(first_child);
var second_child = $first_child.children()[0];
var second_name = second_child.nodeName;

Related

How To Open URL In New Tab Using Ajax Success?

Here i am trying to open the file in new tab by calling ViewFile action of Doctor controller using Ajax Success which is in functionabc(this) on click of anchor tag.
Now the problem is that everything is as required but the url doesnot open in new tab.
Below is my Ajax
<script>
function abc(thisEvent) {
debugger;
var getDoCredId = $(thisEvent).attr('docCredId');
var parameter = { id: getDoCredId };
$.ajax({
url: "/Doctor/ViewFile1",
type: "get",
dataType: "html",
data: parameter,
success: function (data) {
debugger;
if (data = true) {
debugger;
var getdoctorId = $(thisEvent).attr('docCredId');
var url = "/Doctor/ViewFile/" + getdoctorId;
window.open(url, "_blank");
}
else {
debugger;
showNotification("Error", "warning");
}
}
});
}
Below is my anchor tag HTML
<a title="View Attachment" docCredId = "' + getDocCredId + '" onclick="abc(this)"><i class="btn btn-web-tbl btn-warning fa fa-eye "></i></a>
Below is code behind
public bool ViewFile1(int id)
{
var document = _doctorService.GetDoctorCredentialDetails(id);
string AttachPath = ConfigPath.DoctorCredentialsAttachmentPath;
string strFileFullPath = Path.Combine(AttachPath, document.AttachedFile);
string contentType = MimeTypes.GetMimeType(strFileFullPath);
bool checkFileInFolder = System.IO.File.Exists(strFileFullPath);
if (checkFileInFolder == true)
{
return true;
}
else
{
return false;
}
}
public ActionResult ViewFile(int id)
{
var document = _doctorService.GetDoctorCredentialDetails(id);
string AttachPath = ConfigPath.DoctorCredentialsAttachmentPath;
string strFileFullPath = Path.Combine(AttachPath, document.AttachedFile);
string contentType = MimeTypes.GetMimeType(strFileFullPath);
bool checkFileInFolder = System.IO.File.Exists(strFileFullPath);
bool filedata = System.IO.File.ReadAllBytes(strFileFullPath).Any();
byte[] filedata1 = System.IO.File.ReadAllBytes(strFileFullPath);
var cd = new System.Net.Mime.ContentDisposition
{
FileName = document.FileName,
Inline = true
};
Request.HttpContext.Response.Headers.Add("Content-Disposition", cd.ToString());
return File(filedata1, contentType);
}
Since this is too long for a regular comment, I am posting this as an answer, although it isn't directly going solve the problem because I am not able to reproduce it, but might give some insights and let you check the differences with what happens in your code as compared with this simplified example.
Calling window.open() from jQuery ajax success callback works just fine: https://codepen.io/nomaed/pen/dgezRa
I used the same pattern as you did, without your server code but using jsonplaceholder.typicode.com sample API instead.
There are some issues with the code sample that you might want to consider, even though you didn't ask for comments about it and it's not directly related to your issue (probably):
if (data = true) means data will always be true. You probably mean to do a if (data === true) if you know it's a boolean value, or if (data) if you want to accept any truthy value (true, {}, "something", 42, etc). Judging by the Java code and how you define the response format in the jQuery ajax call, it looks like you're expecting the "data" variable result be an HTML and not a boolean. You might want to try and remove the dataType: "html" row and let jQuery set the data format according to what is coming back from the server, and/or send a JSON formatted response, as in a POJO of { result: true } for a successful response. Then make sure that data.result === true to be sure that you got what you expect.
You should probably add arbitrary data to tags DOM elements the data-* attributes and if you're using jQuery, access them using the .data() selector. White adding just random attributs with string values may work, it's considered an abuse of the HTML and DOM, and the data-* attributes are there specifically for adding any data.
In the abc() function you grab the value of the attribute in the beginning (var getDoCredId = $(thisEvent).attr('docCredId');) but in the callback you're trying to get the value once more. You really don't need it since the success() callback is a closure in the scope of the abc() function and it has access to the value already, so doing var getdoctorId = $(thisEvent).attr('docCredId'); in the callback is really not needed.
I'd also suggest naming getDoCredId variable just as docCredId. Having a "get" prefix usually means that it's a getter function or a reference to some getter. Likewise, the "thisEvent" argument of the main function should probably be called "callerElement" or something like that since it's not an event, it's an actual element that you're passing directly from the DOM when calling abc(this) in the onClick event handler of the <a> anchor. This is just to make the code clearer to understand for anyone who's reading it, and for yourself when you're coming back to it several months in the future and trying to figure out what's going on :)
Try adding async: false to your Ajax request
function abc(thisEvent) {
debugger;
var getDoCredId = $(thisEvent).attr('docCredId');
var parameter = { id: getDoCredId };
$.ajax({
async: false, // <<<----------- add this
url: "/Doctor/ViewFile1",
type: "get",
dataType: "html",
data: parameter,
success: function (data) {
debugger;
if (data = true) {
debugger;
var getdoctorId = $(thisEvent).attr('docCredId');
var url = "/Doctor/ViewFile/" + getdoctorId;
window.open(url, "_blank");
}
else {
debugger;
showNotification("Error", "warning");
}
}
});
}

Jquery parse and save part of XML in localstorage

I have an XML which I am parsing using jquery, it works but I want to only get part of the XML data and then save all that part in localstorage.
My xml looks like this
<channel id="123"><display-name>123</display-name></name></channel>
<channel id="123"><display-name>123</display-name></name></channel>
<channel id="123"><display-name>123</display-name></name></channel>
<programme id="123"><display-name>123</display-name></name></programme>
<programme id="123"><display-name>123</display-name></name></programme>
<programme id="123"><display-name>123</display-name></name></programme>
But I only want to get all the <programme> data and then save that to localstorage. Im not sure how I can only grab the programme sections.
I have tried saving the whole xml but that didnt seem to output any data. This is what what I have tried.
<div id="text"></div>
$(function(){
$.ajax({
type: "GET",
url: "/myxml",
dataType: "xml",
success: function(xml){
window.localStorage.setItem('fullxml', xml)
$("#text").append(window.localStorage.getItem('fullxml'));
},
error: function() {
alert("An error occurred while processing XML file.");
}
});
});
To get a specific node from an XML document, you can select the XML node like this:
Javascript:
var programmeNodes = fullxml.getElementsByTagName('programme');
jQuery:
var programmeNodes = $(fullxml).find('programme');
My Solution:
This solution grabs all <programme> nodes and saves the data into an array and then stores that array in local storage for later use.
Given XML data like this:
var xml = `
<programmes>
<programme id="1">
<display-name>Test 1</display-name>
</programme>
<programme id="2">
<display-name>Test 2</display-name>
</programme>
</programmes>
`;
Will give an array of objects like this which can then be stored.
[
{
id: 1,
name: Test1
},
{
id: 2,
name: Test2
}
]
Full demo code:
var xml = `
<programmes>
<programme id="1">
<display-name>Test 1</display-name>
</programme>
<programme id="2">
<display-name>Test 2</display-name>
</programme>
</programmes>
`;
var fullxml = $.parseXML(xml);
// find <programme> XML elements
var programmeNodes = $(fullxml).find('programme');
// create array for programme data
var programmesArr = [];
// loop through each programme and store data in array
$.each(programmeNodes, function(i) {
var programmeID = $(programmeNodes[i]).attr('id');
var programmeDisplayName = $(programmeNodes[i]).find('display-name').text();
programmesArr.push({
id: programmeID,
name: programmeDisplayName
});
});
// store programmesArr in local storage
// localStorage only allows strings, so we need to convert array to JSON string
localStorage.setItem('programmes', JSON.stringify(programmesArr));
// get programmes from local storage
var storedProgrammes = JSON.parse(localStorage.getItem('programmes'));
DEMO: https://jsfiddle.net/1nLw7hjr/13/
Usage:
var programmeToFind = 2;
var programme = $.grep(storedProgrammes, function(e) {
return e.id == programmeToFind;
});
console.log(programme[0].id); // 2
console.log(programme[0].name); // Test2
Or as a little function:
function searchProgrammes(id) {
var programme = $.grep(storedProgrammes, function(e) {
return e.id == id;
});
return programme[0];
}
var programme = searchProgrammes(2);
console.log(programme.id); // 2
console.log(programme.name); // Test2
grep()
Finds the elements of an array which satisfy a filter function. The
original array is not affected.
I think you don't get any response because when you append the XML to the document, the browser try to parse it, and because this isn't valid HTML, it fails and show only the text, not the tags. So, the simplest solution will to not use jQuery's append() method, and instead, append the XML via text() (that doesn't parse the HTML tags, and instead escapes them), like:
$(function() {
$.ajax({
type: "GET",
url: "/myxml",
dataType: "xml",
success: function(xml) {
window.localStorage.setItem('fullxml', xml);
var el = $("#text");
el.text(el.text() + window.localStorage.getItem('fullxml'));
},
error: function() {
alert("An error occurred while processing XML file.");
}
});
});
Edit:
If you want to store only some elements, you should convert the XML to objects. Use DOMParser, as follows:
$(function() {
$.ajax({
type: "GET",
url: "/myxml",
dataType: "xml",
success: function(xml) {
var xmldoc;
if (window.DOMParser) {
parser = new DOMParser();
xmldoc = parser.parseFromString(xml, "text/xml");
} else { // Internet Explorer
xmldoc = new ActiveXObject("Microsoft.XMLDOM");
xmldoc.async = false;
xmldoc.loadXML(xml);
}
var programmes = xmldoc.getElementsByTagName('programme');
var str = '';
programmes.forEach(function(el) {
str += el.outerHTML;
});
// str now contains only the <programme> elements
window.localStorage.setItem('fullxml', str);
var el = $("#text");
el.text(el.text() + window.localStorage.getItem('fullxml'));
},
error: function() {
alert("An error occurred while processing XML file.");
}
});
});

JavaScript Saving data from an ajax request

Challenge:
While on URL1(random wikipedia page), make an ajax request to URL2(100 most common words wikipedia page), format a list out of the returned data to be used later.
I have to run this from the console while on "URL1"
example:
Navigate to URL1
Open Console
paste code
hit enter
So far I have been able to grab the entire html source while on URL1 with the following:
$.ajax({
url: 'https://en.wikipedia.org/wiki/Most_common_words_in_English',
type: 'GET',
dataType: 'html',
success: function (response) {
console.log(response); // works as expected (returns all html)
}
});
I can see in the console the entire HTML source -- I then went to URL2 to figure out how to grab and format what I needed, which I was able to do with:
var array = $.map($('.wikitable tr'),function(val,i){
var obj = {};
obj[$(val).find('td:first').text()] = $(val).find('td:last').text();
return obj;
});
console.log(JSON.stringify(array));
Now this is where my issue is -- combining the two
$.ajax({
url:'https://en.wikipedia.org/wiki/Most_common_words_in_English',
type:'GET',
dataType:'html',
success: function(data){
// returns correct table data from URL2 while on URL2 -- issue while running from URL1
var array = $.map($('.wikitable tr'),function(val,i){
var obj = {};
obj[$(val).find('td:first').text()] = $(val).find('td:last').text();
return obj;
});
console.log(JSON.stringify(array));
};
});
Im guessing this is due to the HTML I want to map is now a string, and my array is looking for HTML elements on the current page which it of course would not find.
Thanks
Simple fix here! You're exactly right, it's not parsing the html you return, so just tell jQuery to convert it into an object it can use $(data) and use that to find what you need.
In essence, your 'document' now becomes $(data) which you will use as the source of all your queries.
$.ajax({
url: 'https://en.wikipedia.org/wiki/Most_common_words_in_English',
type: 'GET',
dataType: 'html',
success: function(data) {
var myVar = data;
Names = $.map($(myVar).find('.wikitable tr'), function(el, index) {
return $(el).find('td:last').text()
});
console.log(Names);
}
});

update xml file using JavaScript and jQuery

I have simple XML file
<?xml version="1.0" encoding="utf-8" ?>
<config>
<device>
<node>1</node>
<name>Deposit</name>
<description>Server</description>
<area>Saloon</area>
<type>Server</type>
</device>
</config>
and i have Ajax which is loading xml:
function changename(node2){
var nodenumber = node2
var newname = "newname"
$.ajax({
type: "GET",
url: "config2.xml",
dataType: "xml",
success: function(xml) {
$(xml).find('device').each(function () {
var node = $(this).find('node');
if (node.text() == nodenumber) {
var name = $(this).find('name').text();
alert(name);
}
});
}
});
}
What i need to do is update name in XML. I need to put newname variable value there.
This code only alert old name. Now i need to update xml file new name which is in newname variable.
Please help
use the same function which allows you to get the old name value:
var xml = $(xml);
xml.find('device').each(function () {
var node = $(this).find('node');
if (node.text() == nodenumber) {
$(this).find('name').text(newname);
}
});
you can also change whole your code in the success callback to this:
var xml = $(xml);
var node = xml.find('device>node')
.filter(function(index, node){ return ($(node).text()==nodenumber); })
.parent().find(">name").text(newname);
the point is it is now changed, but only in what you have in xml variable, and if you create another jQuery object, it has the old value.
Consider that it is a client side change (just in browser) in a xml document which is a JavaScript object, after you made your changes in it you should POST it to your server side, and override the new changed xml over the old version.

How to convert simple form submit to ajax call;

I have a form with input field which can be accessed like
var algorithm = document.forms["algoForm"]["algorithm"].value;
var input = document.forms["algoForm"]["input"].value;
and earlier call was
document.forms["algoForm"].submit();
and form was
<form name="algoForm" method="post" action="run.do">
It all run fine
Now I wanted convert it to the ajax call so that I can use the returned data from java code on the same page. So I used soemthing like
var algorithm = document.forms["algoForm"]["algorithm"].value;
var input = document.forms["algoForm"]["input"].value;
var data = 'algorithm = ' + algorithm + '&input = ' + input;
$.ajax(
{
url: "run.do",
type: "POST",
data: data,
success: onSuccess(tableData)
{ //line 75
alert(tableData);
}
}
);
However the above code doesn't run. Please help me make it run
Let's use jQuery's serialize to get the data out of the form and then use the jQuery's ajax function to send the data to the server:
var data = $("form[name=algoForm]").serialize();
$.ajax({
url: "run.do",
type: "POST",
data: data,
success: function(tableData){
alert(tableData);
}
});
data expects a literal object, so you need:
var data = {
'algorithm': algorithm,
'input': input
};
Instead of retrieving all the parameter value and then sending them separately (which can be done server side as well, using below code), Use this:
var $form = $("#divId").closest('form');
data = $form.serializeArray();
jqxhr = $.post("SERVLET_URL', data )
.success(function() {
if(jqxhr.responseText != ""){
//on response
}
});
}
divId is id of the div containing this form.
This code will send all the form parameters to your servlet. Now you can use request.getParameter in your servlet to get all the individual fields value on your servlet.
You can easily convert above jquery post to jquery ajax.
Hope this helps :)
// patching FORM - the style of data handling on server can remain untouched
$("#my-form").on("submit", function(evt) {
var data = {};
var $form = $(evt.target);
var arr = $form.serializeArray(); // an array of all form items
for (var i=0; i<arr.length; i++) { // transforming the array to object
data[arr[i].name] = arr[i].value;
}
data.return_type = "json"; // optional identifier - you can handle it on server and respond with JSON instead of HTML output
$.ajax({
url: $form.attr('action') || document.URL, // server script from form action attribute or document URL (if action is empty or not specified)
type: $form.attr('method') || 'get', // method by form method or GET if not specified
dataType: 'json', // we expect JSON in response
data: data // object with all form items
}).done(function(respond) {
console.log("data handled on server - response:", respond);
// your code (after saving)
}).fail(function(){
alert("Server connection failed!");
});
return false; // suppress default submit action
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I don't know how but this one runs well,
var algorithm = document.forms["algoForm"]["algorithm"].value;
var input = document.forms["algoForm"]["input"].value;
$.post('run.do', {
algorithm : algorithm,
input : input
}, function(data) {
alert(data);
}
);

Categories