I am trying to import data from mongodb into jade template, in order to show them in graph. I am using chart.js inline script, in order to render data on graph. So data from Mongodb is on the page, and I can access it like this:
each city in cities
p #{city.name}
And here is how I pass data to page:
exports.index = function(req,res){
var cities = City.find({}).limit(20);
cities.exec(function(err,doc) {
res.render("index",{cities:doc});
});
};
I created same app with php, by simply passing data to page and injecting data into javascript graph(with json_encode)
Here is final result with php:
It was easy, since php data are global to HTML page. How to do that with Jade ?
Thanks
Ah, so your goal is to both use the city data to generate HTML on the server but ALSO make it available in the browser as raw javascript object data. To do that you format it as JSON and stuff it into a <script> tag. There are modules to help with this such as sharify,
but the basic idea in your jade template do something like:
In your express route handler javascript:
exports.index = function(req,res){
var cities = City.find({}).limit(20);
cities.exec(function(err,doc) {
//There are tricky rules about safely embedding JSON within HTML
//see http://stackoverflow.com/a/4180424/266795
var encodedCityData = 'window.cities = ' + JSON.stringify(cities)
.replace(/</g, '\\u003c')
.replace(/-->/g, '--\\>');
res.render("index",{cities:doc, encodedCityData: encodedCityData});
});
};
In your jade template:
script!= encodedCityData
In the browser, you will have access to the data via the cities variable which has been set onto the window object.
Related
I'm looking for some sample code using the AEM JCR_SQL2 API in server-side Javascript (NOT Java), i.e. code that starts with use(function() { ... }) and is loaded via data-sly-use=${...}.
All Google results are 100% Java based examples.
What I've already tried: Google "JCR-SQL2 js example" and variations.
Expected result: sample code in Javascript.
Actual result: lots of Java code :-(
If you wanna use server-side JS (what I don't recommend), then you only have to convert the syntax of the Java examples. You interact with the Java-Objects anyway. So the API is the same for JS as for Java. In case you have a HTL component and calling the JS via the Use-API, then several objects are already defined in your JS scope.
https://helpx.adobe.com/experience-manager/htl/using/global-objects.html
Here is an JS example to search all core components with a SQL-2 query:
use(function () {
var pageName = currentPage.name;
var title = currentPage.properties.get("jcr:title");
var resourceName = granite.resource.name;
var resourceTitle = properties.get("jcr:title");
var componentList = [];
var componentIter = resolver.findResources("SELECT * FROM [cq:Component] AS c WHERE ISDESCENDANTNODE(c, '/apps/core/wcm')", "JCR-SQL2");
while (componentIter.hasNext()) {
var compoenentRes = componentIter.next();
componentList.push(compoenentRes.getPath());
}
return {
pageName: pageName,
title: title,
resourceName: resourceName,
componentList: componentList
};
});
The component HTL code to use it, would be:
<div data-sly-use.info="info.js">
<p>page name: ${info.pageName}</p>
<p>title: ${info.title}</p>
<p>resourceName: ${info.resourceName}</p>
<p>core components: </p>
<ul data-sly-list.component="${info.componentList}">
<li>${component}
</ul>
</div>
PS: You probably know, but here you find the Use-API for JS:
https://helpx.adobe.com/experience-manager/htl/using/use-api-javascript.html
I'm not aware of any Web-API for JCR_SQL2 queries. You would have to implement your own Servlet in AEM (with Java), which would accept queries from external HTTP requests. Then you could call your servlet from your JS code via Ajax, and execute the query inside AEM with Java.
Maybe the Query Builder API is interesting for you. This query-language is already available from the outside, and can be called via Ajax. For testing and developing your queries you can use the Query Debugger:
Adobe Documentation:
https://helpx.adobe.com/experience-manager/6-3/sites/developing/using/querybuilder-api.html
Query Debugger:
http://localhost:4502/libs/cq/search/content/querydebug.html
Query Debuger with Sample Query:
http://localhost:4502/libs/cq/search/content/querydebug.html?charset=UTF-8&query=type%3Dcq%3APage%0D%0Aorderby%3D%40jcr%3Acontent%2Fcq%3AlastModified%0D%0Aorderby.sort%3Ddesc
Sample Query called directly:
http://localhost:4502/bin/querybuilder.json?orderby=%40jcr%3acontent%2fcq%3alastModified&orderby.sort=desc&type=cq%3aPage
In my app I'm reading data from a JSON file and creating a model from it like this
var myModel = new sap.ui.model.JSONMOdel("pathToJson");
I have 300 values but I only want to read 50, is there a way to do that. I know I can use $top and $skip to select a specific set of values using OData. The API provides the function myModel.loadData() which contains a parameter oParameters but I don't know what I can pass in. Does anyone know if this possible?
The JSON model is a client-side model. This means that all the data is loaded at once with a single request. In the standard implementation, it has no methods for reading paged JSON contents (with top / skip or any other name you might give them).
You have said that you have a JSON file that you are loading. So such a paging does not even make sense from a technical point of view. This is because you cannot (easily) load a portion of a static file with client-only code (especially JSON, which is not valid if you are reading a fragment of it).
If you actually just want to store a segment of the file in the model, you can simply read the whole file with jQuery.ajax and then slice the array.
If you actually have a RESTful web service, then the paging mechanism should be part of this service (e..g it should have some path or query parameters for specifying the paging parameters). This service should return a valid JSON document for each call. On the client side, you can use such a service with the help of some functions (e.g. in the controller):
onInit: function () {
this.setModel(new JSONModel([])); // initially an emty array
},
//call this method when you want to read a page
onReadDataPage: function (iTop, iSkip) {
// use jQuery.ajax or jQuery.get to read a "page" of data; e.g.
jQuery.ajax({
url: "your service path",
data: {
top: iTop,
skip: iSkip || 0
},
success: this.onDataReceived.bind(this)
});
},
onDataReceived: function (aData) {
var oModel = this.getModel();
oModel.setData(oModel.getData().concat(aData);
}
If you want to use this in combination with a List with the growing feature, then you will need to create a new type of model - which is not trivial.
I have a large mongoDB database set up and am trying to create a website where a user can use a searchbar to query the database remotely and have the results posted on the site (strictly read-only).
I have experience with databases for data analysis, but have never created a website for querying results.
I'm don't have any experience with web development and don't know what platforms (PHP? node.js?) to use.
Thanks in advance.
There are the following steps to the problem:
Create the front-end, which will consist of HTML, CSS, and Javascript. Beginners often find it easiest to work with jQuery and jQuery UI, because they are well-documented and contain plugins for almost all possible scenarios (they should not, however, be used to create large complex applications!). Bootstrap or Foundation can help you with the HTML / CSS.
Create a (probably) JSON API, which the front-end can communicate with to submit searches and retrieve results. You could use PHP, Python, Ruby, or many other languages to do this. For a simple site like the one you're describing, it's more a matter of preference than anything else.
Translate the search request from the front-end into the MongoDB query APIs, and return the results through the API. You will use a MongoDB client library compatible with whatever language you have chosen.
Depending on your needs, you may be able to eliminate (2) by using an existing REST API for MongoDB.
Note that if you just want to make MongoDB data accessible via searching / charting, then you may be able to avoid coding altogether by leveraging SlamData, an open source project I contribute to. SlamData lets you use Google-style search (or more advanced SQL) to query MongoDB and get the results back in tabular or chart form.
I am doing such in nodejs.
In my server side app I have connection via mognoose like:
var mongoose = require('mongoose');
mongoose.connect('mongodb://yourhost/database');
Next you need to have your model to your database
var YourDBVarName = mongoose.model('collectionName', {
yourfields1 : type,
yourfields2 : type,
yourfields3 : type
...
});
Then I make GET for it
var express = require('express');
var app = express();
app.get('/dblisting', function(req,res){
YourDBVarName.find({ yourfieldsX: 'value'}, function(err, data) {
if(err) {
res.send(err.message);
}
else{
res.send(data);
});
});
Then simply you make some GET with $.ajax to yournodeserver.com/dblisting and in response you recive your collection filtered as in
{ yourfieldsX: 'value'}
Ofcourse you may do just {} so you get all your stored data.
SLee
If you want know about retrieving data from mongoDB, you can use my github https://github.com/parthaindia/CustomMongo .Use getByCondition() method which requires collection name and a Map . The Map can be your queries in form of key value pair,Key being the column name. I use this method when I write search Query for the web development. The java code gives you a Json. Write a Servlet to post your Json to WEB UI.
This is an example to show how to post the retrieved data using Js ,"server_base_url + /server/FetchData" would be your Service URL.The data you has to be appended to a table . Or a span ,depends on what you actually want.The below code appends data
function getdata() {
$.get(server_base_url + "/server/FetchData", {
}).done(function (data) {
$.each(data, function (index, value) {
alert("The Index" + index + "The Value" + value);
$("#11table1").append("<tr><td id='dynamicid1" + index + "'>" + value + "</td></tr>");
});
});
}
This function can be used for defining table
function defineTable() {
$("#mainDivID").text("").append("<div id='contpanel' class='contentpanel'>");
$("#contpanel").append("<div id='rowid11' class='row'>");
$("#rowid11").text("").append("<div id='row11table1' class='col-md-12'>");
$("#row11table1").text("").append('<br /><br /><center><h5 class="lg-title mb5" style="background-color:#428BCA;height:20px;color:#fff;padding-top:4px;"><b>Heading</b></h5></center>');
$("#row11table1").append("<div id='table11id1' class='table-responsive'>");
$("#table11id1").append("<table id='11table1' class='table table table-bordered mb30' >");
$("#11table1").append("<thead><tr><th>Index</th><th>Value</th></tr></thead>");
}
I am using token input to search data as follows:
<portlet:resourceURL var="categoryRequestURL" />
<script type="text/javascript">
$(document).ready(function () {
var catUrl = "<%=categoryRequestURL%>";
var cat_input_id = "<%=portletNamespace%>categories_selector";
$("#textbox_id").tokenInput(catUrl, {theme: "facebook"});
});
</script>
And in the public void serveResource():
PrintWriter writer = resourceResponse.getWriter();
JSONObject j1 = JSONFactoryUtil.createJSONObject();
j1.put("id", "1");
j1.put("name", "Data center");
JSONObject j2 = JSONFactoryUtil.createJSONObject();
j2.put("id", "2");
j2.put("name", "Database");
catJsonArray.put(j1);
catJsonArray.put(j2);
writer.write(jsonArray.toString().trim());
writer.flush();
writer.close();
The problem was whatever I entered in the input box, all data in the json array was displayed:
However, if I hard coded json data instead of using resource url. Then it worked correctly.
Does any one have any ideas?
I have no experience with liferay in the slightest, but think I can see what is 'theoretically' the problem.
With jquery tokeninput, when you use an external URL to get your search results, you must deal with the search logic yourself. This is to allow you to query databases and such like. The search parameter is (by default) sent to your page in the GET parameter 'q', and the JSON you return should only be the relevant search results, rather than the entire collection of data.
As I say, I have no idea how to implement such a thing using liferay - but from looking at your code, there doesn't seem to be any point where that logic could be in there!
Is it possible to access data obtained via .getJSON call in jquery as a jinja2 variable ?
$.getJSON(
$SCRIPT_ROOT +"/gitem/"+node.id,
function(data){
if (data.length > 0){
$.each(data, function(index,val_dict) {
var button_id = "button_"+String(index);
var popup_id = "element_to_pop_up_"+String(index);
var append_string = sprintf('<div class="icony"><img src="%s" height="75" id="%s" >%s</div>',val_dict.img_url,button_id,val_dict.img_caption);
var bpopup_element = sprintf('<div id="%s"><a class="bClose"><img src="%s" width="500px">X<a/></div>',popup_id,val_dict.img_url)
$('.data_area').append(append_string+bpopup_element);
$('#'+popup_id).hide();
$('#'+button_id).bind('click', function(e) {
e.preventDefault();
$('#'+popup_id).bPopup();
});
});
}
else
{
var append_string = '<div class="icony">No Images to display for this category</div>';
$('.data_area').append(append_string);
}
$("#list_viewer").css("display", "block");
});
For example in the above I am getting the data and then constructing the DOM within js. While what would be best would be to import data via .getJSON and then set the data as a jinja2 variable.
Later I can use that variable within jinja2 template ?
it that possible ?
or better still...
can a jinja macro be called from within the .getJSON function ? that can also allow embedding of json data within jinja2....
thanks for any pointer...
Probably not. Jinja generally runs on the server, rendering your web site templates before sending them off to the client. The client (i.e. your web browser) will not have access to the templates.
If you'd like to use Jinja templates to render client-side JSON objects, you could take a look at Jasinja, which is a tool to convert your Jinja templates to JavaScript, which you can then use in the browser. A number of similar tools exist.
Finally, another solution is to send your JSON data to the web server, render them to HTML via Jinja, then send back the resulting HTML in the XMLHttpRequest response. However, if you've obtained this JSON data from the same server you use to render templates, you might be better off just having HTML sent to the client directly and added to the DOM from there.