It's possible to 'GET' multiple XML files with javascript? - json

I want to add data that's stored in XML Files to the HTML View with handlebars.js but,
Instead of make a GET of 1 url ex:http://json.org/example.html i will want to add multiple XML Files. I will aprreciate any help on this
Thanks in advance!
var ourRequest = new XMLHttpRequest();
ourRequest.open('GET', 'https://learnwebcode.github.io/json-example/pets-data.json');
ourRequest.onload = function() {
if (ourRequest.status >= 200 && ourRequest.status < 400) {
var data = JSON.parse(ourRequest.responseText);
createHTML(data);
} else {
console.log("We connected to the server, but it returned an error.");
}
};
ourRequest.onerror = function() {
console.log("Connection error");
};
ourRequest.send();
Handlebars.registerHelper("calculateAge", function(birthYear) {
var age = new Date().getFullYear() - birthYear;
if (age > 0) {
return age + " years old";
} else {
return "Less than a year old";
}
});
function createHTML(petsData) {
var rawTemplate = document.getElementById("petsTemplate").innerHTML;
var compiledTemplate = Handlebars.compile(rawTemplate);
var ourGeneratedHTML = compiledTemplate(petsData);
var petsContainer = document.getElementById("pets-container");
petsContainer.innerHTML = ourGeneratedHTML;
}
<div class="page-wrap">
<h1>Handlebars js</h1>
<div id="pets-container"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<script id="petsTemplate" type="text/x-handlebars-template">
{{#each pets}}
<div class="pet">
<div class="photo-column">
<img src="{{photo}}">
</div>
<div class="info-column">
<h2>{{name}} <span class="species">({{species}})</span></h2>
<p>Age: {{calculateAge birthYear}}</p>
{{#if favFoods}}
<h4 class="headline-bar">Favorite Foods</h4>
<ul class="favorite-foods">
{{#each favFoods}}
<li>{{{this}}}</li>
{{/each}}
</ul>
{{/if}}
</div>
</div>
{{/each}}
</script>

What you need is a single callback that gets executed only when all the data you need from your various requests has been fetched. To achieve this you will need some sort of synchronization between the various AJAX calls you're doing.
Promise pattern, the Q library, which is one of the several implementations of the pattern. They have done most of the hard work of synchronizing multiple AJAX requests for us.
I will post an example here:
function xmlPromise(name) {
return Q.promise(function (resolve, reject, notify) {
$.ajax({
type: "GET",
dataType: "xml",
async: true,
url: name,
contentType: "text/xml; charset=UTF-8"
})
.done(function (data) {
resolve(data);
}).fail(function () {
reject();
});
});
};
//your xml files can be stored in the promises variable
var promises = [ xmlPromise('your-xml-file-1.xml'), xmlPromise('your-xml-file-2.xml') ];
var results = [];
Q.allSettled(promises).then(function(responses) {
results.push(responses[0].value);
results.push(responses[1].value);
});
Hope it help

Related

Sorting with isotope from external json rendered with handlebars

Can't seem to get Isotope sort to work :(
On the client side of a webpage I'm displaying data which comes from an external json with a template using handlebars.js.
I want the users to be able to sort, filter and search the data that is displayed. I've seen that with Isotope can this be achieve successfully. I did manage to get filtering to work.
However I'm stuck with sorting in targeting the class of the object with the getSortData option which value comes from the json.
Example of the JSON structure with the price:
Here is the code trying to sort by price, first my menu:
<ul id="sort">
<li>original order</li>
<li>number</li>
</ul>
Then my handlebars template, where I want to reach the p.class = number:
<div id="mcContainer"></div>
<script id="mcTemplate" type="text/x-handlebars-template">
{{#each this}} {{#annoncer}}
<article class="mc_item {{category}} {{year}}">
<a data-single href="{{id}}">
<h3>{{brand}} {{model}}</h3>
<img src={{images.0.small}} />
<h4 class="mc_aar">ÅR: {{year}}, {{km}} km</h4>
<p>{{category}}</p>
<p class="mc_pris number">{{price}},-</p>
<hr>
</a>
</article>
{{/annoncer}} {{/each}}
</script>
And my javascript file:
(function ($) {
"use strict";
// javascript code here. i.e.: $(document).ready( function(){} );
$(document).ready(function ($) {
var $container = $('#mcContainer');
$.ajax({
url: "http://diegovega.dk/kea/2semester/json-eks/json-eks.json",
method: "GET",
dataType: 'json',
success: function (response) {
var template = $('#mcTemplate').html();
var renderer = Handlebars.compile(template);
var result = response;
$('#mcContainer').html(renderer(result));
runIsotope();
}
});
function runIsotope() {
var $items = $('.mc_item');
$items.isotope({})
$items.isotope('reloadItems')
.isotope({
itemSelector: '.mc_item',
layoutMode: 'fitRows',
fitRows: {
gutter: 20
},
getSortData: {
number: '.number parseInt'
},
});
// Sort based on price
$('#sort').on('click', function () {
if ($(this).hasClass('checked')) {
$(this).removeClass('checked');
.isotope({
sortBy: 'original-order'
});
} else {
$('#sort').removeClass('checked');
var sortValue = $(this).attr('data-sort-value');
console.log($(this).attr('data-sort-value'));
.isotope({
sortBy: sortValue
});
$(this).addClass('checked');
}
});
} //RUN ISOTOPE
}); // END DOCUMENT READY
})(jQuery); // END use strict
Any help is greatly appreciated :)
Initialize Isotope on the container, not the items
Use data-sort attribute on the links click

Cannot GET the requested API in express.js

Here is my express app code
app.get('/books',function(req,res){
var {keyword} =req.query;
connection.query('SELECT * from books', function (error, results, fields) {
if (error) throw error;
for(let result of results){
if(result.title === keyword){
res.send(result);
}
}
});
});
and the url i am requesting is http://......../books/keyword=intro. Where intro is the user input.
What i am trying to achieve here, is from an input in HTML, to take that info and send it to my API, so it can query my DB and get what i want.
But i get a 404 error, so i guess my api is configured incorrectly.
Is there a better way to implement what i am doing?
Is the keyword=intro even the correct way to query my db.
My html is like this
<!DOCTYPE html>
</head>
<body>
<div id="data">
<input type="button" id="button" value="Click"/>
<input type="text" id="search" >
</div>
<div id="search">
</div>
<script>
document.getElementById('button').addEventListener('click',getUserInput);
function getUserInput(event){
var userInput = document.getElementById("search").value;
if(userInput !== ""){
httpGetAsync(userInput);
}
}
function httpGetAsync(searchTerm){
var theUrl = 'books?keyword=' + searchTerm;
const xhttp = new XMLHttpRequest();
xhttp.open("GET", theUrl, true); // true for asynchronous
xhttp.send(null);
xhttp.onreadystatechange = processRequest;
function processRequest() {
if (xhttp.readyState == XMLHttpRequest.DONE);
var result = JSON.parse(xhttp.response);
console.log(result);
}}
</script>
</body>
In httpGetAsync function replace
var theUrl = 'books/keyword=' + searchTerm;
with:
var theUrl = window.location + '/books/keyword=' + searchTerm;
This answer is more of a comment unless it's acceptable. The statement that I want to write is too long for a comment.
In regards to my answer is that a valid way to write your prepared statement model? How I write my SQL models are like this and it works fine. Are you receiving any errors from your SQL syntax?
Notice the brackets after the ?.
selectBooks: function(data, callback) {
let keyword = "%" + req.query + "%";
connection.query("SELECT * FROM books WHERE title LIKE ?", [keyword], callback);
}

WinJS "forEach" Undefined

am working on windows app(winjs) with navigation template, all am trying to do is when i open the app at the home.html page list of applicants/candidates should be loaded. here is my code i was working on. but it throes me with forEach is undefined
(function () {
"use strict";
WinJS.UI.Pages.define("/pages/startpage/startpage.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
// TODO: Initialize the page here.
var titlesListGrouped = new WinJS.Binding.List().createGrouped(
function (i) { return i.ApplicantName.charAt(0).toUpperCase(); },
function (i) { return { firstLetter: i.ApplicantName.charAt(0).toUpperCase() }; }
);
var list = q("#ApplicantListView").winControl;
list.itemDataSource = titlesListGrouped.dataSource;
list.itemTemplate = q("#ApplicantTemplate");
list.groupDataSource = titlesListGrouped.groups.dataSource;
list.groupHeaderTemplate = q("#headertemplate");
WinJS.xhr({ url: "http://localhost/applicants/processing/getapplicant.php", })
.then(function (xhr) {
var applicants = JSON.parse(xhr.response).d;
applicants.forEach(function (i) {
var item = {
ApplicantId: i.ApplicantId,
ApplicantName: i.ApplicantName,
clickFunction: function (args) { WinJS.Navigation.navigate("/pages/details/details.html", item); }
};
item.clickFunction.supportedForProcessing = true;
titlesListGrouped.push(item);
});
});
},
unload: function () {
// TODO: Respond to navigations away from this page.
},
updateLayout: function (element) {
/// <param name="element" domElement="true" />
// TODO: Respond to changes in layout.
}
});}
and the html code
<section class="page-section" aria-label="Main content" role="main">
<div id="headerTemplate" data-win-control="WinJS.Binding.Template">
<div>
<p data-win-bind="innerText:firstLetter"></p>
</div>
</div>
<div id="ApplicantTemplate" data-win-control="WinJS.Binding.Template">
<div data-win-bind="onclick:clickFunction">
<div class="appId" data-win-bind="innerText:ApplicantId"></div><br />
<div class="appName" data-win-bind="innerText:ApplicantName"></div>
</div>
</div>
<div id="ApplicantListView"
data-win-control="WinJS.UI.ListView"></div>
</section>
and this is my php which generates json data
<?php
header('Allow-Control-Allow-Origin:*');
$database = mysqli_connect('localhost','root','','tech_m');
$query = "SELECT * from `applicant_table`";
$rs = mysqli_query($database, $query);
while($assoc = mysqli_fetch_assoc($rs)){
//echo "Access Granted";
$ApplicantId = $assoc['app_id'];
$ApplicantName = $assoc['app_name'];
$rows[] = array('ApplicantId' =>$ApplicantId ,'ApplicantName' =>$ApplicantName );
}
$response['rows'] = $rows;
$encodedfile = json_encode($response);
echo $encodedfile; ?>
please if anyone could help on this, it would be a great help.
here is my code i was working on. but it throws me with forEach is undefined.
From your php codes, you return a Json object: $response['rows'] = $rows;.
So the JSON object has a property rows, which is an array. But in your JS codes,
you retrieve the arrary using JSON.parse(xhr.response).d, in which the d property didn't exist.
To fix the problem, you can simply modify var applicants=JSON.parse(xhr.response).d; to below codes:
var applicants = JSON.parse(xhr.response).rows;
I checked the link you posted. It didn't talk about the how the dataSource look like. So I think JSON.parse(xhr.response).d is a data array in that blog.

Hello how to upload an image using angularjs+mysql+node.js

How to upload the image in angularjs and mysql and node.js?
<html>
<head>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app = "myApp">
<div ng-controller = "myCtrl">
<input type = "file" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
</div>
<script>
var myApp = angular.module('myApp', []);
myApp.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "/fileUpload";
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
</script>
</body>
</html>
AngularJs is a client side language. so it is not able to direct save data to MySql.
If any data is store in a database or in a server you must used any server side language.
You are create a web service that can tack response from client side (AngularJS) and send proper response.
File Upload in Mysql using NodeJs
fs.open(temp_path, 'r', function (status, fd) {
if (status) {
console.log(status.message);
return;
}
var buffer = new Buffer(getFilesizeInBytes(temp_path));
fs.read(fd, buffer, 0, 100, 0, function (err, num) {
var query = "INSERT INTO `files` SET ?",
values = {
file_type: 'img',
file_size: buffer.length,
file: buffer
};
mySQLconnection.query(query, values, function (er, da) {
if (er)throw er;
});
});
});
function getFilesizeInBytes(filename) {
var stats = fs.statSync(filename)
var fileSizeInBytes = stats["size"]
return fileSizeInBytes
}

Backbone using external js

Hi all I have a site developed in cakephp and I would to integrate backbone on it.
For my scope I would to use external js for backbone to reuse the code.
I have write some lines but I can't append results on my element.
I have tried to print the "el" in this modes:
console.log($(this.el));
console.log(this.el);
console.log(this.$el);
But nothing I can't enter into el to make a simple append!
The container #search-results already exist
This is my main view:
<script type="text/javascript">
var search = {};
search.product = {};
search.product.template = "#results-product-template";
search.product.container = "#search-results";
search.product.defaults = {
id:0,
type:"product",
};
$(function(){
var ProductList = new Search.Collections.Products();
var ProductView = new Search.Views.Product({
// new Search.Collections.Products();
collection:ProductList
,el:$("#search-results")
});
function parseResults () {
var json = {
//my data
}
for (var i = json.products.length - 1; i >= 0; i--) {
ProductList.add([new Search.Models.Product(json.products[i])]);
};
updateResults();
}
function updateResults () {
console.log('updateResults: Ritorno il risultato quando hunter riceve una risposta dal server');
if ($('#search-results').length == 0) {
$('div.main > section:first-child').before('<section id="search-results"> <ul id="product-results"> <li>Contenuto</li> </ul> </section>');
}
ProductView.render();
}
// search
$('#search-results .close').on('click', function () {
$('#search-results').animate({height:0}, 500, function () {
$(this).remove();
})
});
});
</script>
And this is my external js with backbone
var Search = {
Models: {},
Collections: {},
Views: {},
Templates:{}
}
Search.Models.Product = Backbone.Model.extend({
defaults: search.product.defaults || {},
toUrl:function (url) {
return url.replace(" ", "-").toLowerCase();
},
initialize:function () {
console.log("initialize Search.Models.Product");
this.on("change", function (){
console.log("chiamato evento change del Model Search.Models.Product");
});
this.on("change:text", function () {
console.log("chiamato evento change:text del Model Search.Models.Product");
});
}
});
Search.Collections.Products = Backbone.Collection.extend({
model: Search.Models.Product,
initialize:function () {
console.log("initialize Search.Collections.Products");
console.log(this);
console.log(this.length);
console.log(this.models);
}
});
Search.Views.Product = Backbone.View.extend({
initialize:function () {
console.log("initialize Search.Views.Product");
console.log($(search.product.template).html());
},
template:function (data) {
if (data == null) {
data = this.collection.toJSON();
}
var template = Handlebars.compile($(search.product.template).html());
template(data);
},
render:function () {
console.log($(this.el));
$(this.el.append("TEST"));
//HERE IS THE PROBLEM
// I have tried this.$el.append("TEST");
return this;
}
});
Does this change anything?
var ProductView = new Search.Views.Product({
// new Search.Collections.Products();
collection:ProductList,
el:$("#search-results")[0]
});
I think backbone can accept both jQuery wrapped or not wrapped object and be fine, but I don't know what Backbone version you are using, see if this works
EDIT: From backbone 1.0 sources, it seems backbone can indeed take either a jQuery wrapped object or a regular dom element, it should still work
this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
Do you have something online (JSFiddle?) I will be happy to take a look, but this.$el should work and be equal to $("#search-results") from your code in a quick glance.
Have you tried using ProductView.setElement($("#search-results")) instead? it should be the same, but worth a try as well.