Collect data from page format.json.
In JS I have:
$('input[name="q"]').autoComplete({
source: function(term, response){
$.getJSON('/search.json', { q: term }, function(data){ response(data); });
}
});
For autocomplete I use this plugin.
What is responsible for the output?
I have in the autocomplete drop all the names. To fall out only need to apply. it is necessary to drop only those which coincide.
Is responsible for it .indexOf(term)? what to use?
The screen shows all the results (which have match and those who do not have a match). Need to see only those that have a match.
Being you're getting the data from a JSON file you'll have to do the filtering on the client side. The way that it would work with an actual AJAX request to a server, you'd do the filtering on the server to only return the data you need (that's why you send the query term as a parameter).
So you will need to change your code to look like this:
$('input[name="q"]').autoComplete({
source: function (term, response) {
$.getJSON('/search.json', function (data) {
term = term.toLowerCase();
var matches = [];
for (i = 0; i < data.length; i++)
if (~data[i].toLowerCase().indexOf(term)) matches.push(data[i]);
response(matches);
});
}
});
You may need to do something different depending on what your data structure looks like but I'm assuming it's an array of strings
EDIT
If you want to limit your matches you can do it in the for loop rather than in the last line, this will be better for performance as it won't have to loop around once you've got 5 matches
$('input[name="q"]').autoComplete({
source: function (term, response) {
$.getJSON('/search.json', function (data) {
term = term.toLowerCase();
var matches = [];
for (i = 0; i < data.length; i++)
if (~data[i].toLowerCase().indexOf(term) && matches.length == 4) {
matches.push(data[i]);
break;
}
response(matches);
});
}
});
Related
I am a beginner in Javascript and AngularJS and am trying to do the below:
There is a service that takes a list as URLs as input and find their respective data in a local cache/repository custom service.
If all are found, they are returned.
If some are missing, the missing ones are fetched by making ASYNC calls to the API. They are also stored into the repository for future availability.
All received data are concatenated into a local "data" variable and sent as a single array of objects to the controller.
It is looping through each URL using $.map to fetch data and concat it to the local "data" variable. Once the loop is complete, it is returning the "data" variable.
I am aware that this is not going to work and also the reason for it. But, am not able to figure out how to achieve this using an ASYNC design pattern.
myService.factory("dataManagerService",["dataRepositoryService","dataFetchService",
function(dataRepositoryService,dataFetchService)
{
var methodObj = {};
methodObj.getObjData = function(urlList)
{
//URLs are used to fetch data from API and also to uniquely identify the fetched data.
//urlList is a list/array of URLs for which data is required.
//Get all objects from data repository which are specified in the URL list.
var data = dataRepositoryService.getData(urlList);
//If repository did not have all objects specified from the URL list, fetch the missed objects.
if (data.length < urlList.length)
{
//Get list of URL for which data was received from repository.
var excludeURLList = $.map(data,
function(obj)
{
return obj.url;
}
);
//Get list of all URLs from urlList that are missing from excludeURLList
var fetchUrlList = $.grep(urlList,
function(url)
{
return excludeURLList.indexOf(url) < 0;
}
);
//Loop through all URLs in fetchUrlList (for which data was not found in the repository)
$.map(fetchUrlList,
function(url)
{
//Make a GET request to the API
dataFetchService.fetchData(url)
.then(
function(response)
{
//Add the received response to the repository, so that its available the next time.
dataRepositoryService.setData(response.data);
//Append missing data to "data" variable
data.concat(response.data);
}
);
}
);
}
return data; /* This will be incomplete since it will be returned before all the async calls have been completed. */
}
return methodObj;
}
]);
You're going to want to use $q.all() to retrieve all of the URLS. Here's a pretty good article on this: https://www.martin-brennan.com/using-q-all-to-resolve-multiple-promises/
You're going to want to do something like this:
getObjectList(urlList) {
var promises =[]
urlList.map( function(url) { promise.push(getUrl(url) } )
$q.all(promises).then( function(responses) { assemble what you want to return here}
)
}
function getUrl(url) {
var q=$q.defer()
if (whereever you've stored the data has fetched the url already) {
return $q.when(the data)
} else {
return $http.get(url).then( function(response) {
return $q.resolve(response.data)
}, function (error) { return $q.reject(error) })
}
}
Archive.org json doc: http://archive.org/help/json.php
I am using this url: https://archive.org/metadata/AhmedAlajmiTheCompleteHolyQuran
The json format is displayed in this order
036.mp3
016.mp3
However the actual order on the details page is
001.mp3
002.mp3
The details page: https://archive.org/details/AhmedAlajmiTheCompleteHolyQuran
How can i get the uploaders sorted order that is displayed in the details page. How come the json is sorted in a different format. I can sort the urls based on the numbers, but the file name will not always be by numbers.
This is what i have so far. It just gets the mp3 urls. BUT THE ORDER IS WRONG!
var urlJ = "https://archive.org/metadata/AhmedAlajmiTheCompleteHolyQuran";
function functionName() {
var url = "https://archive.org/metadata/AhmedAlajmiTheCompleteHolyQuran";
var details = "https://archive.org/download/AhmedAlajmiTheCompleteHolyQuran";
function jsonpCallback(response) {
//after success some staff
var files = response.files;
for(var i=0; i < files.length; i++){
if(files[i].source == "original"){
console.log(details + "/" + files[i].name);
}
}
console.log(response.files[0]);
}
$.ajax({
url: url,
dataType: 'jsonp',
error: function(xhr, status, error) {
alert(error.message);
},
success: jsonpCallback
});
return false;
}
functionName();
There's no way to sort it with the API provided, however the metadata provides one piece of data you can use to sort it yourself.
mtime - Unix-style timestamp of file
Therefore, you can just sort it with JavaScript (put this right after you pull response.files):
var files = response.files;
for (var i = files.length - 1; i >= 0; i--)
if (typeof files[i].mtime === 'undefined')
files.splice(i, 1);
files.sort(function(a, b) {
return a.mtime - b.mtime;
});
Also, if you're only pulling the files, you can just request only the files with:
https://archive.org/metadata/AhmedAlajmiTheCompleteHolyQuran/files
When I run the code:
Instead of request each module per line of code, I'm saving all the modules' string page in an array of modules,
var modules = ['mod1.html','mod2.html', ... , 'modN.html'];
and then pass to a function that suppose to put all the loaded modules into the modules-panel div at once.
function loadModules(modules, callback){
var content = [];
for(var i = 0; i < modules.length; i++){
$('#modules-panel').load(modules[i],function(){
content.push($('#modules-panel').html());
});
}
callback();
}
The issue is that only the last module appears where it should be.
The function should save the loaded module ( page ) into a stack repeatedly and then append all the modules in the page at once.
Given that you want to get the HTML from these pages, it would be better to use $.ajax directly and then read the response from that instead of repetedly filling an extraneous element.
Also, your callback() logic is flawed. You need to call that once all the AJAX requests have completed. For that you can use $.done. Try this:
function loadModules(modules, callback){
var content = [], requests = [];
for(var i = 0; i < modules.length; i++){
requests.push($.ajax({
url: modules[i],
success: function(html) {
content.push($('#modules-panel').html());
}
}));
}
$.when.apply($, requests).done(callback);
}
It should be noted that this may not be the best pattern to use as it will mean your server may be deluged with requests. If you can, I would look in to using server-side includes instead.
This is the place where the loadModules function is called:
var modules = ['loadfile.html', 'getFBinfo.html'];
loadModules(modules, function(data){
var total = '';
for(var i = 0; i < data.length; i++){
total += data[i];
}
$('#modules-panel').html(total);
});
Thanks for clarifying the issue! However the answer I've got was pretty simple!
I've taken the suggestion about ajax. The function became this:
function loadModules(modules, callback){
var content = [];
for(var i = 0; i < modules.length; i++){
$.ajax({
url: modules[i],
success: function(html) {
content.push(html);
if(content.length == modules.length){
callback(content);
}
}
});
}
}
As can be seen, I could return the callback function by comparing the length between what is passed to the function and the total possible/real length (the modules' length).
The problem now is to know what happens if the ajax request gets an error from the server.
I have a list of names in a text file
example:
user1 = Edwin Test //first line of text file
user2 = Test Edwin //second line of text file
I would like each lines data to be set to a variable:
user1 and user2 //so that after jquery loads I can user $user1 and it will give Edwin Test
Text file will be in the same folder as jquery file.
My code:
$.get('users.txt', function(data) {
alert(data);
var lines = data.split("\n");
$.each(lines, function() {
var line=perLine[i].split(' ');
});
});
When i load the page using mamp locally, I am able to see the contents on the file using the alert but when i type for example (user1) in the console it says that the variable is not set.
Here's what I think you want:
$.get('users.txt', function(data) {
var lines = data.split("\n");
$.each(lines, function(i) {
var line = lines[i].split(' = ');
window[line[0]] = line[1];
});
});
later on...
console.log(user1); // "Edwin Test"
var users = {};
var lines = data.split("\n");
$.each(lines, function (key, value) {
var prep = value.split(" = ");
users[prep[0]] = prep[1];
});
To output user1 You would call users.user1
JSFiddle
The code adds lots of variables to the global namespace. Also, it invites bugs because $.get is asynchronous and so code that depends on the variables existing needs to be called where shown in the comment to be guaranteed to work. This would be considered bad style by many, but here's how to do it:
$.get('users.txt', function(data) {
alert(data);
var lines = data.split("\n");
var i,l=lines.length,parts;
for(i=0;i<l;++i){
parts = lines[i].split('=');
if (parts.length == 2){
try {
// window is the global object. window['x']=y sets x as a global
window['$'+parts[0]] = parts[1]; // call the var $something
} catch(e) {}; // fail silently when parts are malformed
}
// put any code that relies on the variables existing HERE
}
});
Here's what you might do instead:
Put the data in an object. Pass the object to a function showVars(vars) that contains the next step.
$.get('users.txt', function(data) {
alert(data);
var lines = data.split("\n");
var i,l=lines.length,parts, vars = {};
for(i=0;i<l;++i){
parts = lines[i].split('=');
if (parts.length == 2){
try {
vars[parts[0]] = parts[1];
} catch(e) {}; // fail silently when parts are malformed
}
showVars(vars); // put any code that relies on the variables existing HERE
}
});
function showVars(vars){
// put whatever uses/displays the vars here
}
Yet another way to make this easier to change the data format. If you can store the data in this format, called JSON:
['Edwin Test','Test Edwin','Someone Else','Bug Tester']
Then the parser is either a one liner array = JSON.parse(jsonString) or sometimes is done for you by jQuery and put in data. JSON can store all kinds of data, and there is support for it in other languages libraries besides Javascript, such as PHP, python, perl, java, etc.
$.get('users.txt', function(data) {
alert(data);
var lines = data.split("\n");
for(var i = 0 ; i < lines.length; i++){
var line=lines[i].split(' ');
});
});
I think you are missing the i in the loop.
I guess you could also do
$.each(lines, function(i) {
var line=lines[i].split(' ');
});
In any event, I would probably recommend that you do this string splitting on the server instead and deliver it to the client in the correct/ready form.
Hi everyone i'm trying to display some random images while not loading (refresh) page
So how can i display random images on a page without refreshing the page ?
<script type="text/javascript">
$(function () {
$.ajax({
type: "get", url: "Home/Oku", data: {}, dataType: "json",
success: function (data) {
for (var i = 0; i < data.length; i++) {
var newFirmDiv= $(' <img src="../../banner_image/' + data[i] + '" width="154px" height="108px"/>');
$(".firmShowCase").append(newFirmDiv);
}
}
});
});
</script>
Here is my action method that provides return values an array
public ActionResult Oku()
{
var query = from table in db.news select table.news_image_name;
return Json(query, JsonRequestBehavior.AllowGet);
}
Here is result as you can see below
2nd Try:
function for min and max
(http://www.naden.de/blog/zufallszahlen-in-javascript-mit-mathrandom)
function getRandom(min, max) {
if(min > max) {
return -1;
}
if(min == max) {
return min;
}
var r;
do {
r = Math.random();
}
while(r == 1.0);
return min + parseInt(r * (max-min+1));
}
And Your Code
for (var i = 0; i < data.length; i++) {
randomIndex = getRandom(0, data.length-1);
var newFirmDiv= $(' <img src="../../banner_image/' + data[randomIndex] + '"width="154px" height="108px"/>');
$(".firmShowCase").append(newFirmDiv);
}
If you want to keep the random order...
...you have to save it like in a new array, afterwards you could save it via ajax in a database or a temp file. And the top of your current file you would have to check if there is an existing temp file; if it shall be bound to a user, you could generate a random key (like with time) save it in a session variable and name the tmp file or the data in the database with the same random key... so far my ideas, if it's that what you are looking for. Of cause it would be easier to do this on the server side right from the start.
First Answer:
(The question was not really clear - if something does not work and so on...)
First of all data is not returned as an array, but an object. But i think you do not understand the parameters of the ajax function very well.
In the url parameter should be the script (for example getImages.php) which shall be executed. So there you should collect the images, parse them to jason and print them, in that way it will be returned as data.
In the parameter data you can pass some params to the skript, which you can get by decoding them in php.
I just chose PHP for example.
If I am wrong and "Home/Oku" leads to some script you might show us what it does?