get parent element attribute value - javascript

this is my xml document:-
<root>
<child_1 entity_id = "1" value="india">
<child_2 entity_id = "2" value="gujarat">
<child_3 entity_id = "3" value="Ahemdabad"/>
<child_4 entity_id = "4" value="Surat"/>
<child_5 entity_id = "5" value="Rajkot"/>
</child_2>
</child_1>
</root>
this is my javascript html code:-
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
var xml;
var ind_sex;
$.get(
"code.xml",
null,
function (data) {
xml = data;
},
"xml"
);
function get_list() {
var city = $('#name').val();
alert(city);
var xPath = '//*[#value = "city"]' +
'/../../#value';
var iterator = xml.evaluate(xPath, xml.documentElement, null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
var thisNode = iterator.iterateNext();
var str = '';
while (thisNode) {
if (str) {
str += ', ';
}
str += thisNode.textContent;
thisNode = iterator.iterateNext();
}
$("#result").text(str);
}
</script>
</head>
<body>
<input type="text" id="name"></input>
<input type="button" name="button" value="Search" onclick="get_list()">
<div id="result">
</div>
</body>
</html>
here i am try to input in textbox city name if its match on my xml file then its return me there country name.
i dont get any error but not getting result.
i think problem in my xPath pleasae help me out of this.

Use:
var xPath = '//*[#value = "' + city + '"]/../../#value';
An equivalent expression is:
var xPath = '//*[*/*[#value = "' + city + ']]/#value';

As far as I remember, lists don't work like that... they're variables associated with a given value, so it's more like:
list($a, $b, $c) = [1, 2, 3];
Anyway, why don't you take a look at the 'Lists' section in the phpredis page? It's one of the recommended PHP clients for Redis, and its examples are quite clear

Related

Use function parameters as a variable call

what has already been described in the title, but basically I want to send a function perimeter and use it to call one of the three different variables. Also so it doesn't come to a miss understanding the "$('#'+id)" part of the code works all I need is the correct syntax for the "id =" part (if even possible). And I know there is a workaround but I am trying to minimize code and this seems like the most optimal solution.
my code:
<div class="one">
<p>ime:</p>
<input type="text" id="name">
<p>kraj:</p>
<input type="text" id="city">
<p>starost:</p>
<input type="text" id="age">
<p id="one_output"></p>
</div>
var name = "1";
var city = "2";
var age = "3";
function statement(id) {
id = $('#'+id+'').val();
$("#one_output").text("Sem " + name + " in živim v " + city + ". Star sem " + age);
};
$('.one input[type="text"]').keyup(function() {
switch($(this).attr("id")) {
case "name":
statement(the_id);
break;
case "city":
statement(the_id);
break;
case "age":
statement(the_id);
break;
}
});
ok, I think I finally understood what you're after
so you're passing a variable name and want to dynamically call it, instead of going the global way using this, I would recommend to do it by having all your vars in just one global one, for example
var formInputs = { name: '1', city: '2', age: '3' }
and then you can easily read/write them with formInputs[ var_name_here ]
so your example, would be written as
var formInputs = { name: '1', city: '2', age: '3' }
function statement(name, val) {
formInputs[name] = val
var txt = `Sem ${formInputs.name} in živim v ${formInputs.city}. Star sem ${formInputs.age}`
$("#one_output").text(txt)
}
$('.one input[type="text"]').keyup(function() {
var elm = $(this)
statement(elm.attr("id"), elm.val())
})
var formInputs = { name: '...', city: '...', age: '...' }
var statement = function(name, val) {
formInputs[name] = val // assign value to variable
var txt = `Sem <b>${formInputs.name}</b> in živim v <b>${formInputs.city}</b>. Star sem <b>${formInputs.age}</b>` // the new text
$("#one_output").html(txt) // output
}
$('.one input[type="text"]').keyup(function() {
var elm = $(this) // our key element
statement(elm.attr("id"), elm.val()) // pass id and why not the value, so we dont need the element again
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="one">
<p>ime: <input type="text" id="name"></p>
<p>kraj: <input type="text" id="city"></p>
<p>starost: <input type="text" id="age"></p>
<p id="one_output"></p>
</div>
If you want to minimize your code, you can start by doing this:
id = $(`#${id}`).val();
Instead of this:
id = $('#'+id+'').val();
Modify your keyup callback to a more cleaner code:
$('.one input[type="text"]').keyup(function() {
var myId = $(this).attr("id"));
var id = $('#'+myId+'').val();
$("#one_output").text("Sem " + name + " in živim v " + city + ". Star
sem " +
age);
});

csv does not seem to appear due to reference error

I am quite new to this all, so i am pretty sure this is a simple oversight on my part, but i cant get it to run.
When i deploy the code below and click on the button, it does not do anything. When i inspect the html in my browser, it says "userCodeAppPanel:1 Uncaught ReferenceError: csvHTML is not defined
at HTMLInputElement.onclick"
When i run the function csvHTML from Code.gs, I can see the expected results in my Logger.log, so it seems the problem does not lie in my code.gs
What i am trying to achieve is showing the csv results in html. When all works fine, i will want to work with the data in some other way.
Attached below is my code.
Index.html:
<!DOCTYPE html>
<!-- styles -->
<?!= HtmlService.createHtmlOutputFromFile("styles.css").getContent(); ?>
<div class="content">
<h1>csv representation</h1>
<input class="button" type="submit" onclick="html();" value="Refresh" id="refresh"><br>
<div id="tabel"></div>
<svg class="chart"></svg>
</div>
<!-- javascript -->
<script src="//d3js.org/d3.v3.min.js"></script>
<?!= HtmlService.createHtmlOutputFromFile("chart.js").getContent() ?>
<?!= HtmlService.createHtmlOutputFromFile("main.js").getContent() ?>
<script>
function html()
{
var aContainer = document.createElement('div');
aContainer.classList.add('loader_div');
aContainer.setAttribute('id', 'second');
aContainer.innerHTML = "<div class='loader_mesage'><center>Fetching csv list. Please be patient!<br /> <br /><img src='https://i.ibb.co/yy23DT3/Dual-Ring-1s-200px.gif' height='50px' align='center'></img></center></div>";
document.body.appendChild(aContainer);
google.script.run
.withSuccessHandler(showTable)
.csvHTML();
}
function showTable(tabel)
{
document.getElementById("tabel").innerHTML = tabel;
var element = document.getElementById("second");
element.parentNode.removeChild(element);
}
</script>
and Code.gs:
function doGet(e) {
return HtmlService.createTemplateFromFile("index.html")
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
// Fecth Data and make a csv output.
function csvHTML()
{
var query = "{ 'query': 'SELECT * FROM `<some table>` limit 1000;', 'useLegacySql': false }";
var job = BigQuery.Jobs.query(query, <projectName>);
var json = JSON.parse(job);
var tabel = json2csv(json);
Logger.log(tabel)
return tabel;
}
function json2csv(json, classes) {
var headerRow = '';
var bodyRows = '';
classes = classes || '';
json.schema.fields.forEach(function(col){
headerRow +=col.name+",";
})
json.rows.forEach(function(row){
row.f.forEach(function(cell){
bodyRows +=cell.v+",";
})
})
return headerRow + bodyRows }
So thanks to the suggestions by TheMaster, i rewritten it into the following:
index.html:
<!-- javascript -->
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
function html()
{
var aContainer = document.createElement('div');
aContainer.classList.add('loader_div');
aContainer.setAttribute('id', 'second');
aContainer.innerHTML = "<div class='loader_mesage'><center>Fetching csv list. Please be patient!<br /> <br /><img src='https://i.ibb.co/yy23DT3/Dual-Ring-1s-200px.gif' height='50px' align='center'></img></center></div>";
document.body.appendChild(aContainer);
google.script.run
.withSuccessHandler(showTable)
.csvHTML();
}
function showTable(tabel)
{
document.getElementById("tabel").innerHTML = tabel;
var element = document.getElementById("second");
element.parentNode.removeChild(element);
}
</script>
<!DOCTYPE html>
<div class="content">
<h1>csv representation</h1>
<input class="button" type="submit" onclick="html();" value="Refresh" id="refresh"><br>
<div id="tabel"></div>
<svg class="chart"></svg>
</div>
Code.gs has not been modified.
It appears that the <?!= htmlService.createHtmlOutputFromFile("styles.css").getContent(); ?> and other createHtmlOutputFromFile were getting in the way. Eventually i need these, but I will figure out how to incorporate that at a later stage.
Thanks for all the advice and help!
Disclaimer: I have zero experience with Google Apps Script, so take this with a grain of salt.
Looking at their documentation for BigQuery, it seems you are not querying the database correctly. I am surprised by your claim that Logger.log() shows the correct output. It does not appear that it should work.
In case I am right, here is what I propose you change your Code.gs file to:
function doGet(e) {
return HtmlService.createTemplateFromFile("index.html")
.evaluate()
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
// Fetch Data and make a csv output.
function csvHTML() {
var results = runQuery('SELECT * FROM `<some table>` limit 1000;');
var tabel = toCSV(results);
Logger.log(tabel);
return tabel;
}
/**
* Runs a BigQuery query and logs the results in a spreadsheet.
*/
function runQuery(sql) {
// Replace this value with the project ID listed in the Google
// Cloud Platform project.
var projectId = 'XXXXXXXX';
var request = {
query: sql,
useLegacySQL: false
};
var queryResults = BigQuery.Jobs.query(request, projectId);
var jobId = queryResults.jobReference.jobId;
// Check on status of the Query Job.
var sleepTimeMs = 500;
while (!queryResults.jobComplete) {
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
}
// Get all the rows of results.
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
pageToken: queryResults.pageToken
});
rows = rows.concat(queryResults.rows);
}
var fields = queryResults.schema.fields.map(function(field) {
return field.name;
});
var data = [];
if (rows) {
data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
}
return {
fields: fields,
rows: rows
};
}
function toCSV(results) {
var headerRow = results.fields.join(',');
var bodyRows = results.rows.map(function(rowData) {
return rowData.map(function(value) {
// for proper CSV format, if the value contains a ",
// we need to escape it and surround it with double quotes.
if (typeof value === 'string' && value.indexOf('"') > -1) {
return '"' + value.replace(/"/g, '\\"') + '"';
}
return value;
});
})
.join('\n'); // join the lines together with newline characters
return headerRow + '\n' + bodyRows;
}
Reminder: I have not tested this, I'm purely writing this based on my knowledge of Javascript and their documentation and sample code.

How to generate dynamic HTML with jQuery in a loop and a JSON with parameters?

I would like to generate a HTML file out of an JSON in a loop. For example that's the result I want:
<div class="card">
<p>My name is: Peter</p>
<!-- another code -->
<p>My job is: Programmer</p>
<!-- some more code -->
</div>
<div class="card">
<p>My name is: John</p>
<!-- another code -->
<p>My job is: Programmer</p>
<!-- some more code -->
</div>
<!-- and so on ... -->
But I want to generate all that HTML (that means: all the "card"-divs) dynamically just out of an simple JSON like:
[
{ "Name": "Peter", "Job": "Programmer" },
{ "Name": "John", "Job": "Programmer" },
{ "Name": "Kevin", "Job": "Scientist" },
]
Unfortunately I'm just learning some JS/jQuery and don't know exactly, how to do that with jQuery in a loop. Anyone some help?
Try this one:
function createCard(cardData) {
var cardTemplate = [
'<div class="card">',
'<p>My name is: ',
cardData.Name || 'No name provided',
'</p>',
'<p>My job is: ',
cardData.Job || 'No job provided',
'</p></div>'
];
// a jQuery node
return $(cardTemplate.join(''));
}
var data = [
{ "Name": "Peter", "Job": "Programmer" },
{ "Name": "John", "Job": "Programmer" },
{ "Name": "Kevin", "Job": "Scientist" },
];
var cards = $();
// Store all the card nodes
data.forEach(function(item, i) {
cards = cards.add(createCard(item));
});
// Add them to the page... for instance the <body>
$(function() {
$('body').append(cards);
});
Take a look.
https://jsfiddle.net/c0w6jbpa/
$.each(arr, function(i){ //Loop the array
var templateString = '<div class="card"><p>My name is: '+arr[i].Name+'</p><p>My job is: '+arr[i].Job+'</p></div>';
//You can get the prop of array with arr[i].Name
$('#test').append(templateString);
})
You can use $.each for loop an array.
Link: http://api.jquery.com/jquery.each/
Take a look
var jsonData = '[{"Name":"Peter","Job":"Programmer"},{"Name":"John","Job":"Programmer"},{"Name":"Kevin","Job":"Scientist"}]';
UpdateView("#testDiv",jsonData);
function UpdateView(divId,jsonData){
var htmlTemplate = '<div class="card"><p>My name is: {0}</p><!-- another code --><p>My job is: {1}</p><!-- some more code --></div>';
var dataList= JSON.parse(jsonData);
var html ="";
dataList.forEach(function(item){
var temp = htmlTemplate.replace("{0}",item.Name);
temp =temp.replace('{1}',item.Job);
html += temp;
});
$(divId).html(html);}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='testDiv'>
</div>
This will help you to generate divs :
var data = [
{"Name":"Peter","Job":"Programmer"},
{"Name":"John","Job":"Programmer"},
{"Name":"Kevin","Job":"Scientist"},
];
var divs = "";
for( var i = 0; i < data.length;++i) {
divs += "<div class='card'>"
+"<p>My name is: "+data[i].Name+"</p>"
+"<p>My job is: "+data[i].Job+"</p>"
+"</div>";
}
$("p").append(divs);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<P> Hi</P>
In pure JavaScript, you could use a string template and append the HTML to a container, similar to this.
var jsonData = '[{"Name":"Peter","Job":"Programmer"},{"Name":"John","Job":"Programmer"},{"Name":"Kevin","Job":"Scientist"}]'
var htmlTemplate = '<div class="card"><p>My name is: {0}</p><!-- another code --><p>My job is: {1}</p><!-- some more code --></div>'
var newHtml = ''
var container;
var tempContainer;
data = JSON.parse(jsonData);
var addPeople = function() {
for (var i = 0; i < data.length; i++) {
newHtml = htmlTemplate.replace('{0}', data[i].Name).replace('{1}', data[i].Job)
tempContainer = document.createElement('div');
tempContainer.innerHTML = newHtml;
container = document.getElementById('people');
container.appendChild(tempContainer);
}
};
document.addEventListener('DOMContentLoaded', addPeople, false);
<div id="people"></div>
Depending on the browser you might need use document.attachEvent("onreadystatechange"...) instead ofdocument.addEventListener` but in jQuery this has been normalized.
In jQuery you can do the following:
var jsonData = '[{"Name":"Peter","Job":"Programmer"},{"Name":"John","Job":"Programmer"},{"Name":"Kevin","Job":"Scientist"}]'
var htmlTemplate = '<div class="card"><p>My name is: {0}</p><!-- another code --><p>My job is: {1}</p><!-- some more code --></div>'
var newHtml = ''
var container;
var tempContainer;
data = JSON.parse(jsonData);
var addPeople = function(){
for (var i = 0; i < data.length; i++) {
newHtml = htmlTemplate.replace('{0}', data[i].Name).replace('{1}', data[i].Job)
container = $('#people');
container.append(newHtml);
}
};
$('document').ready(function() {
addPeople();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="people"></div>
No need for jquery.
cards.forEach(function(card){
document.body.innerHTML += "<div class='card'><p>My Name is "+card.Name+"</p><p>My Job Is "+card.Job+"</p></div>"
});
You better learn how to do it in native javaScript:
JSON.parse(MyJsonArray).forEach(function (person){
document.getElementById("cardParentEl").innerHTML += ' my name is:'+ person.Name +' my job is:'+ person.Job+'';
});
As you can see, it's messy.. a better way to dynamically create html, if you have to do it very often in your code is to use template engines
Sorry for indentation, I wrote this on a phone

Using results from scriptDB to add to HTML

How can I add a new div tag for each item in scriptDB?
It looks like the code gets stuck when I get to the "while (results.hasNext())" part, possibly because I am using Apps Script syntax in the script section of the HTML. I am able to make the script work when I substitute the entire while loop with just a simple div.innerHTML...etc. line
the index.html file looks like this:
<form id="myForm">
<p>Name of Alert: <input name="alertName" type="text" /></p>
<select name="frequency">
<option value="everyDay">Every day</option>
<option value="everyWeek">Every week</option>
</select>
<input type="button" value="Submit"
onclick="google.script.run
.withSuccessHandler(updateAlertList)
.processForm(this.parentNode)" />
</form>
<script>
function updateAlertList(results) {
var div = document.getElementById('output');
while (results.hasNext()) {
var result = results.next();
div.innerHTML = '' + result.alertName + '';
}
}
</script>
The Code.gs file has this in it:
function processForm(formObject) {
var formAlertName = formObject.alertName;
var formFrequency = formObject.frequency;
var db = ScriptDb.getMyDb();
var alert = {
alertName: formAlertName,
frequency: formFrequency
};
var record = db.save(alert);
var results = db.query({});
return results;
}
Update: worked when I added this to code.gs
var arrayResults = [];
while (results.hasNext()) {
arrayResults.push(results.next());
}
return arrayResults;
and this to index.html
for (var i=0;i<results.length;i++)
{
alert(results[i].alertName);
div.innerHTML = '' + results[i].alertName + '';
}
You need to process the results (iterator) in the gs and create an array of results to work through in the javascript.

Get parent element node when child node is matched

This is my code:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
var xml;
$.get(
"code.xml",
function(data) { xml=data; },
"html"
);
function get_list(){
xmlDoc = $.parseXML( xml ),
$xml = $( xmlDoc ),
$title = $xml.find('[value="'+$('#select').val()+'"]');
$nodes = $title.find('*');
var result='';
$nodes.each(function(){
result += $(this).attr('value');
result += ' ';
});
$("#result").html(result);
}
</script>
</head>
<input type="text" id="select">
<input type="button" name="button" value="Search" onclick="get_list()" >
<div id="result">
</div>
</html>
This is my xml file:
<root>
<child_1 entity_id = "1" value="india">
<child_2 entity_id = "2" value="gujarat">
<child_3 entity_id = "3" value="Ahemdabad"/>
<child_4 entity_id = "4" value="Surat"/>
<child_5 entity_id = "5" value="Rajkot"/>
</child_2>
</child_1>
<child_6 entity_id = "6" value="Rasia">
<child_7 entity_id = "7" value="state">
<child_8 entity_id = "8" value="cty"/>
<child_9 entity_id = "9" value="cty1"/>
<child_10 entity_id = "10" value="cty2"/>
</child_2>
</child_6>
</root>
With this code I get the child node value.
I wanted something, like when i enter in textbox any of city name: Ahemdabad, Surat, Rajkot; then its match on my xml file returns me country name like India.
Thanks!
Try
var xml;
$.get(
"code.xml",
function(data) {
xml=data;
},
"html"
);
function get_list(){
var xmlDoc = $.parseXML( xml ),
$xml = $( xmlDoc ),
$title = $xml.find('[value="'+$('#select').val()+'"]');
var ctrs = $xml.find('root').children();
$("#result").html($title.closest(ctrs).attr('value'));
}
Demo: Plunker
You can use this xpath
//*[#value='Ahemdabad']/parent::*/#value
Just replace 'Ahemdabad' with the desired city name

Categories

Resources