Populating JSON array to drop down reserved word column name conflict - javascript

This is the first time ill use JSON. I used the json_encode(myarrayhere) to return array value as shown below.
There is a corresponding value on change of selected value on dropdown.
I verified that I get the array data by using alert(dataArray) and it returns like this
[{"title":"First"},
{"title":"Second"},
{"title":"Third"} ]
I used the word title as column name for a table I'm using in my database.
But the problem now is how to properly populate them in a drop down. I tried to do value.title but it looks like that title is a reserved word/method in php
$.ajax({
type: 'POST',
data: {ctgy: selected},
url: 'awts.php' ,
datatype: 'json',
success: function (dataArray) {
alert(dataArray);
var items = '';
$.each(result,function(name,value) {
items += "<option value='"+value.title+"'>"+value.title)+"</option>";
});
$("#dropdownselectid").html(items);
}
});
Thanks in advance.

Firstly, if you check the console you'll see that you have a syntax error. You have an extra ) when you append value.title to the HTML string.
Secondly, your $.each() call is attempting to loop through result when your data is in a variable named dataArray.
Try this:
$.ajax({
type: 'POST',
data: { ctgy: selected },
url: 'awts.php',
datatype: 'json',
success: function(dataArray) {
var items = '';
$.each(dataArray, function(name, value) {
items += '<option value="' + value.title + '">' + value.title + '</option>';
});
$("#dropdownselectid").html(items);
}
});
Working example

Related

Communication beetween Javascript and PHP scripts in web app

THE CONTEXT
I'm developing a web app that loads contents dynamycally, retrieving data from a
catalogue of items stored as a MongoDB database in which records of the items and their authors are in two distinct collections of the same database.
Authors ID are stored in the item field creator and refer to the author field #id. Each item can have none,one or many authors.
Item sample
{
"_id" : ObjectId("59f5de430fa594333bb338a6"),
"#id" : "http://minerva.atcult.it/rdf/000000016009",
"creator" : "http://minerva.atcult.it/rdf/47734211-2637-3895-a690-4f33412931ec",
"identifier" : "000000016009",
"issued" : "fine sec. XIV - inizi sec. XV",
"title" : "Quadrans vetus",
"label" : "Quadrans vetus"
}
Author sample
{
"_id" : ObjectId("59f5d8e80fa594333bb1d72c"),
"#id" : "http://minerva.atcult.it/rdf/0007e43e-107f-3d18-b4bc-89f8d430fe59",
"#type" : "foaf:Person",
"name" : "Risse, Wilhelm"
}
WHAT WORKS
I query the database submitting a string in a form, using this PHP script
ITEM PHP SCRIPT
<?php
require 'vendor/autoload.php';
$title=$_GET['item'];
$client = new MongoDB\Client("mongodb://localhost:27017");
$db=$client->galileo;
$collection=$db->items;
$regex=new MongoDB\BSON\Regex ('^'.$title,'im');
$documentlist=$collection->find(['title'=>$regex],['projection'=>['_id'=>0,'title'=>1,'creator'=>1,'issued'=>1]]);
$items=$documentlist->toArray();
echo (json_encode($items));
?>
called by a Javascript script (new_search.js) using ajax, that has also the responsibility to attach to html document a <li class=item> for every item that matches the query, inserting the JSON fields and putting them in the provided tags ( <li class=item-name>,<li class=auth-name, and the last <li> in div class=item-info for date).
WHAT DOES NOT WORK
My intent is reproduce the pattern to retrieve author names from another collection in the same database, querying it using author field #id from the html tag <li class=auth-name, using a similar php script and a similar ajax call.
I tried to make a nested ajax call (in the one I used to retrieve the items infos) to invoke author_query.php that performs the MongoDB query on the collection of authors.
So, the question is: Is it possible use the $_GET superglobal to get the html tag that contains the author id #id in order to search it in the database?
Otherwise, how can I adjust the code to pass a javascript variable to php (not by user input) that lets me keep the content already loaded on the page?
UPDATES
To make clearer the question, I follow the tips in the comments and I updated my scripts using JSON directly to provide the needed data.
I also perfom a debug on the js code and it's clear that PHP don't provide any response,in fact ajax calls for authors name fails systematically.
I suppose that occurs because PHP don't receive the data dueto the fact I'm not using the correct syntax probably (in js code or in the php with $_GET or in both) to pass the variable author (I also tried data:'author='+author treating the JSON object author has a string). Anyway I don't understand what is the correct form to write the variable to pass using the data field of ajax().
MY SCRIPTS
JS SCRIPT new_search.js
$(document).ready(function () {
$("#submit").on("tap", function () {
var item = document.getElementById("search").value;
var author;
$.ajax({
url: "item_query.php",
type: "GET",
data: 'item=' + item,
dataType: "json",
async:false,
success: function (items) {
for (var i = 0; i < items.length; i++) {
$("#items-list").append(
'<li class="item">' +
'<div class="item-photo-container">' +
'<img src=images/item_126.jpg>' +
"</div><!--end item-photo-container-->" +
'<div class="item-info">' +
'<ul>' +
'<li><a><h3 class="item-name">' + items[i].title + '</h3></a></li>' +
'<li class="auth-name">' + items[i].creator+ '</li>' +
'<li>' + items[i].issued + '</li>' +
'</ul>' +
'</div><!--end item-info-->' +
'</li><!--end item-->'
);
}
}
});
$('.item').each(function () {
author = $(this).find('.auth-name').text();
if (author == 'undefined')
$(this).find('.auth-name').text('Unknown');
else if(author.indexOf(',')!=-1) {
author='[{"author":"'+author+'"}]';
author=author.replace(/,/g,'"},{"author":"');
author = JSON.parse(author);
console.log(author);
$.ajax({
url: "author_query.php",
type: "GET",
data: author,
dataType: "json",
processData: false,
success: function (auth_json) {
$(this).find('.auth-name').text('');
var author_text=' ';
for(var i=0;i<auth_json.length;i++)
author_text+=auth_json.name+' ';
$(this).find('.auth-name').text(author_text);
},
error: function () {
console.log('Error 1');
}
});
}
else{
author='{"author":"'+author+"}";
author=JSON.parse(author);
$.ajax({
url: "author_query.php",
type: "GET",
data: author,
dataType: "json",
processData: false,
success: function (auth_json) {
$(this).find('.auth-name').text(auth_json.name);
},
error: function () {
console.log('Error 2');
}
});
}
});
});
});
AUTHOR PHP SCRIPT author_query.php
<?php
require 'vendor/autoload.php';
$auth=$_GET['author'];
$client = new MongoDB\Client("mongodb://localhost:27017");
$db=$client->galileo;
$collection=$db->persons;
if(is_array($auth)){
foreach ($auth as $a){
$document=$collection->findOne(['#id'=>$a],['projection'=>['_id'=>0,'name'=>1]]);
$auth_json[]=( MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
}
else{
$document=$collection->findOne(['#id'=>$auth],['projection'=>['_id'=>0,'name'=>1]]);
$auth_json=( MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
echo (json_encode($auth_json));
?>
"I'm sure that authors array... is not empty and actually contains the authors IDs". You mean the jQuery object $('.item')? I think that it is empty, because it is created too soon.
The first $.ajax call sends an ajax request and sets a handler to add more stuff to the HTML, including elements that will match the CSS selector .item. But the handler doesn't run yet because it's asynchronous. Immediately after this, the object $('.item') is created, but it's empty because the new .item elements haven't been created yet. So no more ajax requests are sent. Some time later, the call to item_query.php returns, and the new HTML stuff is added, including the .item elements. But by now it's too late.
You say the array was not empty. I suspect you checked this by running the CSS selector after doing the search, after the return of the ajax call.
A lot of newbies have problems like this with asynchronous javascript. If you want to use the result of an asynchronous function in another function, you have to call the second function inside the callback function of the first one. (Actually there are more sophisticated ways of combining asynchronous functions together, but this is good enough for now.)
On a side note, you've done this in a slightly strange way where you save data in HTML, and then read the HTML to do some more stuff. I wouldn't use HTML as a storage place - just use variables like you would for most other things.
Try this:
$.ajax({
url: "item_query.php",
...
success: function (items) {
for (var i = 0; i < items.length; i++) {
var author = items[i].creator;
var authors;
// insert code here to generate authors from author.split(',') .
// authors should look something like this: [{author: 'http://minerva.atcult.it/rdf/47734211-2637-3895-a690-4f33412931ec'}] .
$.ajax({
url: "author_query.php",
type: "GET",
data: JSON.stringify(authors),
...
success: function (auth_json) {
...
},
error: function () {
console.log('Error 1');
}
});
$("#items-list").append(
'<li class="item">' +
'<div class="item-photo-container">' +
'<img src=images/item_126.jpg>' +
"</div><!--end item-photo-container-->" +
'<div class="item-info">' +
'<ul>' +
'<li><a><h3 class="item-name">' + items[i].title + '</h3></a></li>' +
'<li class="auth-name">' + items[i].creator+ '</li>' +
'<li>' + items[i].issued + '</li>' +
'</ul>' +
'</div><!--end item-info-->' +
'</li><!--end item-->'
);
}
}
});
I make the first call to retrieve the item infos asynchronous and the nested that search for the authors name synchronous. In this way I solved the problem.
For sure it is not the best solution, and it needs a quite long,but acceptable, time (<1 second) to load the content.
JS SCRIPT
$(document).ready(function () {
$("#submit").on("tap", function () {
var item = document.getElementById("search").value;
$.ajax({
url: "item_query.php",
type: "GET",
data: 'item=' + item,
dataType: "json",
success: function (items) {
for (var i = 0; i < items.length; i++) {
var authors_names=' ';
var authors= JSON.stringify(items[i]);
if(authors.indexOf('creator')!=-1){
if(authors.charAt(authors.indexOf('"creator":')+'"creator":'.length)!='[')
authors=authors.substring(authors.indexOf('"creator":"'),authors.indexOf('"',authors.indexOf('"creator":"')+'"creator":"'.length)+1);
else
authors=authors.substring(authors.indexOf('"creator"'),authors.indexOf(']',authors.indexOf('"creator"'))+1);
authors='{'+authors+'}';
//console.log(authors);
$.ajax({
url: "author_query_v3.php",
type: "GET",
data: 'authors='+authors,
dataType:"json",
async:false,
success: function (auth_json) {
authors=[];
authors=auth_json;
var author;
for(var j=0;j<authors.length;j++){
author=JSON.parse(authors[j]);
authors_names+=author.name+" | ";
}
console.log(authors_names);
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR+' '+textStatus+ ' '+errorThrown);
}
});
}
else{
authors_names='Unknown';
}
$("#items-list").append(
'<li class="item">' +
'<div class="item-photo-container">' +
'<img src=images/item_126.jpg>' +
"</div><!--end item-photo-container-->" +
'<div class="item-info">' +
'<ul>' +
'<li><a><h3 class="item-name">' + items[i].title + '</h3></a></li>' +
'<li class="auth-name">' + authors_names+ '</li>' +
'<li>' + items[i].issued + '</li>' +
'</ul>' +
'</div><!--end item-info-->' +
'</li><!--end item-->'
);
}
}
});
});
});
PHP SCRIPT
<?php
require 'vendor/autoload.php';
$auth=$_GET['authors'];
$client = new MongoDB\Client("mongodb://localhost:27017");
$db=$client->galileo;
$collection=$db->persons;
$auth=json_decode($auth);
$auth=$auth->creator;
if(is_array($auth)) {
foreach ($auth as $a) {
$document = $collection->findOne(['#id' => $a], ['projection' => ['_id' => 0, 'name' => 1]]);
$auth_json[] = (MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
}
else{
$document=$collection->findOne(['#id'=>$auth],['projection'=>['_id'=>0,'name'=>1]]);
$auth_json[]=( MongoDB\BSON\toJSON(MongoDB\BSON\fromPHP($document)));
}
echo(json_encode($auth_json));
?>

how to append a html tag from an ajax call response

I have an ajax function :
$('#app-name').change(function () {//1
console.log("inside change");
var applname= this.value;
console.log(applname);
$.ajax({//2
url: 'foo',
method : 'GET',
dataType : "json",
contentType: "application/json",
data: {"AppID":"appname"},
success: function(data){
var order_data = data;
$('#foo-name').html('');
$.each(order_data, function(i, item) {//3
console.log(order_data[i]);
$('<option value='+ order_data[i] +'>'+order_data[i]).html('</options>').appendTo('#foo-name');
});//3
}
});//2
});//1
This function is doing everything else except appending value to the html.
Am i doing it wrong? Can you help solve this issues.
Place the closing </option tag in the jQuery object you create. Don't set it through the html() method. Try this:
$('<option value="' + order_data[i] + '">' + order_data[i] + '</option>').appendTo('#foo-name');
That said, you can also improve performance of your code by building the string in the loop and appending it to the select once, like this:
success: function(data) {
var options = '';
$.each(data.split(/\n/), function(i, item) {
options += '<option value=' + item.trim() + '>' + item.trim() + '</option>');
});
$('#foo-name').html(options);
}
Update You also need to split() the text you state that you're returning before looping through it.
Please use below code in your ajax success event.
success: function(data) {
var _html = '';
$.each(order_data, function(i, item) {
_html += '<option value='+ item +'>'+item+'</options>';
});
$('#foo-name').append(_html);
}

Javascript failing in external file only

Can anyone tell me why I get an error on the 2nd line saying 'unexpected string' but works fine when I have it directly on my view (i'm using MVC 3, not that it makes a difference):
function getUsers(processId) {
$.ajax({
url: "#Url.Action('GetProcessApprovers', 'Risk')",
data: { processId: processId },
dataType: "json",
type: "POST",
error: function () {
alert("An error occurred.");
},
success: function (data) {
var items = "<option value=\"\">-- Please select --</option>"
if (data != "") {
$.each(data, function (i, item) {
items += "<option value=\"" + item.Value + "\">" + item.Text + "</option>";
});
}
$("#ProcessOwnerId").html(items);
}
});
};
Because your url: "#Url.Action('GetProcessApprovers', 'Risk')", only executes in the context of the view, not in an external JS file. It's razor code.
You need to pass the url to the Javascript in some other way, perhaps as a parameter of your function.
getUsers(processId, ajaxUrl)
Another way would be to write out the url from the HtmlHelper into a data attribute in your view and then pick it up in your Javascript.
HTML
<div id="someContainer" data-url="#Url.Action('GetProcessApprovers', 'Risk')">...
JS
var url = $("#someContainer").attr("data-url");
Your url parametre is has the issue.
please change it like this:
url: '#Url.Action("GetProcessApprovers", "Risk")',
Hope it works

Drawind Dynamic series and points with Highchart and ajax

I try to get several series of data from employees and get them drawed through HighCharts.
I don't know the company till the user click, so then I get trough ajax all the employees and their data (points).
I have a select box where I choose the company. Once done, I call via AJAX/jQuery the server to get data added to HighChart:
$("#company").change(function(){
$.ajax({
type: 'POST',
dataType: 'json',
url: xxxxx,
async: false,
data: { company: company},
success: function(data) {
$.each(data, function(val, text) {
alert (val);
alert (text);
chart2.addSeries({
name: val,
data: text
});
});
}
...
Data I get from the server trough Firebug is in this way:
{"Employee1":[["1356908400000","10.00"],["1359586800000","11.00"], ["1362006000000","12.00"],["1364684400000","13.45"]],"Employee2":[["1356908400000","10.00"],["1359586800000","11.00"],["1362006000000","12.00"],["1364684400000","13.45"]]}
Employee1 and Employee2 should be the series.
However when I call addseries method I get this error:
Uncaught Highcharts error #14: www.highcharts.com/errors/14
It seems data doesn't like to Highcharts.
When I debug through alerts, I get this:
alert (val)->Employee1
alert (text)=1356908400000,10.00,1359586800000,11.00,1362006000000,12.00,1364684400000,13.45
This example is working fine when I put data without ajax.
Any idea?
I've found the answer :-)
text is an array so I need another $.each to read it and format the result:
success: function(data) {
$("html").css('cursor','auto');
$.each(data, function(val, text) {
counter = 0;
$.each(text, function() {
if (counter==0) {
employee_data= "[" + this + "]";
}
else{
employee_data= employee_data + "," + "[" + this + "]";
}
counter=1
});
employee_data = "["+ + "]";
chart.addSeries({
name: val,
data: employee_data
});
});
},

Using Ajax callback variable values in JQuery dynamic click handlers

I'm doing a simple ajax query which retrieves a variable-length list of values as JSON data. I'm trying to make a list based on this data which has click-functions based on the values I got from the JSON query. I can make this work just fine by writing the onClick-methods into the HTML like this:
function loadFooList() {
var list_area = $("#sidebar");
list_area.html("<ul>")
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosesfoo" + item.id;
list_area.html(list_area.html()
+ "<li> <a href='#' onClick='alert(\"" +
link_id + "\");'>" +
item.name + "</a></li>");
});
list_area.html(list_area.html() + "</ul>");
}
});
}
I don't like writing the onClick-function into the HTML and I also want to learn how to create this same functionality via JQuery click-function.
So the problem is obviously variable-scoping. My naive attempt here obviously won't work because the variables are no longer there when the click happens:
function loadFooList2() {
var list_area = $("#sidebar");
var link_ids = Array();
list_area.html("<ul>")
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosefoo" + item.id;
list_area.html(list_area.html()
+ "<li> <a href='#' id='" + link_id + "'>"+item.name+"</a></li>");
link_ids.push(link_id);
});
list_area.html(list_area.html() + "</ul>");
for (link_index=0; link_index<link_ids.length; link_index++) {
$("#" + link_ids[link_index]).click(function() {
alert(link_ids[i]);
});
}
}
});
}
Obviously I'd like to do something else than just alert the value, but the alert-call is there as long as I can get that working and move forward.
I understand that I'll have to make some kind of handler-function to which I pass a state-variable. This works for a single value (I can store the whole link_ids array just fine, but then I don't know which of them is the right value for this link), but how would I do this for arbitrary-length lists?
Here is an example from JQuery docs which I'm trying to copy:
// get some data
var foobar = ...;
// specify handler, it needs data as a paramter
function handler(data) {
//...
}
// add click handler and pass foobar!
$('a').click(function(){
handler(foobar);
});
// if you need the context of the original handler, use apply:
$('a').click(function(){
handler.apply(this, [foobar]);
});
And I quess the last example here, "if you need the context of the original handler..." would probably be what I want but I don't know exactly how to get there. I tried to store the current link_id value into this, use it from this in the applied function (using apply()) but I didn't succeed. The necessary values were still undefined according to FireFox. I'm using JQuery 1.3.2.
So what's the right solution for this relatively basic problem?
Use append instead of html():
function loadFooList() {
var ul = $('<ul>');
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
$.each(json, function(i, item) {
var link_id = "choosesfoo" + item.id;
var a = $('<a>').attr('href','#').bind('click', function(e) {
alert(link_id,item_name);
e.preventDefault();
});
$('<li>').append(a).appendTo(ul);
});
ul.appendTo('#sidebar'); // this is where the DOM injection happens
}
});
}
So the problem appears to be getting the link id associated with the link so that your click handler has access to it. Note that if it's alphanumeric it will qualify for the id attribute and you can extract it from there. If it is purely numeric, it will be an illegal id attribute. In that case, you can either use an attribute, like rel, or the jQuery.data() method to store the link id with the link. You can also simplify by using append. I'll show both examples.
var link = $("<li><a href='#' id='" + link_id + "'>" + item.name + "</a></li>";
link.click( function() {
alert( $(this).attr('id') );
});
list_area.append(link);
or (if numeric)
var link = $("<li><a href='#'>" + item.name + "</a></li>";
link.data('identifier', link_id )
.click( function() {
alert( $(this).data('identifier') );
});
list_area.append(link);
Try this:
function loadFooList() {
var list_area = $("#sidebar");
$.ajax({
type: 'GET',
url:'/data/foo/list',
dataType: 'json',
success: function (json) {
var out = '<ul>';
$.each(json, function(i, item) {
var link_id = "choosefoo" + item.id;
out +="<li><a href='#' id='" + link_id + "'>"+item.name+"</a></li>";
});
out +="</ul>"
var $out = $(out);
$out.find('a').click(function(){
var link_id = this.id;
var item_name = $(this).text();
alert(link_id);
alert(link_name);
})
list_area.html($out);
}
});
}
Using multiple appends causing the browser to redraw multiple times in a row. You only want to modify the dom once.

Categories

Resources