Right now I am feeding in the contents of one JSON feed and display
(function () {
var twitterLikes = "data.json";
//Grab the JSON
$.getJSON(twitterLikes, {
format: "json"
})
.done(function (data) {
//iterate through each item
$.each(data.likes, function (i, likes) {
//Print out JSON results
var twitterLike = '<div class="twitterLike" id="' + likes.id + '"><img class="twitterLikeImage" src="' + likes.image + '"><p class="twitterLikeCaption">' + likes.caption + '</p><a class="twitterLikeLink" href="' + likes.link + '" target="_blank">See original post</a></div>';
//Append printed reuslts to parent container
document.getElementById("twitterLikes").innerHTML += twitterLike;
//Cap the results
if (i === 12) {
return false;
}
});
});
})();
This needs modification. I have another JSON file that I've created as some sort of "Locked" file, which basically locks a particular post in a given position.
{ "locked":[{"id":90210, "position":3}] }
How would I modify my function to parse the 2nd JSON File (locked). Basically look in the locked file, see if theres an id and position. Match that id to the 1st JSON file (data.json). Lock that post based on id to the particular position. Go through data.json and paint the rest of the posts skipping the locked positions. Should only show 12 at most also.
I am not sure I understand your locking mechanism, but some variant on (I have used lodash to help - but it's not necessary)
$.getJSON("data.json", { format: "json" })
.done(function (data) {
$.getJSON("locked.json", {format: "json"})
.done(function(locked){
var lockedIds = _.map(locked, function(l){
return l.id
})
$.each(data.likes, function(i, likes){
// If not locked then process
if (!_.contains(likes.id, lockedIds)){
// do something here
}
})
})
}
Hope this helps.
Thanks Joe. This is what I got so far:
$.getJSON("data.json", { format: "json" })
.done(function( data ) {
$.getJSON("locked.json", {format: "json"})
.done(function(locked){
var lockedIds = _.map(locked, function(l){
return l.id
})
//iterate through each item
$.each( data.likes, function( i, likes ) {
if (!_.contains(likes.id, lockedIds)){
//Print out JSON results
var twitterLike='<div class="twitterLike" id="'+likes.id+'"><img class="twitterLikeImage" src="'+likes.image+'"><p class="twitterLikeCaption">'+likes.caption+'</p><a class="twitterLikeLink" href="'+likes.link+'" target="_blank">See original post</a></div>';
//Append printed reuslts to parent container
document.getElementById("twitterLikes").innerHTML+=twitterLike;
}
//Cap the results
if ( i === 12 ) {
return false;
}
});
});
})();
I seem to be off a little bit. You are right, I don't necessarily need to combine the two. More need to display those posts in a "locked" position, then move onto the rest from the original feed.
DATA.JSON
{
"count": 2,
"likes": [
{
"link": "http://twitter.com/p/tQc2YNh3ox/",
"caption": "Yada",
"profile_pic": "",
"likes": 27,
"id": "815278414704900657_1364335477",
"image": "http://twitter.com/pic1.png"
}, {
"link": "http://twitter.com/p/tQc2YNh3ox2/",
"caption": "Yada2",
"profile_pic": "",
"likes": 27,
"id": "815078520979421610_1364335477",
"image": "http://twitter.com/pic2.png"
}
]
}
LOCKED.JSON
{
"likes": [
{
"id": "815278414704900657_1364335477",
"position": 3
}, {
"id": "815078520979421610_1364335477",
"position": 5
}
]
}
Related
My objective is to carry multiple parameters in same row but from different column. In my case, each row contain of 7 columns. but only 3 parameters that I need to pass to btnApprove1 function. This function will appoint to other API which require all that 3 parameters.
So how to carry service_id, project_id and staff_id into btnApprove function when clicked?
columns: [
{ data : "service_id", "className": "text-center" },
{ data : "project_id", "className": "text-center" },
{ data : "staff_id", "className": "text-center" },
{ data : "status", "className": "text-center",
render: function(data){
if (data == "1001") {
return "<span onclick='btnApprove(""+data+"")'</span>";
}
else {
return data;
}
}
},
{ data : "lorry", "className": "text-center" },
{ data : "car", "className": "text-center" },
{ data : "van", "className": "text-center" }
]
function btnApprove(service_id, project_id, staff_id){
console.log(service_id, project_id, staff_id)
var params = {
"service_id": service_id,
"project_id": project_id,
"staff_id": staff_id
};
params = JSON.stringify(params);
$.ajax ({
...
});
}
According to the jQuery Datatable documentation for the column cell render() function, it takes four parameters, the third parameter is called row, and it's an array of values each representing the value of the column with the respective index. You can use this parameter to pass the right values to your btnApprove function.
In the code block below, I make use of destructuring on the row array to only get the first three values you need. Template literals also help make string HTML more readable.
render: function(data, type, [service_id, project_id, staff_id]) {
if (data === '1001') {
return `
<span onclick="btnApprove('${service_id}', '${project_id}', '${staff_id}')">
${data}
</span>
`;
}
return data;
}
To make sure that your <span> click event has access to btnApprove when used as a string like you have, it needs to be declared globally, on thing you can do is to change the definition of the function from:
function btnApprove(service_id, project_id, staff_id) {
To:
btnApprove = function(service_id, project_id, staff_id) {
I just solve this issue by applying this.
{ data : "status", "className": "text-center",
fnCreatedCell: function (nTd, sData, oData, iRow, iCol) {
if (oData.status == "1001") {
var stat = '<span class="badge badge-warning font-11">Approval</span><br/>';
$(nTd).html("<span onclick='btnApprove(""+oData.service_id+"", ""+oData.project_id+"", ""+oData.staff_id+"")'>"+stat+"</span>");
}
else if (oData.status == "1000") {
var stat2 = '<span class="badge badge-primary font-11">Registered</span>';
$(nTd).html("<span onclick='btnNotApprove(""+oData.service_id+"", ""+oData.project_id+"", ""+oData.staff_id+"")'>"+stat2+"</span>");
}
}
},
I am trying to populate datatables with a complex json scheme, however I don't know exactly how to do it.
First, some parts of json are nested and it needs iteration.
Second I need to create some markup, basically a href link.
Here is what I have:
$(document).ready(function(){
$('#empTable').DataTable({
'processing': true,
'serverSide': true,
'serverMethod': 'post',
'ajax': {
'url':'/dashboard/ajaxgetrequests',
dataSrc: "json_list"
},
'columns': [
{ data: 'firstname' },
{ data: 'funding_project_name' } // this must be a link like <a href='/<relation_id>'><funding_project_name></a>
]
});
});
{
"json_list":{
"125":{
"firstname":"John",
"funding_project_name":"A",
"relation_id": "7"
},
"133":{
"firstname":"Cesar",
"funding_project_name":[
"A",
"B"
],
"relation_id":[
"7",
"9"
]
}
}
}
1) For nested JSON you can use something like this:
// JSON structure for each row:
// {
// "engine": {value},
// "browser": {value},
// "platform": {
// "inner": {value}
// },
// "details": [
// {value}, {value}
// ]
// }
$('#example').dataTable( {
"ajaxSource": "sources/deep.txt",
"columns": [
{ "data": "engine" },
{ "data": "browser" },
{ "data": "platform.inner" },
{ "data": "details.0" },
{ "data": "details.1" }
]
} );
2) To edit and insert a link you can use columns.render (documentation)
$('#example').dataTable( {
"columnDefs": [ {
"targets": 0,
"data": "download_link",
"render": function ( data, type, row, meta ) {
return 'Download';
}
} ]
} );
Honestly, there may be a better built in way of handling this but when I experience things that do not fit the exact mold of using the base datatable functionality, I prefer to take manual control of the generation. This will give you an overview on how to do it with your structure:
Just basic html for your table (nothing really to see here):
<table id="empTable">
<thead>
<tr><th>First Name</th><th>ProjectName</th></tr>
</thead>
<tbody></tbody>
</table>
In JS we declare a variable we can use throughout our script then on ready event we instatiate our datatable:
var dt;
$(document).ready(function () {
dt = $('#empTable').DataTable();
loadDT();
});
We will also use a function call 'loadDT()' and what this will do is trigger a ajax call to the backend to get your json, in this example, I'm just gonna mock it but in your world so this on the ajax success:
Iterate your list and determine the types then use the api call row.add to dynamically add new rows to your table. (notice we are reusing the stored variable dt that we initially declared.) This is where you can do whatever custom logic fun you need to do.
function loadDT(){
var mockJSON = { "json_list":{ "125":{ "firstname":"John","funding_project_name":"A","relation_id": "7"},"133":{ "firstname":"Cesar","funding_project_name":["A","B"],"relation_id":["7","9"]}}};
$.each(mockJSON.json_list, function (i, n){
if(Array.isArray(n.funding_project_name)) {
$.each(n.funding_project_name, function (i2, p){
dt.row.add([n.firstname,'' + p + '']);
dt.draw(false);
});
} else {
dt.row.add([n.firstname, '' + n.funding_project_name + '']);
dt.draw(false);
}
});
}
Like previously stated, there may be some built in functions to handle this that I am unaware but when things get complicated, just know you can take manual control of it.
Full Example:
var dt;
$(document).ready(function () {
dt = $('#empTable').DataTable();
loadDT();
});
function loadDT(){
var mockJSON = { "json_list":{ "125":{ "firstname":"John","funding_project_name":"A","relation_id": "7"},"133":{ "firstname":"Cesar","funding_project_name":["A","B"],"relation_id":["7","9"]}}};
$.each(mockJSON.json_list, function (i, n){
var projLinks = "";
if(Array.isArray(n.funding_project_name)) {
$.each(n.funding_project_name, function (i2, p){
projLinks += '' + p + ' ';
});
} else {
projLinks = '' + n.funding_project_name + '';
}
dt.row.add([n.firstname, projLinks]);
dt.draw(false);
});
}
<link href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<table id="empTable">
<thead>
<tr><th>First Name</th><th>ProjectName</th></tr>
</thead>
<tbody></tbody>
</table>
I'm using get_bottom_selected to get all the checked/selected nodes in JSTree. When I setup a button in my form that calls the following method it works. When I try to call the same function from check box click event it does not find any selected nodes, even if there are some.
function testit() {
var data = $('#my_tree').jstree(true).get_bottom_selected(true);
for(var count = 0; count < data.length; count++){
// Do Stuff
}
}
When the following event fires I want to call the function and get all the selected child nodes, but it does not work. Is there something specific to do on this event that works different than calling from a button click event?
.on("check_node.jstree uncheck_node.jstree", function(e, data) {
testit(); // first line of this function does not get any selected data, even if several are selected. When called from a button click event in my form it does work.
});
Here's how I currently have my jstree setup.
$('#my_tree')
.on("changed.jstree", function (e, data) {
// Do Stuff
})
.jstree({
checkbox: {
"keep_selected_style": false,
"visible" : true,
"three_state": true,
"whole_node" : true,
},
plugins: ['checkbox'],
'core' : {
'multiple' : true,
'data' : {
"url" : "/static/content_data.json",
"dataType" : "json"
}
}
})
.on("check_node.jstree uncheck_node.jstree", function(e, data) {
testit();
});
Because of the strict mode you will get the exception that if you try to use get_bottom_checked
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them.
at Function.invokeGetter (<anonymous>:2:14)
You can use data.selected from your check or uncheck event handler if you just want the ids of selected nodes but if you need more than that you can use 'data.instance._model.data'. As you can see in my example I am trying to alert if there is only one item selected and that's state is open. In the code example, you can see the Alert if you open the `Europe1 and select the checkbox.
var data1 = [{
"id": "W",
"text": "World",
"state": {
"opened": true
},
"children": [{
"text": "Asia"
},
{
"text": "Africa"
},
{
"text": "Europe",
"state": {
"opened": false
},
"children": ["France", "Germany", "UK"]
}
]
}];
function testit(data) {
alert(data.length + ' and ids are ' +data );
for (var count = 0; count < data.length; count++) {
}
}
$('#Tree').jstree({
core: {
data: data1,
check_callback: false
},
checkbox: {
three_state: false, // to avoid that fact that checking a node also check others
whole_node: false, // to avoid checking the box just clicking the node
tie_selection: false // for checking without selecting and selecting without checking
},
plugins: ['checkbox']
})
$('#Tree').on("check_node.jstree uncheck_node.jstree", function(e, data) {
if (data.selected.length === 1) { alert(data.instance._model.data[data.selected].state['opened']); }
testit(data.selected);
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" type="text/css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<div id="Tree"></div>
According to this
you can get all selected nodes on change event like this:
$('#jstree').on('changed.jstree', function (e, data) {
var i, j, r = [];
for(i = 0, j = data.selected.length; i < j; i++) {
r.push(data.instance.get_node(data.selected[i]).text);
}
$('#event_result').html('Selected: ' + r.join(', '));
}).jstree();
Using gmap3 (a jquery plugin) to display a Google maps interface. I'm trying to load my data from a JSON file but for some reason it's not executing. The map displays, the addMarkers() function is being called, but if I put a console.log() anywhere inside function(data), it doesn't display.
I'm somewhat confused about these anonymous functions and haven't worked with asynchronous functions before. Any advice would be much appreciated.
Javascript
$(document).ready(function(){
displayMap();
addMarkers();
});
// Create map with options
function displayMap(){
$('#map_canvas').gmap3({
map: {
options: mapOptions
}
});
};
// Load data and add markers for each data point
function addMarkers(){
$.getJSON( dataURL, function(data) {
$.each( data.markers, function(i, marker) {
console.log( marker.lat + ':' + marker.lng + ':' + marker.data.category + ':' + marker.data.content );
})
});
};
JSON
{
markers: [
{ lat:-30, lng:145, data: {title: "Le Restaurant", category:"Restaurant", content:"Some French restaurant"} },
{ lat:-30, lng:145, data: {title :"Gem Cafe", category:"Cafe", content:"They sell coffee"} },
{ lat:-30, lng:145, data: {title :"Home", category:"Home", content:"Home sweet home."} }
]
}
Silly me, just checked my JSON format using http://jsonlint.com/ and discovered it was malformed. I needed to enclose the 'key' names in quotes like so ...
{
"markers": [
{ "lat":-30, "lng":145, "data": {"title": "Le Restaurant", "category":"Restaurant", "content":"Some French restaurant"} },
{ "lat":-30, "lng":145, "data": {"title" :"Gem Cafe", "category":"Cafe", "content":"They sell coffee"} },
{ "lat":-30, "lng":145, "data": {"title" :"Home", "category":"Home", "content":"Home sweet home."} }
]
}
I'm new to FuelUX so I was trying to get this to work, based on the example provided:
require(['jquery','data.js', 'datasource.js', 'fuelux/all'], function ($, sampleData, StaticDataSource) {
var dataSource = new StaticDataSource({
columns: [{property:"memberid",label:"LidId",sortable:true},{property:"name",label:"Naam",sortable:true},{property:"age",label:"Leeftijd",sortable:true}],
data: sampleData.memberdata,
delay: 250
});
$('#MyGrid').datagrid({
dataSource: dataSource,
stretchHeight: true
});
});
});
With this as the data:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(factory);
} else {
root.sampleData = factory();
}
}(this, function () {
return {
"memberdata": [{
"memberid": 103,
"name": "Laurens Natzijl",
"age": "25"
}, {
"memberid": 104,
"name": "Sandra Snoek",
"age": "25"
}, {
"memberid": 105,
"name": "Jacob Kort",
"age": "25"
}, {
"memberid": 106,
"name": "Erik Blokker",
"age": "25"
}, {
"memberid": 107,
"name": "Jacco Ruigewaard",
"age":"25"
},{ /* etc */ }]
}
}));
I've got no console errors, no missing includes. Everthing works just fine - it even looks like it's loading. Except nothing shows up in the datagrid but '0 items'.
Any suggestions? I think I did everything the example provided...
EDIT: 14:33 (Amsterdam)
There seems to be a difference when I put this in console:
My page:
require(['jquery','data.js','datasource.js', 'fuelux/all'], function ($, sampleData, StaticDataSource) {
var dataSource = new StaticDataSource({
columns: [{property:"memberid",label:"LidId",sortable:true},{property:"name",label:"Naam",sortable:true},{property:"age",label:"Leeftijd",sortable:true}],
data: sampleData.memberdata,
delay: 250
});
console.debug(dataSource);
});
1st row in console:
function localRequire(deps, callback, errback) { /* etc */ }
2nd row in console:
StaticDataSource {_formatter: undefined, _columns: Array[3], _delay: 250, _data: Array[25], columns: function…}
FuelUX Example:
require(['jquery', 'sample/data', 'sample/datasource', 'sample/datasourceTree', 'fuelux/all'], function ($, sampleData, StaticDataSource, DataSourceTree) {
var dataSource = new StaticDataSource({
columns: [{property: 'toponymName',label: 'Name',sortable: true}, {property: 'countrycode',label: 'Country',sortable: true}, {property: 'population',label: 'Population',sortable: true}, {property: 'fcodeName',label: 'Type',sortable: true}],
data: sampleData.geonames,
delay: 250
});
console.debug(dataSource);
});
1st row in console:
StaticDataSource {_formatter: undefined, _columns: Array[4], _delay: 250, _data: Array[146], columns: function…}
2nd row in console:
function (deps, callback, errback, relMap) { /* etc */ }
Maybe this will help you help me :)
I didn't see all of the information I needed to provide a finite answer. The real magic is the datasource.js file (which you had not provided).
I thought an easier way of demonstrating all the necessary pieces would be to put together a JSFiddle showing your data in use and all the pieces that were necessary.
Link to JSFiddle of Fuel UX Datagrid sample with your data
Adam Alexander, the author of the tool, also has written a valuable example of using the dataGrid DailyJS Fuel UX DataGrid
// DataSource Constructor
var StaticDataSource = function( options ) {
this._columns = options.columns;
this._formatter = options.formatter;
this._data = options.data;
this._delay = options.delay;
};
StaticDataSource.prototype = {
columns: function() {
return this._columns
},
data: function( options, callback ) {
var self = this;
var data = $.extend(true, [], self._data);
// SEARCHING
if (options.search) {
data = _.filter(data, function (item) {
for (var prop in item) {
if (!item.hasOwnProperty(prop)) continue;
if (~item[prop].toString().toLowerCase().indexOf(options.search.toLowerCase())) return true;
}
return false;
});
}
var count = data.length;
// SORTING
if (options.sortProperty) {
data = _.sortBy(data, options.sortProperty);
if (options.sortDirection === 'desc') data.reverse();
}
// PAGING
var startIndex = options.pageIndex * options.pageSize;
var endIndex = startIndex + options.pageSize;
var end = (endIndex > count) ? count : endIndex;
var pages = Math.ceil(count / options.pageSize);
var page = options.pageIndex + 1;
var start = startIndex + 1;
data = data.slice(startIndex, endIndex);
if (self._formatter) self._formatter(data);
callback({ data: data, start: 0, end: 0, count: 0, pages: 0, page: 0 });
}
};
If you were to provide your markup and what your "datasource.js" file contains, I may be able to help you further.
I think the demonstration provides much information on any pieces you may not have understood.
Adding on to creatovisguru's answer:
In his JSFiddle example, pagination is broken. To fix it, change the following line:
callback({ data: data, start: start, end: end, count: count, pages: pages, page: page });
I had the exact same issue, when tried to integrate with Django. The issue I believe is on this line :
require(['jquery','data.js','datasource.js', 'fuelux/all'], function ($, sampleData, StaticDataSource) {
I was not able to specify file extension, my IDE (pycharm), would mark "red", when used "data.js", so it needs to stay without an extension, such as "sample/data"
What I end up doing to make it work, is downloading the full fuelux directory from github in /var/www/html on a plain Apache setup ( no django, to avoid URL.py issues for static files ) and everything works using their example. Here are the steps to get you started :
cd /var/www/html
git clone https://github.com/ExactTarget/fuelux.git
and you will end up with fuelux in /var/www/html/fuelux/
in your browser, navigate to : http://foo.com/fuelux/index.html ( assuming your default document root is /var/www/html )
good luck!