Can yadcf be used to filter rows on a class - class

Im looking for an easy way to filter 3 cols which certain rows have a specific class.
I have a datatable for live football games, this shows me inplay stats and if stats get above a certain level I add a class to the TD, for example
if(Number(chars[0])+Number(chars[1])>15)
{
$(row).find('td:eq(8)').css('background-color', 'lime');
$(row).find('td:eq(8)').addClass('lime');
}
On a busy day I can have over 100 live games at a time and I would like to filter just showing the games which have a class of 'lime'. There are 3 cols I shade using this so ideally I want a single filter to cover all 3
Ive tried using the search plugin for datatables but I can only get it to work on the first page of results.
const table = $('#example').DataTable( {
responsive: {
details: {
}
},
"ajax": "console.json",
"search": {
"regex": true
},
"columns": [
{
"class": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "time" },
{ "data": "firstgoal" },
{ "data": "score" },
{ "data": "league" },
{ "data": "teams", "defaultContent": "0" },
{ "data": function (data, type, dataToSet) {
return data.nextover + "% (" + data.sno + ")";}
},
{ "data": "pi1",
"render": function (data, type, row) {
return '<span class="show-modalp1" data-modal-id="'+ row.gameid + '">' + data + '</span>';
}},
{ "data": "pi2",
"render": function (data, type, row) {
return '<span class="show-modalp2" data-modal-id="'+ row.gameid + '">' + data + '</span>';
}},
{ "render": function (data, type, JsonResultRow, meta) {
return '<img src="'+JsonResultRow.rc+'" class="center">';
}}
],
"order": [[1, 'asc']],
rowCallback: function(row, data, index){
if((data["nextover"] >85 && data["sno"]>14) || (data["nextover"] >70 && data["sno"]>10 && data["time"]>=70) || (data["nextover"] >55 && data["sno"]>5 && data["time"]>=81))
{
$(row).find('td:eq(6)').css('background-color', 'lime');
$(row).find('td:eq(7)').addClass('lime');
}
else
{
$(row).find('td:eq(6)').css('background-color', 'mistyrose');
}
var chars = data["pi2"].split(':');
if(Number(chars[0])+Number(chars[1])>15)
{
$(row).find('td:eq(8)').css('background-color', 'lime');
$(row).find('td:eq(8)').addClass('lime');
}
else
{
$(row).find('td:eq(8)').css('background-color', 'mistyrose');
}
var chars2 = data["pi1"].split(':');
if(Number(chars2[0])+Number(chars2[1])>70)
{
$(row).find('td:eq(7)').css('background-color', 'lime');
$(row).find('td:eq(7)').addClass('lime');
}
else
{
$(row).find('td:eq(7)').css('background-color', 'mistyrose');
}
},
drawCallback: function(settings) {
$(".show-modalp1").each(function() {
var id = $(this).attr('data-modal-id');
$(this).popover({
content: function() {
return '<div style="width: 440px; height=220px"><iframe src="../pressure/showgraph.php?gameid=' + id + '&pi=pi1" width=440 height=220></iframe></div>';
},
trigger: 'hover',
placement: 'left',
html: true,
title: 'Pressure Index 1 = (10*SOT)+(10*SOFT)+1 per 5%poss'
}
)
});
$(".show-modalp2").each(function() {
var id = $(this).attr('data-modal-id');
$(this).popover({
content: function() {
return '<div style="width: 440px; height=220px"><iframe src="../pressure/showgraph.php?gameid=' + id + '&pi=pi2" width=440 height=220></iframe></div>';
},
trigger: 'hover',
placement: 'left',
html: true,
title: 'Pressure Index 2 = 1 *dangerous attack - 1 point if no corners in last 8'
}
)
});
},
} );
$.fn.DataTable.ext.search.push(function(_,__,rowIdx){
return $(table.row(rowIdx).node()).has('td.lime').length || !$('#showLime').hasClass('limeOnly');
});
$('#example').on('draw.dt', function () {
$('[data-toggle="tooltip"]').tooltip();
});
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).parents('tr');
var row = table.row( tr );
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
} );
$('#reset').on('click', function () {
table.columns(1).search("").draw();
table.ajax.reload(null, false);
})
$('#secondhalf').on('click', function () {
regExSearch = '(4[6-9]|[5-8][0-9]|90)';
table.column(1).search(regExSearch, true, false).draw();
});
$('#firsthalf').on('click', function () {
regExSearch = '([1-3][0-9]|4[0-5])';
table.column(1).search(regExSearch, true, false).draw();
});
$('#halftime').on('click', function () {
table.columns(1).search("HT").draw();
});
;
$('#showLime').on('change', function () {
$(this).toggleClass('limeOnly');
table.draw();
});
setInterval( function () {
table.ajax.reload( null, false ); // user paging is not reset on reload
}, 30000 )
}
);

Related

Invisible chart area during print and in exported PDF file in spreadsheet created by service account with Google Sheets API (Node.js) in shared folder

I'm creating a spreadsheet in Node.js environment in shared folder using service account with Google Sheets API v.4 in few steps:
Create spreadsheet itself in shared folder with "Can Edit" permission for service account.
Inserting some data and performing some text formats using spreadsheet ID received as callback from previous step.
Inserting chart using as income data the data inserted in prevoius step.
As the result I have a spreadsheet with expected result (text data and horizontal bar chart on same sheet). But when I'm trying to send it on printer, or download as PDF-file - chart area becomes completely invisible. I didn't find any option in official documentation about possible chart visibility during printing or something like this. And when I'm replacing this created chart with manually created one - everything is ok, I can print it and export to PDF.
So, what is the problem? Am I missing something? Or it's some bug?
index.js
const fs = require('fs');
const { google } = require('googleapis');
const express = require('express');
const bodyParser = require("body-parser");
const app = express();
const PORT = 3000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.listen(PORT, () => {
console.log(`Server started at http://localhost:${PORT}`)
})
const SCOPES = ['https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/spreadsheets'];
const FOLDER_ID = '1xG3xHhrucB4AGLmnd8T2TmCyqhmPux5Q';
var timeStamp = new Date().getTime();
console.log(`timeStamp at startup = ${timeStamp}`);
const auth = new google.auth.GoogleAuth({
keyFile: 'credentials.json',
scopes: SCOPES
});
process.env.HTTPS_PROXY = 'http://10.5.0.20:3128';
const sheets = google.sheets({
version: 'v4',
auth: auth,
proxy: 'http://10.5.0.20:3128'
});
const drive = google.drive({
version: 'v3',
auth: auth,
proxy: 'http://10.5.0.20:3128'
});
function createFileName() {
const now = new Date();
let date = String(now.toISOString().slice(0, 10));
let hours = String(now.getHours()).padStart(2, "0");
let minutes = String(now.getMinutes()).padStart(2, "0");
let seconds = String(now.getSeconds()).padStart(2, "0");
let humanDate = date.replaceAll('-', '.');
humanDate = `${humanDate}_${hours}-${minutes}-${seconds}`;
return humanDate;
}
async function saveFileLocally(filePath, data) {
fs.writeFile(filePath, JSON.stringify(data), error => {
if (error) {
console.error(error);
return;
}
});
return true;
}
app.get("/check", (req, res) => {
res.send('server is online...');
});
app.post("/motivation", async (req, res) => {
if(!req.body) return res.sendStatus(400);
try {
const prizv = req.body.prizv;
const name = req.body.name;
const father = req.body.father;
const sex = req.body.sex;
const age = req.body.age;
const factors = req.body.factors;
const testName = 'motivation';
const clientData = { prizv: prizv, name: name, father: father, sex: sex, age: age, factors: factors, testName: testName };
const fileName = `${createFileName()}_${prizv}`;
const filePath = `files/${testName}/${fileName}.txt`;
const isSaved = await saveFileLocally(filePath, clientData);
if (isSaved) {
console.log(`file is saved locally....`);
const sheetID = await createSheetToGoogleDIsk(clientData, fileName);
res.send(sheetID);
}
} catch (error) {
console.log(error)
}
});
async function createSheetToGoogleDIsk(clientData, fileName) {
const file = fileName;
var sheetsMetadata = {
name: file,
mimeType: 'application/vnd.google-apps.spreadsheet',
parents: [FOLDER_ID]
};
const res2 = drive.files.create({
resource: sheetsMetadata,
fields: 'id'
}, function (err, file) {
if (err) {
console.error(err);
} else {
console.log('SheetID: ', file.data.id);
const gSheetID = file.data.id;
pasteDataToGoogleSheet(clientData, gSheetID);
insertChartToGoogleSheet(gSheetID);
return file.data.id;
}
});
}
async function insertChartToGoogleSheet(spreadsheetId) {
spreadsheetId = spreadsheetId;
let requests = [];
// set font size for whole Sheet as 14
requests.push({
"repeatCell": {
"range": {
"sheetId": 0,
"startRowIndex": 0,
"endRowIndex": 100,
},
"cell": {
"userEnteredFormat": {
"textFormat": {
"fontSize": 13,
},
},
},
"fields": "userEnteredFormat.textFormat.fontSize"
},
});
// set header text format as Bold and 18 pt
requests.push({
"repeatCell": {
"range": {
"sheetId": 0,
"startRowIndex": 0,
"endRowIndex": 2,
},
"cell": {
"userEnteredFormat": {
"textFormat": {
"fontSize": 18,
"bold": true
},
},
},
"fields": "userEnteredFormat(textFormat)"
},
});
// set subheader text format as Bold and 15 pt
requests.push({
"repeatCell": {
"range": {
"sheetId": 0,
"startRowIndex": 3,
"endRowIndex": 4,
},
"cell": {
"userEnteredFormat": {
"textFormat": {
"fontSize": 15,
"bold": true
},
},
},
"fields": "userEnteredFormat(textFormat)"
},
});
// set client data as Bold
requests.push({
"repeatCell": {
"range": {
"sheetId": 0,
"startRowIndex": 5,
"endRowIndex": 10,
"startColumnIndex": 3,
"endColumnIndex": 5
},
"cell": {
"userEnteredFormat": {
"textFormat": {
"fontSize": 13,
"bold": true
},
},
},
"fields": "userEnteredFormat(textFormat)"
},
});
// set 1st column width as 20px
requests.push({
"updateDimensionProperties": {
"range": {
"sheetId": 0,
"dimension": "COLUMNS",
"startIndex": 0,
"endIndex": 1
},
"properties": {
"pixelSize": 20
},
"fields": "pixelSize"
}
});
// set 4st column width as 150px
requests.push({
"updateDimensionProperties": {
"range": {
"sheetId": 0,
"dimension": "COLUMNS",
"startIndex": 3,
"endIndex": 4
},
"properties": {
"pixelSize": 150
},
"fields": "pixelSize"
}
});
// set bold factors Values
requests.push({
"repeatCell": {
"range": {
"sheetId": 0,
"startRowIndex": 33,
"endRowIndex": 45,
"startColumnIndex": 4,
"endColumnIndex": 5
},
"cell": {
"userEnteredFormat": {
"textFormat": {
"fontSize": 13,
"bold": true
},
},
},
"fields": "userEnteredFormat(textFormat)"
},
});
requests.push({
"addChart": {
"chart": {
"chartId": 1,
"spec": {
"titleTextFormat": {
},
"basicChart": {
"chartType": "BAR",
"axis": [
{
"position": "BOTTOM_AXIS",
},
{
"position": "LEFT_AXIS",
}
],
"domains": [
{
"domain": {
"sourceRange": {
"sources": [
{
"sheetId": 0,
"startRowIndex": 33,
"endRowIndex": 45,
"startColumnIndex": 1,
"endColumnIndex": 2
}
]
},
},
}
],
"series": [
{
"series": {
"sourceRange": {
"sources": [
{
"sheetId": 0,
"startRowIndex": 33,
"endRowIndex": 45,
"startColumnIndex": 4,
"endColumnIndex": 5
}
]
}
},
"targetAxis": "BOTTOM_AXIS"
}
],
},
},
"position": {
"overlayPosition": {
"anchorCell": {
"sheetId": 0,
"rowIndex": 11,
"columnIndex": 1
},
"offsetXPixels": 0,
"offsetYPixels": -7,
"widthPixels": 800,
"heightPixels": 450
},
},
"border": {
"color": {
"red": 1,
"green": 1,
"blue": 1,
"alpha": 0
},
}
}
}
});
const batchUpdateRequest = { requests };
sheets.spreadsheets.batchUpdate({
spreadsheetId,
resource: batchUpdateRequest,
}, (err, result) => {
if (err) {
// Handle error
console.log(err);
return false
} else {
console.log(`${result.updatedCells} chart inserted`);
return spreadsheetId
}
});
}
async function pasteDataToGoogleSheet(clientData, sheetId) {
ecxelID = sheetId;
let data1 = [
["Тест «Мотиваційний особистісний профіль»"], [""], ["Результати тестування"], [""], ["Прізвище"], ["Імя"], ["По-батькові"], ["Вік"], ["Стать"]
];
let data2 = [
[clientData.prizv], [clientData.name], [clientData.father], [clientData.age], [clientData.sex]
];
let factorsLabels1_6 = [
["1. Матеріальна винагорода:"], ["2. Комфортні умови:"], ["3. Структурованість роботи:"], ["4. Соціальні контакти:"], ["5. Довірливі стосунки:"], ["6. Визнання:"]
];
let factors1_6 = [
[clientData.factors.factor1], [clientData.factors.factor2], [clientData.factors.factor3], [clientData.factors.factor4], [clientData.factors.factor5], [clientData.factors.factor6]
];
let factorsLabels7_12 = [
["7. Досягнення мети:"], ["8. Влада і вплив:"], ["9. Відсутність рутини:"], ["10. Креативність:"], ["11. Самовдосконалення і розвиток:"], ["12. Цікава і корисна діяльність:"]
];
let factors7_12 = [
[clientData.factors.factor7], [clientData.factors.factor8], [clientData.factors.factor9], [clientData.factors.factor10], [clientData.factors.factor11], [clientData.factors.factor12]
];
const data = [{
range: "B2:B10",
values: data1,
},
{
range: "D6:D10",
values: data2,
},
{
range: "B34:B39",
values: factorsLabels1_6,
},
{
range: "E34:E39",
values: factors1_6,
},
{
range: "B40:B45",
values: factorsLabels7_12,
},
{
range: "E40:E45",
values: factors7_12,
}
];
const resource = {
data,
valueInputOption: 'RAW',
};
sheets.spreadsheets.values.batchUpdate({
spreadsheetId: ecxelID,
resource: resource,
}, (err, result) => {
if (err) {
// Handle error
console.log(err);
return false
} else {
console.log(`${result.updatedCells} cells data inserted`);
return spreadsheetId;
}
});
}
I could confirm your situation. In this case, how about the following modification?
From:
"offsetXPixels": 0,
"offsetYPixels": -7,
"widthPixels": 800,
"heightPixels": 450
To:
"offsetXPixels": 0,
"offsetYPixels": 0, // Modified
"widthPixels": 800,
"heightPixels": 450
or
"widthPixels": 800,
"heightPixels": 450
When the values of offsetXPixels and offsetYPixels are the negative values, it was found that such an issue occurs.
When the values of offsetXPixels and offsetYPixels are 0, these values are not required to be included because of the default value.
Note:
When I tested the above modification, I could confirm that your issue could be removed.
Reference:
EmbeddedObjectPosition

issue with creating multiple leaflet layers from one geojson file

I have included my code below. While it is sort of working, ill get to that in a minute, I feel like there is a better, more efficient, more correct, way to achieve my goal. I have a map for different weather options, in this case, Tornado, Severe Weather and Flash flood warnings. These are all included in one geojson file. The geo json file has a property called LayerId. This determines the time in the loop that the layer would show. I have a simple global map loop that constantly runs from 0 - 11. So if I am on loop 5, then only the data that corresponds with LayerId 5 would be visible. All others would be hidden/removed (which ever is preferred). When the loop hits 6, the layer corresponding to LayerId 5 would go away and LayerId 6 would now show and so on. Once the loop reaches 11, it starts over at 0.
I am not using a leaflet control due to the site requirements so i am using my own simple check box controls. when the check box is clicked, it calls a toggleLayer function to apply filters to my data. If FlashFlood is checked then only the data corresponding to the flash flood would show over the course of the loop IF it has data for flash flood at that interval.
When i said that it is sort of working...in my loop function i have a call to remove a layer. this works except every now and then it throws a null or undefined error. problem is is that its never the same layer. each time i start the application, its a different layer that errors out.
Below i have included a sample of my geojson and the code. The entry point for the code is at the toggleLayer function.
Thanks for any and all help.
GEOJSON FILE
{
"name": "WarningsJson",
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"coordinates": [
[
[ -86.00, 31.00 ],
[ -86.00, 32.00 ],
[ -87.00, 30.00 ],
[ -86.00, 31.00 ]
]
],
"type": "Polygon"
},
"properties": {
"type": null,
"strokeColor": "#ff9aa3",
"StartDateTime": "09/29/2020 7:30:00 AM",
"EndDateTime": "09/29/2020 9:30:00 AM",
"strokeThickness": 20,
"InfoboxTitle": "SFFW",
"Station": "KMOB",
"Identifier": "FFW",
"LayerId": "0"
}
},
{
"type": "Feature",
"geometry": {
"coordinates": [
[
[ -87.00, 32.00 ],
[ -87.00, 33.00 ],
[ -88.00, 31.00 ],
[ -87.00, 32.00 ]
]
],
"type": "Polygon"
},
"properties": {
"type": null,
"strokeColor": "#c0ffd4",
"StartDateTime": "09/29/2020 7:30:00 AM",
"EndDateTime": "09/29/2020 9:30:00 AM",
"strokeThickness": 2,
"InfoboxTitle": "TOR",
"Station": "KMOB",
"Identifier": "TOR",
"LayerId": "1"
}
},......
APPLICATION CODE
var WarnStormModel = (function () {
var layer0 = new L.LayerGroup();
var layer1 = new L.LayerGroup();
var layer2 = new L.LayerGroup();
var layer3 = new L.LayerGroup();
var layer4 = new L.LayerGroup();
var layer5 = new L.LayerGroup();
var layer6 = new L.LayerGroup();
var layer7 = new L.LayerGroup();
var layer8 = new L.LayerGroup();
var layer9 = new L.LayerGroup();
var layer10 = new L.LayerGroup();
var layer11 = new L.LayerGroup();
var warnConditionsLayersGroup = [layer0, layer1, layer2, layer3, layer4, layer5, layer6, layer7, layer8, layer9, layer10, layer11];
var tornadoActive = false;
var svrActive = false;
var ffwActive = false;
const WarnFilter = {
tornado: null,
svr: null,
flood: null
}
function init() {
$.getJSON('/Data/GeoJsonFiles/WarningJsons/Warnings_0.json', function (data) {
L.geoJSON(data, {
style: function (feature) {
return {
color: feature.properties.strokeColor,
fillOpacity: 0
};
},
pane: "warnPane",
onEachFeature: function (feature, layer) {
var popupText = '<div>'
+ '<span style="float: right; cursor: pointer; cursor: hand"</i></span><br>'
+ '<b>LAYER: </b>' + layer.feature.properties.LayerId + '<br>'
+ '<b>TYPE: </b>' + layer.feature.properties.InfoboxTitle + '<br>'
+ '<b>STATION:</b>' + layer.feature.properties.Station + '<br>'
+ '<b>START: </b>' + layer.feature.properties.StartDateTime + '<br>'
+ '<b>END: </b>' + layer.feature.properties.EndDateTime + '<br>';
layer.bindPopup(popupText);
layer._leaflet_id = feature.properties.LayerId;
if (feature.properties.LayerId == "0") { layer0.addLayer(layer); }
else if (feature.properties.LayerId == "1") { layer1.addLayer(layer); }
else if (feature.properties.LayerId == "2") { layer2.addLayer(layer); }
else if (feature.properties.LayerId == "3") { layer3.addLayer(layer); }
else if (feature.properties.LayerId == "4") { layer4.addLayer(layer); }
else if (feature.properties.LayerId == "5") { layer5.addLayer(layer); }
else if (feature.properties.LayerId == "6") { layer6.addLayer(layer); }
else if (feature.properties.LayerId == "7") { layer7.addLayer(layer); }
else if (feature.properties.LayerId == "8") { layer8.addLayer(layer); }
else if (feature.properties.LayerId == "9") { layer9.addLayer(layer); }
else if (feature.properties.LayerId == "10") { layer10.addLayer(layer); }
else if (feature.properties.LayerId == "11") { layer11.addLayer(layer); }
},
filter: function (feature, layer) {
return (
feature.properties.Identifier === WarnFilter.tornado ||
feature.properties.Identifier === WarnFilter.svr ||
feature.properties.Identifier === WarnFilter.flood
)
},
interactive: true
});
}).fail(function (err) { console.log('createWarningsErr: ', err); })
};
//**********//
function isActive(layer) {
if (layer == "TOR") { return tornadoActive; }
else if (layer == "SVR") { return tstrmActive; }
else if (layer == "FFW") { return ffwActive; }
}
var isAnyActive = function () { return tornadoActive || svrActive || ffwActive; }
var toggleLayer = function (layer, checkState) {
switch (layer) {
case "TOR": (checkState) ? WarnFilter.tornado = 'TOR' : WarnFilter.tornado = null; tornadoActive = !tornadoActive;
break;
case "SVR": (checkState) ? WarnFilter.svr = 'SVR' : WarnFilter.svr = null; svrActive = !svrActive;
break;
case "FFW": (checkState) ? WarnFilter.flood = 'FFW' : WarnFilter.flood = null; ffwActive = !ffwActive;
break;
default:
if (checkState) {
for (key in WarnFilter) {
if (WarnFilter.hasOwnProperty(key)) {
debugger
WarnFilter[key] = (key.toString()).toUpperCase();
}
}
}
//set all values in filter themselves to show
else {
for (key in WarnFilter) {
if (WarnFilter.hasOwnProperty(key)) {
WarnFilter[key] = null;
}
}
}
break;
}
showHide(layer, checkState);
}
//**********//
var showHide = function (layer, checkState) {
rerender();
if (isAnyActive() && checkState) {
warnConditionsLayersGroup[GlobalMapLoop.getLoopIndex()].addTo(getMap());
}
else {
warnConditionsLayersGroup[GlobalMapLoop.getLoopIndex()].removeLayer(getMap());
}
}
var loop = function (currentIndex, pastIndex) {
console.log("got to warn loop", currentIndex, pastIndex, isAnyActive())
if (isAnyActive()) {
getMap().removeLayer(warnConditionsLayersGroup[pastIndex]);
getMap().addLayer(warnConditionsLayersGroup[currentIndex]);
}
}
var rerender = (function () {
init();
})
return {
init: init,
toggleLayer: toggleLayer,
loop: loop,
rerender: rerender
};
})();

Hosting a Forge Autodesk viewer on Github

I've an issue with the Forge viewer I'm developping : Im' trying to host it using Github-page, but it doesn't seem to work correctly.
The issue is on the File tree : when I load the viewer page from the Github pages, the file tree seems stuck on "Loading...". However, it correctly loads when I load the page from localhost.
The code of the File tree :
$(document).ready(function () {
prepareAppBucketTree();
$('#refreshBuckets').click(function () {
$('#appBuckets').jstree(true).refresh();
});
$('#createNewBucket').click(function () {
createNewBucket();
});
$('#createBucketModal').on('shown.bs.modal', function () {
$("#newBucketKey").focus();
})
$('#hiddenUploadField').change(function () {
var node = $('#appBuckets').jstree(true).get_selected(true)[0];
var _this = this;
if (_this.files.length == 0) return;
var file = _this.files[0];
switch (node.type) {
case 'bucket':
var formData = new FormData();
formData.append('fileToUpload', file);
formData.append('bucketKey', node.id);
$.ajax({
url: '/api/forge/oss/objects',
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
$('#appBuckets').jstree(true).refresh_node(node);
_this.value = '';
}
});
break;
}
});
});
function createNewBucket() {
var bucketKey = $('#newBucketKey').val();
var policyKey = $('#newBucketPolicyKey').val();
console.log(bucketKey)
jQuery.post({
url: '/api/forge/oss/buckets',
contentType: 'application/json',
data: JSON.stringify({ 'bucketKey': bucketKey, 'policyKey': policyKey }),
success: function (res) {
$('#appBuckets').jstree(true).refresh();
$('#createBucketModal').modal('toggle');
},
error: function (err) {
if (err.status == 409)
alert('Bucket already exists - 409: Duplicated')
console.log(err);
}
});
}
function prepareAppBucketTree() {
$('#appBuckets').jstree({
'core': {
'themes': { "icons": true },
'data': {
"url": '/api/forge/oss/buckets',
"dataType": "json",
'multiple': false,
"data": function (node) {
return { "id": node.id };
}
}
},
'types': {
'default': {
'icon': 'glyphicon glyphicon-question-sign'
},
'#': {
'icon': 'glyphicon glyphicon-cloud'
},
'bucket': {
'icon': 'glyphicon glyphicon-folder-open'
},
'object': {
'icon': 'glyphicon glyphicon-file'
}
},
"plugins": ["types", "state", "sort", "contextmenu"],
contextmenu: { items: autodeskCustomMenu }
}).on('loaded.jstree', function () {
$('#appBuckets').jstree('open_all');
}).bind("activate_node.jstree", function (evt, data) {
if (data != null && data.node != null && data.node.type == 'object') {
// $("#MyViewerDiv").empty();
var urn = data.node.id;
getForgeToken(function (access_token) {
jQuery.ajax({
url: 'https://developer.api.autodesk.com/modelderivative/v2/designdata/' + urn + '/manifest',
headers: { 'Authorization': 'Bearer ' + access_token },
success: function (res) {
if (res.status === 'success') callByUrn('urn:'+urn);
else $("#MyViewerDiv").html('The translation job still running: ' + res.progress + '. Please try again in a moment.');
},
error: function (err) {
var msgButton = 'This file is not translated yet! ' +
'<button class="btn btn-xs btn-info" onclick="translateObject()"><span class="glyphicon glyphicon-eye-open"></span> ' +
'Start translation</button>'
$("#MyViewerDiv").html(msgButton);
}
});
})
}
});
}
function autodeskCustomMenu(autodeskNode) {
var items;
switch (autodeskNode.type) {
case "bucket":
items = {
uploadFile: {
label: "Upload file",
action: function () {
uploadFile();
},
icon: 'glyphicon glyphicon-cloud-upload'
}
};
break;
case "object":
items = {
translateFile: {
label: "Translate",
action: function () {
var treeNode = $('#appBuckets').jstree(true).get_selected(true)[0];
translateObject(treeNode);
},
icon: 'glyphicon glyphicon-eye-open'
}
};
break;
}
return items;
}
function uploadFile() {
$('#hiddenUploadField').click();
}
function translateObject(node) {
$("#MyViewerDiv").empty();
if (node == null) node = $('#appBuckets').jstree(true).get_selected(true)[0];
var bucketKey = node.parents[0];
var objectKey = node.id;
jQuery.post({
url: '/api/forge/modelderivative/jobs',
contentType: 'application/json',
data: JSON.stringify({ 'bucketKey': bucketKey, 'objectName': objectKey }),
success: function (res) {
$("#MyViewerDiv").html('Translation started! Please try again in a moment.');
},
});
}
Please note that Github Pages are used for serving static pages without any special server-side logic. Your Forge application requires a server to talk to as well, for example, to obtain a list of buckets for the tree view (by making a request to /api/forge/oss/buckets).
You could potentially host your application's server-side logic on something like Heroku, and then have your static HTML/CSS/JavaScript page on Github talk to that server (for example, https://my-forge-app.herokuapp.com/api/forge/oss/buckets). Just be careful about CORS.

Why are so many documents getting fetched in Meteor?

My application is fetching a huge number of documents from the server in Meteor. I've tried optimizing the Live Query to reduce this, but I'm still getting several thousand documents per hour when the collection.find().count() is just 13.
Subscription:
Template.calendar.onCreated( function() {
var self = this;
self.ready = new ReactiveVar();
PostSubs = new SubsManager();
self.autorun(function() {
var handle = PostSubs.subscribe('meals');
self.ready.set(handle.ready());
});
});
Publication:
Meteor.publish('meals', function() {
return Meals.find({
userId : this.userId,
start : {
$gte : moment().subtract(2, 'w').format("YYYY-MM-DD"),
$lte : moment().add(2,'w').format("YYYY-MM-DD")
}
});
return this.ready();
});
Usage in context:
Template.calendar.onRendered(() => {
$( '#meals-calendar' ).fullCalendar({
defaultView: 'basicWeek',
firstDay: 1,
height: 200,
editable: true,
events( start, end, timezone, callback ) {
let data = Meals.find().fetch().map( ( event ) => {
return event;
});
if ( data ) {
callback( data );
}
},
eventRender( event, element ) {
element.find( '.fc-content' ).html(
`<strong>${ event.title }</strong>`
);
},
dayClick( date ) {
Session.set( 'eventModal', { type: 'add', date: date.format() } );
$( '#add-edit-event-modal' ).modal( 'show' );
$('#title').focus();
},
eventClick( event ) {
Session.set( 'eventModal', { type: 'edit', event: event._id } );
$( '#add-edit-event-modal' ).modal( 'show' );
},
eventDrop( event, delta, revert ) {
let date = event.start.format();
let update = {
_id: event._id,
start: date
};
Meteor.call( 'editEvent', update, ( error ) => {
if ( error ) {
Bert.alert( error.reason, 'danger' );
}
});
},
});
Tracker.autorun( () => {
Meals.find().fetch();
$( '#meals-calendar' ).fullCalendar( 'refetchEvents' );
});
});

Datatables with Jeditable, how do I setup initially in edit mode? (or always be in edit mode)

Is it possible to have the Jeditable field start off in edit mode when using the datatables plugin?
Jeditable website says the solution (not using thru Datatables) :
You can trigger the used event when your document loads. For example:
$(function() {
$("#editable").trigger("click");
How do I access it in datatables, here's my code:
var oTable;
$(function () {
oTable = $('#calendarTable').dataTable({
"bPaginate": false,
"bSort": false,
"bFilter": false,
"bInfo": false,
"aoColumns": [
null,
null,
null,
null,
{ "bVisible": false },
{ "bVisible": false },
{ "bVisible": false },
{ "bVisible": false },
{ "bVisible": false },
{ "bVisible": false },
{ "bVisible": false },
{ "bVisible": false },
{ "bVisible": false },
{ "bVisible": true }
]
});
//$("#editable").trigger("click");
// oTable.fnGetNodes()).editable.trigger("click");
oTable.editable("disable");
var year;
var lobid;
var officeid;
year = $('#hv_year').val();
lobid = $('#hv_lob').val();
officeid = $('#hv_office').val();
var url;
url = "save.asp";
url = url + "?year=" + year;
url = url + "&lobid=" + lobid;
url = url + "&officeid=" + officeid;
/* Apply the jEditable handlers to the table */
$('td:eq(4)', oTable.fnGetNodes()).editable(url, {
"callback": function (sValue, y) {
var aPos = oTable.fnGetPosition(this);
oTable.fnUpdate(sValue, aPos[0], aPos[1]);
},
"submitdata": function (value, settings) {
return {
"row_id": this.parentNode.getAttribute('id'),
"column": oTable.fnGetPosition(this)[2]
};
},
tooltip: 'Click to Edit',
height: "40px",
type: 'textarea',
onblur: 'ignore',
cancel: 'Cancel',
submit: 'Save',
indicator: '<img src="images/loader.gif">'
});
I think you can just chain the click:
$('td:eq(4)', oTable.fnGetNodes()).editable(url, {
"callback": function (sValue, y) {
var aPos = oTable.fnGetPosition(this);
oTable.fnUpdate(sValue, aPos[0], aPos[1]);
},
"submitdata": function (value, settings) {
return {
"row_id": this.parentNode.getAttribute('id'),
"column": oTable.fnGetPosition(this)[2]
};
},
tooltip: 'Click to Edit',
height: "40px",
type: 'textarea',
onblur: 'ignore',
cancel: 'Cancel',
submit: 'Save',
indicator: '<img src="images/loader.gif">'
}).trigger("click");