I'm trying to add entries to a dropdown list which I have defined in my .jade file as below.
extends layout
block content
script(src='http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js')
script(src='/javascripts/addsystem.js')
h1= title
p Testing
select#allSystems
And my Ajax method looks like the following:
var select = $('#allSystems');
console.log("Runing script")
$.ajax({
url: '/submit/getAllSystems',
dataType:'JSON',
success:function(data){
$.each(test.system, function(key, val) {
select.append('<option id="' + val.id + '">' + val.name + '</option>');
})
}
});
The Ajax script is located the JS file which is included in the Jade file. (Jquery is also included in the Jade file).
Everything seems to be working fine, except for the append. I.e. the console logs show good data all the way and when printing the select object in the Ajax script the browser recognizes it as a HTML element.
When printing the running "console.log(select);", Firefox console shows the following:
Object { context: HTMLDocument → submit, selector: "#allSystems" }
Any idea what I'm doing wrong?
Jade is a templating language that has to be compiled and executed with the data in order to render HTML. JQuery will not automatically do that for you, which is why your commented-out attempt at select.append failed.
Building the HTML yourself works (though it makes some ugly code and I still dislike string concatenations). However, when you did that you changed to .appendTo, which is going to try and take your select object and append it to the option, which I don't think is what you want.
give this a shot:
select.append('<option id="' + val.id + '">' + val.name + '</option>');
If that doesn't work, then there's something up with your selector that gets you the select variable.
* EDIT *
I notice in your Jade that you are loading your scripts before the rest of the DOM. IF the contents of addsystem.js are as you describe, then you're fetching the data and trying to append it to a DOM node that doesn't exist yet. Try wrapping it like so:
$(function(){ /** your code **/ })
Which is a shorthands to jQuery's methods for doing stuff after the DOM is fully loaded.
Related
I have taken some source code from here to submit a form using AJAX. The form is basically taking some information from a user and putting it into a database via PHP. The code I have works, but given that what I am working on has many forms all doing the same thing, I - obviously - want to make sure my code is lean and mean. So, making sure that each of my form field names have the same as my database with some matching IDs for various parts of the form for user feedback, have changed it to the following:
<script type="text/javascript">
$(document).ready(function() {
// process the form
$('#formId').submit(function(event) { // for the specified form:
// completeForm('#formId'); // WHERE I CALL THE FUNCTION
// FUNCTION STARTS HERE WHEN IT IS ONE
var formData = {}; formId = '#formId';
$(formId + ' input, ' + formId + ' select, ' + formId + ' textarea').each(
function(index){ // for each item (input, select, textarea in the specified form
var input = $(this);
// First, clear any existing formatting that has been added by previous form inputs
$('#' + input.attr('id') + '-group').removeClass('has-info has-error has-success bg-error bg-info bg-success');
// Next, add data to the array of data to pass to the PHP script
Array.prototype.push.call(formData, input.val());
}
); // End of loop through each item.
// Now the data is collected, call the requested PHP script via AJAX.
$.ajax({
type : 'POST', // define the type of HTTP verb we want to use (POST for our form)
url : $(this).attr('action'), // '/processing/general_settings_processing.php', // the url where we want to POST
data : formData, // our data object
dataType : 'html' // 'json' // what type of data do we expect back from the server
})
// using the done promise callback
.done(function(data) {
// log data to the console so we can see
console.log(data);
// Return success and error messages to the user
// Code to come once the basics have been sorted out!
});
// FUNCTION WOULD END HERE WHEN IT IS ONE.
event.preventDefault();
});
});
</script>
The code as above works absolutely fine; the relevant PHP file is called and - although I have no processing done in this particular file yet - does its stuff (I have it echoing the $_POST array to a file and returning to view in the console log atm).
However, when I try and make it a function, it doesn't - the console log simply echoes out the source code for this document instead of the PHP array that it supposed to be doing. The function is placed above the $(document).ready line; specified as function completeForm(formID) { . . . } , contains the section of code as noted in the comments and called in the commented out line as shown. So, logically (to me) it should work.
The ultimate idea is to have the function to do this in a file that can be called by all the forms that call it, while the code to call the function is in the relevant part of the page. Some pages will have more than one form using it. (I mention that should even if what I am doing here works, it wouldn't when I come to reuse the code!)
(I'm relatively new to JS and JQuery, although have a fairly good grasp of some programming techniques, mainly these days just in PHP.)
The issue you are having with making that a function is you forget to include the "thisBinding". As a result, when you tried to use the form's action target in your ajax call with this code:
url : $(this).attr('action')
it does not find an "action" attribute - basically the issue is that this is actually window and as a result there is no action attribute. Simply bind this to your function call and your code will work as written.
completeForm.call(this,'#formId');
.call MDN
I am currently working on a Spring mvc project in which I am using the jQuery autocomplete plugin to load data from a JSON file rendered from the server.
$('#searchTerm').autocomplete({
serviceUrl: '${ctx}/search/searchAutocomplete',
paramName: "parameterName",
delimiter: ",",
transformResult: function(response) {
return {
suggestions: $.map($.parseJSON(response), function(item) {
return {
value: item.userName + " , " + item.userId + ", " +
item.pathToImageFile , data: item
};
})
};
},
onSelect: function (suggestion) {
$(this).val(suggestion.data.userName);
console.log(suggestion.data.userId);
console.log(suggestion.data.pathToImageFile);
window.location.href = "${ctx}/userPage?
userID="+suggestion.data.userId;
}
});
This code works as expected. I am able to show the data of the suggestions in the suggestions list, and I am able to redirect to another page when selecting the item.
My inquiry is, how do I use the data from item.pathToImageFile to generate an image of a profile picture whithin the suggestions list? Similar to how facebook shows the profile pictures of users or groups when you search.
I went over the following similar topics here:
jQuery UI - Formatting the autocomplete results. Add image possible?
Jquery UI autocomplete - images IN the results overlay, not outside like the demo
How to change rendering of dropdown in jquery ui autocomplete attached to a class?
However I can't seem to apply the accepted answers in my code. In plain html and javascript, I know the syntax for each suggestion item should look something like this:
'<img src="'+ suggestion.data.pathToImageFile + '"/>'
'<p>' +suggestion.data.userName + '</p>'
I just can't seem to figure out the configurations and built in methods of the autocomplete plugin. The documentation does not help at all. Hope someone can help me out. Thanks
You need to add .data("ui-autocomplete")._renderItem = function (ul, item) {
in my AJAX response the item.label already contains the needed HTML code with the correct format (I don't use images, but other formatting)
$('#searchTerm').autocomplete({
serviceUrl: '${ctx}/search/searchAutocomplete',
paramName: "parameterName",
delimiter: ","
/* This is the part to be implemennted */
}).data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "</a>")
.appendTo(ul);
};
You need to adjust the code and your AJAX response, but I think you can take it from here...
I can't help with the jquery.autocomplete plugin, but if you can't get it to work the Select2 plugin features this functionality and it is well documented on their examples page on github here (look in the "Data Sources -> Loading remote data", section).
Perhaps you might get some insight/inspiration from there? Hope that's helpful!
I have a database, analysis.php and index.php webpages. The analysis.php gets the data from the database, sorts it in a required pattern, and then echoes the json_encode($array); into a div with the id 'data'. I am trying to get that JSON Data and parse it in the index.php page.
However I am getting an error. SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
I am trying to get this data everytime the user selects an option from a select box.
My jQuery code is:
$(document.body).on('change', '.select' , function () {
var identification = $(this).val();
var JSONText = $(this).closest('div[id|="module"]').find('p[id="JSON"]');
JSONText.load('analysis.php?data=' + identification + ' #data');
console.log("JSON Imported: '" + identification + "'");
var obj = jQuery.parseJSON(JSONText.text());
console.log(JSONText.text());
});
EDIT: As you can see I have the snippet console.log(JSON.text());. The output of the JSON that I get is correct. The only issue I think might be is that the quotes are all " instead of the JSON quotes being different from the outer quotes.
jQuery.load is asynchronous, you're trying to parse the JSON before its actually loaded. Using jQuery.getJSON loads the content, does the parsing and provides a callback you can bind to.
jQuery.load loads the content as HTML and sets the innerHTML of the selected element, you could bind the complete handler here aswell, but you may encounter issues by loading the content as HTML and then using text to retrieve it from the DOM as some parts of your JSON may be interpreted as HTML elements.
Better use this:
$(document.body).on('change', '.select' , function () {
var identification = $(this).val();
$.getJSON(
'analysis.php?data=' + identification + ' #data',
function (data) {
console.log(data);
}
);
});
In addition to LJ_1102's solution, here is a way to fix your current snippet:
JSONText.load('analysis.php?data=' + identification + ' #data', function() {
console.log("JSON Imported: '" + identification + "'");
var obj = jQuery.parseJSON(JSONText.text());
console.log(JSONText.text());
});
I have a fly out javascript menu that is initialized using the onload event. All of the data inside the menu right now is hard coded but needs to be dynamic and will come from my database. Is there a way to build this javascript file with my database values? Is this possible? I'm a total noob to JS so please spell things out for me.
Maybe an example of what I'm thinking will help. This is part of my JQuery file after I have my serialized array. How do I get the array into the menu from here?
if(data.success == 0) {
// error
} else {
// my array that needs to be exported into the JS file.
}
This is the other file that I'm talking about that needs to be built with the data from the database.
function create_menu()
{
document.write(
'<table cellpadding="0" cellspaceing="0" border="0" style="width:98%"><tr>' +
'<td class="td" valign="top">' +
'<h3>Test</h3>' +
'<ul>' +
'<li>afd</li>' +
'<li>fsg</li>' +
'<li>sfg</li>' +
'<li>fsg</li>' +
'</ul>' +
'</td></tr></table>');
}
One option would be to build the JavaScript file dynamically on the server when a request comes in from the browser using one of the various server-side scripting languages. The downside to this method is that that browsers may cache the file and, therefore, may operate with stale data.
The other option is to use a static JavaScript file and use an AJAX call to get the latest menu options and then render them into the page's DOM. This would be better than the first option since you wouldn't have the caching concerns.
The third method is to dynamically generate the markup for the page and not worry about requesting a menu via JavaScript. This is the best option in my book. I wouldn't want to wait for the navigational elements of a page to be requested via JavaScript when it's something simple that should already be part of the page.
You need to use AJAX.
You can load the contents from back-end into a JavaScript array and use that. This is how dynamic data is fetched from the server without a page refresh.
Hope this helps.
JSON is a data format which can be executed using eval(). Create some JSON which represents whatever format you've hard-coded and evaluate it like in Wikipedia's example
This is only okay if you trust the source of the JSON, in this case you're generating it yourself so it should be okay.
example, json_menu.php returns the text:
create_menu( { "menus" : ["afd", "fsg", "sfg", "fsg"] } );
And you execute it like this by evaluating it:
function create_menu(JSONData)
{
var s = '<table cellpadding="0" cellspaceing="0" border="0" style="width:98%"><tr>' +
'<td class="td" valign="top">'
// loop through each one
for(var menu in JSONData.menus)
s = s + '<li>' + menu + '</li>';
s = s + '</ul></td></tr></table>';
// write it out
document.write(s);
}
// this gets called somewhere in your OnLoad
function yourOnLoader()
{
var ajaxRequest = new ajaxObject('http://your-site.com/json_menu.php');
ajaxRequest.callback = function (responseText) { eval(responseText); }
ajaxRequest.update();
}
I know very little (none) JavaScript, or much about using API's. However I would like to display some hotel reviews on my webiste made available over the qype.com API. However I'm struggling with being able to manage this.
This is the code I have so far:
$(document).ready( function() {
$.getJSON( "http://api.yelp.com/business_review_search?term=hilton%20metropole&location=B26%203QJ&ywsid=APIKEY Removed",
function(data) {
$.each( data.businesses, function(i,businesses) {
content = '<p>' + businesses.reviews.text_excerpt + '</p>';
content = '<p>' + businesses.reviews.date + '</p>';
$(content).appendTo("#review");
} );
}
);
} );
I have a div in the body called review where I want to display the text.
Any advice greatly received.
JSON can be found at http://api.yelp.com/business_review_search?term=hilton%20metropole&location=B26%203QJ&ywsid=lOoGGbkYpVmTvxHlWGT2Lw
Also, I have multiple businesses on the same page, how would I make use of this multiple times on the same page, but output the data in different locations?
Update: Ah, I see your error now. businesses.reviews is an array (each business can have more than one review) so you have to loop over each business and each business' reviews.
i had to change some things to get it to run in my test bed, but you can see a sample of this code running here: http://bit.ly/4mTxPp
yelp currently support JSONP calls so you can change your code to:
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
function showData(data) {
$.each(data.businesses, function(i,business){
// extra loop
$.each(business.reviews, function(i,review){
var content = '<p>' + review.text_excerpt + '</p>';
content += '<p>' +review.date + '</p>';
$(content).appendTo('#review');
});
});
}
$(document).ready(function(){
// note the use of the "callback" parameter
writeScriptTag( "http://api.yelp.com/business_review_search?"+
"term=hilton%20metropole"+
"&location=B26%203QJ"+
"&ywsid=lOoGGbkYpVmTvxHlWGT2Lw"+
"&callback=showData"); // <- callback
});
function writeScriptTag(path) {
var fileref = document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", path);
document.body.appendChild(fileref);
}
</script>
Do you get an error in Firebug using this code? What happens exactly?
I expect this problem is caused by the fact that you're trying to do a cross-domain request which is not allowed. Normally you'll want to do this kind of data gathering on your back-end, but you can use an alternative such as JSONP to do the same.
Take a look at jQuery's documentation on this stuff and it should be clear what's going on.
Also, as a side note: In your callback you have content = which is ok but not ideal. Assigning to content like this will create a variable in the global scope which you do not want. In this case it probably wont cause an issue but say you have 2 of these requests going at once, the second assignment could easily step on the first causing hard-to-debug weirdness. Best to just always create variables with var.
If data.businesses is an array, I would assume that data.businesses[x].reviews is also an array. This code loops the businesses as well as the reviews for each business. It also gets rid of the content variable by appending straight to the #review div.
$.each(data.businesses, function(i,business){
$.each(business.reveiws, function(r,review){
$("#review").append(
'<p>' + review.text_excerpt + '</p>'
).append(
'<p>' + review.date + '</p>'
);
});
});
I think you can specify JSONP with your $.getJSON method by adding "callback=?" to the url parameters.
As of jQuery 1.2, you can load JSON
data located on another domain if you
specify a JSONP callback, which can be
done like so: "myurl?callback=?"
$.getJSON("http://api.yelp.com/business_review_search?term=hilton%20metropole&location=B26%203QJ&ywsid=APIKEY Removed&callback=?",
function(data){
...
});
The problem is that you are making a cross domain request, which is not allowed for security purposes. Either you will have to make a proxy script on your domain (like for example in php) and call yelp from that or fetch the data completely on the server side.
I assume you must be experiencing part of your data (which you are supposed to see) disappearing. I think you must edit your code to:
content = '<p>' + businesses.reviews.text_excerpt + '</p>';
content += '<p>' + businesses.reviews.date + '</p>';
Hope this helps...