JSON and JavaScript integration when formatting a SPARQL query in HTML - javascript

I have an HTML + SPARQL + JSON + JavaScript program that works correctly, shown here: http://ontomatica.com/public/test/clavius.html
Here is the SPARQL + JSON + JavaScript code:
function retrieveData() {
var query = "PREFIX : <http://dbpedia.org/resource/> PREFIX dbp: <http://dbpedia.org/ontology/> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX dbpprop: <http://dbpedia.org/property/> SELECT ?person ?b_date ?d_date ?abstract ?thumbnail WHERE { ?person rdf:type dbp:Person ; dbp:birthDate ?b_date ; dbp:deathDate ?d_date ; dbp:abstract ?abstract . OPTIONAL { ?person dbp:thumbnail ?thumbnail } FILTER ( ?b_date >= '1488-01-01'^^xsd:date && ?b_date < '1600-01-01'^^xsd:date && ?d_date < '1650-01-01'^^xsd:date ) FILTER ( langMatches(lang(?abstract), 'EN')) } ORDER BY ?person ?b_date";
var url = 'http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=' + encodeURIComponent(query) + '&output=json';
$.ajax({
url: url,
dataType: "json",
success: function (data) {
$('#results').show();
$('#raw_output').text(JSON.stringify(data, null, 3));
handle_json(data);
},
error: function(e) {}
});
}
function handle_json(json) {
$('#output_div').text("");
$.each(
json['results']['bindings'], function(index, value) {
var html = "";
name = value['person']['value'].replace("http://dbpedia.org/resource/", "");
name = decodeURIComponent(name.replace(/_/g, " "));
html += "<div><h3><b>" + name + ":</b> (" + value['b_date']['value'] + " - " + value['d_date']['value'] + ")</h3></div>";
if (value['thumbnail'] != null)
html += "<div class='inline thumb'><img style='width: 200px' src='" + value['thumbnail']['value'].replace("200px", "150px") + "'/></div>";
else
html += "<div class='inline thumb'><img src=''/></div>";
html += "<div class='inline abstract'>" + value['abstract']['value'] + "</div><div class='clear'></div><br>";
$('#output_div').append(html);
}
);
}
However, a new version of the program does not work correctly. Here are the components.
The modified SPARQL query works correctly:
PREFIX : <http://dbpedia.org/resource/>PREFIX dbp: <http://dbpedia.org/ontology/>PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>PREFIX dbpprop: <http://dbpedia.org/property/>SELECT ?food ?abstract ?thumbnail ?caption WHERE { ?food rdf:type dbp:Food ; dbpprop:name ?name ; dbpprop:caption ?caption ; dbp:abstract ?abstract . OPTIONAL { ?food dbp:thumbnail ?thumbnail } FILTER ( regex(?name, "Calzone" )) FILTER ( langMatches(lang(?abstract), "EN"))} ORDER BY ?food
I've tested the query on the DBpedia Virtuoso SPARQL end point. Here is the result:
http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=PREFIX+%3A+%3Chttp%3A%2F%2Fdbpedia.org%2Fresource%2F%3EPREFIX+dbp%3A+%3Chttp%3A%2F%2Fdbpedia.org%2Fontology%2F%3EPREFIX+rdf%3A+%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3EPREFIX+dbpprop%3A+%3Chttp%3A%2F%2Fdbpedia.org%2Fproperty%2F%3ESELECT+%3Ffood+%3Fabstract+%3Fthumbnail+%3Fcaption+WHERE+{+%3Ffood+rdf%3Atype+dbp%3AFood+%3B+dbpprop%3Aname+%3Fname+%3B+dbpprop%3Acaption+%3Fcaption+%3B+dbp%3Aabstract+%3Fabstract+.+OPTIONAL+{+%3Ffood+dbp%3Athumbnail+%3Fthumbnail+}+FILTER+%28+regex%28%3Fname%2C+%22Calzone%22+%29%29+FILTER+%28+langMatches%28lang%28%3Fabstract%29%2C+%22EN%22%29%29}+ORDER+BY+%3Ffood&format=text%2Fhtml&timeout=30000&debug=on
So far, so good.
Here is the modified JSON + JavaScript program (with the operational SPARQL query).
function retrieveData() {
var query = "PREFIX : <http://dbpedia.org/resource/>PREFIX dbp: <http://dbpedia.org/ontology/>PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>PREFIX dbpprop: <http://dbpedia.org/property/>SELECT ?food ?abstract ?thumbnail ?caption WHERE { ?food rdf:type dbp:Food ; dbpprop:name ?name ; dbpprop:caption ?caption ; dbp:abstract ?abstract . OPTIONAL { ?food dbp:thumbnail ?thumbnail } FILTER ( regex(?name, "Calzone" )) FILTER ( langMatches(lang(?abstract), "EN"))} ORDER BY ?food";
var url = 'http://dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fdbpedia.org&query=' + encodeURIComponent(query) + '&output=json';
$.ajax({
url: url,
dataType: "json",
success: function (data) {
$('#results').show();
$('#raw_output').text(JSON.stringify(data, null, 3));
handle_json(data);
},
error: function(e) {}
});
}
function handle_json(json) {
$('#output_div').text("");
$.each(
json['results']['bindings'], function(index, value) {
var html = "";
name = value['food']['value'].replace("http://dbpedia.org/resource/", "");
name = decodeURIComponent(name.replace(/_/g, " "));
html += "<div><h3><b>" + name + ":</b> (" + value['caption']['value'] + ")</h3></div>";
if (value['thumbnail'] != null)
html += "<div class='inline thumb'><img style='width: 200px' src='" + value['thumbnail']['value'].replace("200px", "150px") + "'/></div>";
else
html += "<div class='inline thumb'><img src=''/></div>";
html += "<div class='inline abstract'>" + value['abstract']['value'] + "</div><div class='clear'></div><br>";
$('#output_div').append(html);
}
);
}
Here are the differences between the correct program and the incorrect program.
The DBpedia ontology term is changed from 'person' to 'food'.
The query field to be formatted in HTML output (encoded by <div><h3></div></h3>) is changed from ['b_date'] to ['caption'].
I suspect the problem is local to the $.ajax clause and the JSON.stringify statement:
$('#raw_output').text(JSON.stringify(data, null, 3));
Bottom line: I would like to generalize the first program for other applications, but am fumbling the JSON statements.
Why does the second program fail when it is based on the first program? What am I doing wrong?
Is there a better way to generalized the program (1) for other SPARQL queries with different terms; (2) with different numbers of terms; (3) for a SPARQL query of federated databases (only DBpedia is used in the example, but I'd like to format terms from a federated query - mashing up data from different RDF triplestores).
Working Example
Non-working Example

The problem is that you've got unescaped quotes in the second query, which means that the Javascript engine sees a syntax error (an unexpected identifier). The relevant part is in:
var query = "…FILTER ( regex(?name, "Calzone" )) FILTER ( langMatches(lang(?abstract), "EN"))} ORDER BY ?food";
Notice in the syntax highlighting that the string ends at the " immediately before Calzone, etc.
I found this by looking at the Javascript console in Google Chrome when loading your second sample page:
You can fix this by doing:
var query = "…FILTER ( regex(?name, 'Calzone' )) FILTER ( langMatches(lang(?abstract), 'EN'))} ORDER BY ?food";
Once you've done that, you get the kinds of results you'd expect:

Related

Javascript: create dynamic js based on attribute from JSON read from a DB table

I hope someone can help me with some JavaScript that I am stuck on. I guess I would call this dynamic JavaScript. Here is what I'm trying to accomplish.
Overview of the app:
This is an entitlements app, where the user selects an application from a drop down that they need to be entitled to. Once they select the app, the system reads a db record for this app. In that record, there is JSON that defines what other information needs to be prompted for and the app will dynamically build the prompts and append to the HTML.
Read some JSON from a DB table using ajax (this works fine)
Using the 'variable' attribute from the JSON, create the following code substituting varname with the name defined in the variable attribute.
Code:
$('select[name="varname"]').on('change', function() {
var varname = $('select[name="varname"]').val(); });
JSON
{
"prompts": [{
"id": "1",
"enabled": "1",
"required": "1",
"prompt": "AWS Account Number ",
"variable": "aws_account_number",
"type": "select",
"value_list_type": "table",
"table_name": "cld_accounts",
"filter": "filter=accounttype,eq,aws&filter=accountstatus,eq,open&filter=rootaccountowner,eq,sts",
"order": "order=accountnumber",
"value_column": "record.accountnumber",
"dropdown_definition": "'record.accountnumber + \" - \" + record.clientid + \" - \" + record.alias'"
},
{
"id": "2",
"enabled": "1",
"required": "1",
"prompt": "Requested Permission ",
"variable": "permission",
"type": "select",
"value_list_type": "table",
"table_name": "aws_sso_mapping_from_ad",
"filter": "filter=accountnumber,eq,aws_account_number",
"order": "order=rolename",
"value_column": "record.rolename",
"dropdown_definition": "'record.rolename'"
}
]}
so, everywhere that 'varname' appears in that select function, it needs to be 'aws_account_number' so that this is the code that is generated:
$('select[name="aws_account_number"]').on('change', function() {
var aws_account_number = $('select[name="aws_account_number"]').val(); });
Below is my function code. Right after eval(ssrc1) (I know I shouldn't be using eval) is what I can't get to work. I have tried eval, string replace, template literals, etc., nothing seems to work.
Maybe there is a better way if anyone has any other suggestions. Basically what I need after the user completes all the prompts is to be able to send that data to handler that will entitle the user for the app. The problem is app 1 may have two prompts, app 2 may have four prompts.
// Get additional data based on selected application
$('select[name="application"]').on('change', function() {
var appId = $('select[name="application"]').val();
getApplicationConfig(appId);
});
function getApplicationConfig(appId) {
url = "/apiv1/api.php/records/ent_appconfig?filter=id,eq," + appId
console.log('getting application config, appId: ' + appId);
webix.ajax().headers({
"<?php echo $api_header_key?>":"<?php echo $api_header_value?>",
"Access-Control-Allow-Origin":"*"
}).get(url).then(function(data){
app_data = JSON.parse(data.text());
app_data.data[0].prompts_json.prompts.forEach(generateHTML);
function generateHTML(item) {
if ((item.type == 'select') && (item.enabled == '1')) {
console.log('generateHTML: ' + JSON.stringify(item));
html = gen_html_select(item.variable, item.prompt, item.required);
$('#additional_questions').append(html); // Append generated html to additional_questions div
// Select that uses table for options
if (item.value_list_type == 'table') {
vx = "var1";
ssrc1 = ''; // clear the variable
ssrc1 = 'url = "' + generateURL(item.table_name, item.filter, item.order) + '"; \
webix.ajax().headers({ "<?php echo $api_header_key?>":"<?php echo $api_header_value?>", \
"Access-Control-Allow-Origin":"*" \
}).get(url).then(function(data){ \
app_data = JSON.parse(data.text()); \
console.log(app_data.data); \
app_data.data.forEach(generateSelectOptions); \
});'
eval(ssrc1);
console.log("url: " + url);
window[item.variable] = "TEST123456";
console.log('window item.variable: ' + aws_account_number);
console.log('wiv: ' + window[item.variable]);
ssrc2 = '$(\'select[name="\' + item.variable + \'"]\').on(\'change\', function() { \
window[item.variable] = $(\'select[name="\' + item.variable + \'"]\').val(); \
console.log(\' accountnumber \' + aws_account_number); \
});'
console.log('ssrc2: ' + ssrc2);
//xxx = eval(ssrc2);
//var_dump(ssrc2);
//console.log('ssrc2: ' + xxx);
// var k = item.variable;
// console.log('item_variable: ' + k);
// //eval('var ' + k + '= ' + 'david;');
// //eval('var ' + k + ' = 10;');
// eval('var ' + k + ' = 100;');
// console.log('variable: ' + eval('item.variable;'));
} // End select table
// Select that uses the app JSON for options
if (item.value_list_type == 'list') {
console.log("select list");
console.log(item.list_values);
//app_data2 = JSON.parse(item.list_values);
app_data2 = item.list_values;
//console.log(app_data2);
app_data2.forEach(get_permission);
console.log("finished");
} // End select list
} // End if item.type = select and item.enabled = 1
function generateSelectOptions(record) {
// Needs to stay in generateHTML function to access the item object
option_template = 'newOption = new Option(<DISPLAY>, <VALUE>);'
// Replace placeholders in template with values from app JSON
var result = option_template.replace(/<VALUE>/gi, eval(item.value_column));
result = result.replace(/<DISPLAY>/gi, eval(item.dropdown_definition));
eval(result);
aws_account_number.add(newOption, undefined);
} // End generateSelectOptions
} // End generateHTML
$(".select2").select2();
// $('select[name="aws_account_number"]').on('change', function() {
// var accountnumber = $('select[name="aws_account_number"]').val();
// console.log('accountnumber ' + accountnumber);
// });
}); // End webix ajax call
} // End getApplicationConfig

$('#' + postFormId ).html( xml ) throwing Unexpected call to method error

Edit:I have tried jquery versions 1.11.3 and 1.4.2
The following code throws the error "Unexpected call to method or property access" when emulating previous versions of ie(5 and 7). Using this emulation is not optional as it is set by a third party IT. It works fine in IE8 and there was a version that was essentially the same code (I copy and pasted it, and made a couple of changes) used to work in 5 and 7.
Using console.logs, I'm fairly certain that the issue is in $('#' + postFormId ).html( xml ) though I could be wrong.
if( punchOutCartPage != "SalesOrder" ) {
$(document).on('click','#btn-proceed-checkout',function(){
var itemsXML = parseShoppingCart();
var headerXML = "\t<header>\n\t\t{sellerId}\n\t\t{buyerID}\n\t\t{sessionId}\n\t</header>";
var shoppingCartXML = createNetSuiteShoppingCart( headerXML, itemsXML );
var form = $("#cart");
var form_action = form.attr("action");
$.ajax({
url:'/app/site/backend/emptycart.nl?c=',
context: document.body,
success: function(data){
var form_serialized = form.serialize();
$.post(form_action, form_serialized,
function (val) {
postToPunchOutUrl(punchOutUserCartUrl, shoppingCartXML);
}
);
}
});
return false;
});
}
function parseShoppingCart() {
}
function createNetSuiteShoppingCart( headerXML, itemsXML ) {
var parentCompany =localStorage.StrparentCompany;
var account =localStorage.Straccount;
var sessionId = localStorage.StrpunchOutSessionId;
headerXML = headerXML.replace("{sellerId}", "<sellerID>" + encodeXML(account) + "</sellerID>");
headerXML = headerXML.replace("{buyerID}", "<buyerID>" + encodeXML(parentCompany) + "</buyerID>");
headerXML = headerXML.replace("{sessionId}", "<PunchOutSessionID>" + encodeXML(sessionId) + "</PunchOutSessionID>");
itemsXML = "<NetSuiteSellerPunchOutShoppingCart>\n" + headerXML + "\n" + "<itemList>\n" + fezzik + "</itemList>\n" + "</NetSuiteSellerPunchOutShoppingCart>";
itemsXML = encodeXML(itemsXML);
var shoppingCartXML = '<input type="hidden" name="shoppingcart-urlencoded" value="{url-encoded-raw-xml}">';
return shoppingCartXML.replace("{url-encoded-raw-xml}", itemsXML);
}
function postToPunchOutUrl( url, xml ) {
var postFormId = "poomform";
$('#' + postFormId ).html( xml );
$('#' + postFormId ).attr( "action", url );
document.forms[postFormId].submit();
}
function encodeXML(string) {
return string.replace(/\&/g, '&' + 'amp;').replace(/</g, '&' + 'lt;').replace(/>/g, '&' + 'gt;').replace(/\'/g, '&' + 'apos;').replace(/\"/g, '&' + 'quot;');
}
This issue was caused by the document mode emulation itself. When internet explorer emulates document mode 5 or 7, it wraps a form tag around your forms in certain cases. So this <form method="POST" name="poomform" id="poomform" action="https://www.example.net"></form> became (I didnt copy it, but approximately)
<form><form method="POST" name="poomform" id="poomform" action="https://www.example.net"></form></form>
Which then throws the unexpected call to method error.
I worked around this by adding the form with javascript after the page had loaded, so I replaced the form in the html with <div id="poomformholder"></div>
and then added a line of jquery to my postToPunchOutUrl function to look like:
function postToPunchOutUrl( url, xml ) {
$('#' + "poomformholder" ).html("<form method=\"POST\" name=\"poomform\" id=\"poomform\" action=\"https://www.example.net\"></form>");
//The id name of our form.
var postFormId = "poomform";
$('#' + postFormId ).attr("action",url);
$('#' + postFormId ).html(xml);
And now everything works. Hopefully this helps someone in the future and thank you for your help!

Kendo mvc Grid ClientTemplate javascript function not working

I have a Kendo mvc Grid and using client template as a column and i wrote a javascript function in the template to return the script block but its seems not working and no javascript error. I also tried to write the script to the client template directly but its not working too.
//html in client template
.Columns(columns =>
{
columns.Template(e =>
{ }).ClientTemplate(
"<div class='table-responsive'>" +
"<table border='0' class='table' >" +
...................................
"</table>" +
"</div>"+
"#=AlignDiv(Id)#"
);
})
//javascript function to return a script block as a string
<script type="text/javascript">
function AlignDiv(Id) {
var result = "<script> $('.calDiv"+Id+"').map(function () {" +
"return $(this).Height();" +
"}).get()," +
"maxHeight = Math.max.apply(null, heights);" +
"$('.calDiv" + Id + "').height(maxHeight);" +
"alert('test')<\/script>";
return result;
}
Thanks a lot,
Dennis
In order to format Kendo Grid Column value with conditionally chosen action you can use one of the suitable examples below. For more information: How Do I Have Conditional Logic in a Column Client Template?
UI for Javascript:
{
field: "EmployeeName", type: "string", width: "55px", title: "Employee Name",
template: "#= GetEditTemplate(data) #"
}
UI for MVC:
...
columns.Bound(t => t.EmployeeName)
.Title("Status Name")
.Template(#<text></text>)
.ClientTemplate("#= GetEditTemplate(data)#").Width("55px");
...
Javascript Method:
<script>
//Change the color of the cell value according to the given condition
function GetEditTemplate(data) {
var html;
if (data.StatusID == 1) {
html = kendo.format(
//"<a class=\"k-button\" href='" + '#Url.Action("Edit1", "Controller")' + "/{0}" + " '>Edit</a> ",
"<span class='text-success'>" +
data.EmployeeName
+ "</span>"
);
}
else {
html = kendo.format(
//"<a class=\"k-button\" href='" + '#Url.Action("Edit2", "Controller")' + "/{0}" + " '>Edit</a> ",
"<span class='text-danger'>Cancel</span>"
);
}
return html;
}
</script>

Append image in function jquery

Good evening.
I have this jquery code which allows me, once you press the Enter key, to post a comment.
Fattio that I run an append with the username and the content that the user wants to publish.
In addition to the username I would also like to "hang" the profile picture using their path. How do I post a photo?
Thanks for your help. Here's the code:
function commento_post(id_post)
{
$('.form-commento'+id_post).click(function ()
{
$('#ins_commento'+id_post).keydown(function (e)
{
var message = $("#commento"+id_post).val();
var username = $("#username").val();
var id_user = $("#id_user").val();
if(e.keyCode === 13)
{
$.ajax(
{
type: 'POST',
url: 'http://localhost/laravel/public/index.php/post/ins_commento',
data: { commento: message, id_post: id_post },
success: function(data)
{
$('#commento'+id_post).val('');
$('#commentscontainer'+id_post).append
(
/*$(".username-commento"+id_post).html
(*/
$('<a/>',
{
text : username, href : 'http://localhost/laravel/public/index.php/utente/'+id_user
}).css({'font-weight':'bold'})
//)
).append(' ').append(message).append($('<br/>'));
var el = $('#numero_commenti'+id_post);
var num = parseInt(el.text());
el.text(num + 1);
}
});
}
});
});
}
In your success function, you could simplify everything quite a bit in the following way while not using jQuery append so much, but just using a variable to store your code and then appending it in one go. This will allow you to append all sort of elements, it's easily parseable for the you and it reduces the amount of calls you have to make.
// Add whatever you want your final HTML to look like to this variable
var html = "<a href='http://localhost/laravel/public/index.php/utente/" + id_user + "' style='font-weight: bold;'>" + username + "</a>";
html += message;
// add an image
html += "<img src='path/to/image.jpg' />"
html += "<br />";
// append to code you constructed above in one go
$('#commentscontainer' + id_post).append(html);
Update
I amended an incorrect quote and changed + id_user + "to + id_user + "', which makes everything after it work.

Posting a JSON string with multiple values to ext js panel

I am working on an element of an application I am developing. I have a small web app dedicated to keep track of clients for a business. Currently my capability is pretty limited. I store the note along with other attributes in the clients table. I decided to try and make it a bit better by adding a note table and updating an ext js panel with the notes.
Everything works if I only have one note in my notes query.
Otherwise I receive this error.
SyntaxError: invalid property id
..._date":"2013-10-08","note_body":"abcd"},{"username":"rcox","bdev_firstname":"Tre...
This is the PHP I am using.
case 'note':
$userid = $_REQUEST['clientID'];
$query = $dbh->prepare("SELECT a.username, b.bdev_firstname, b.bdev_lastname, n.note_date, n.note_body FROM admin a, bdevs b, clients c, notes n WHERE c.clientID=".$userid.";");
$query->execute();
while($cli = $query->fetch()) {
$json = '{"username":"'.$cli['username'].'","bdev_firstname":"'.$cli['bdev_firstname'].'","bdev_lastname":"'.$cli['bdev_lastname'].'","note_date":"'.$cli['note_date'].'","note_body":"'.$cli['note_body'].'"},';
$note .= $json;
}
$note = trim($note, ',');
echo '{success: true, data:'.$note.'}';
break;
This is my ext js function.
function getNote(){
var selectedNote = userGrid.getSelectionModel().getSelected();
Ext.Ajax.request({
url: 'inc/template.php',
params: {list: 'note',
clientID: selectedNote.get('clientID')
},
method: 'POST',
success: function(f,a){
var jsonData = Ext.util.JSON.decode(f.responseText);
if(jsonData.success == true)
{
var username = jsonData.data.username;
var bdev_firstname = jsonData.data.bdev_firstname;
var bdev_lastname = jsonData.data.bdev_lastname;
var note_date = jsonData.data.note_date;
var note_body = jsonData.data.note_body;
RightPanel.update('<b>Admin:</b> ' + username + '<br/><b>Buissiness Dev Rep:</b> ' + bdev_firstname + bdev_lastname + '<br/><b>Note Date:</b> ' + note_date + ' <br/>----------<br/> ' + note_body);
}
else
{
RightPanel.update('Access Denied');
}
},
failure: function(f,a){
Ext.Msg.alert("Error", "Access Denied");
}
});
}
This has been answered below. For more troubleshooting on this topic you can visit my question on Sencha Forums. http://www.sencha.com/forum/showthread.php?273478-MOVED-POST-Posting-a-JSON-array-with-multiple-values-to-ext-js-panel&p=1002545#post1002545
What's the point of using json if you actually don't use it.
case 'note':
$userid = $_REQUEST['clientID'];
$query = $dbh->prepare("SELECT a.username, b.bdev_firstname, b.bdev_lastname, n.note_date, n.note_body FROM admin a, bdevs b, clients c, notes n WHERE c.clientID = ?");
$query->execute(array($userid));
$response = json_encode(array('success'=> true, data => $query->fetchAll(PDO::FETCH_ASSOC)));
echo $response;
break;
And then ext.js part where your error lies - if data is an array, you need to iterate over it, before you can access associative fields, right?
if(jsonData.success == true)
{
var i, item;
for( i = 0; i < jsonData.data.length; i++; ) {
item = jsonData.data[i];
RightPanel.update('<b>Admin:</b> ' + item.username + '<br/><b>Buissiness Dev Rep:</b> ' + item.bdev_firstname+" "+item.bdev_lastname + '<br/><b>Note Date:</b> ' + item.note_date + ' <br/>----------<br/> ' + item.note_body);
}
}

Categories