Meteor multiple-select autoform - mongodb

I'm new to meteor and I have problems with the meteor autoform from aldeed/meteor-autoform
I'd like to implement a Multiple-selection box.
Exercises = new Mongo.Collection('exercises');
ExerciseSchema = new SimpleSchema({
name: {
label: "Name",
type: String
},
tags: {
label: "Tags",
type: Tags
}});
Tags = new SimpleSchema({
wow: {
type: String,
allowedValues: ['red', 'green', 'blue'],
autoform: {
options: [
{label: "Red", value: "red"},
{label: "Green", value: "green"},
{label: "Blue", value: "blue"}
]
}
}});
And in my html I insert
{{#autoForm collection="Exercises" id="insertExerciseForm" type="insert" resetOnSuccess=true}}
<div class="card-content">
{{> afQuickField name='tags.wow' type='select-multiple'}}
</div>
In the Browser it looks correct like
Multiple select box select
But when I select multiple elements and click the submit button from my Autoform, I get this error in my Browser Console:
Error in insertExerciseForm insert Error: Wow must be of type String
When I remove the type='select-multiple' from the afQuickField then I can select only one element and it works fine. But I need to select mutiple elements
Can someone help me?

I think that type: [String] instead of type: String would do the job, according to the docs: https://github.com/aldeed/meteor-simple-schema

[String] does not help.
I found it out.
Tags = new SimpleSchema({
wow: {
type: Array,
allowedValues: ['red', 'green', 'blue'],
autoform: {
options: [
{label: "Red", value: "red"},
{label: "Green", value: "green"},
{label: "Blue", value: "blue"}
]
},'wow.$': {
type: String
},
}});
but now, it just saves the value in MongoDB, how can I save label and value?

Related

MongoDB lookup to various collections based on a field value

Consider there is documents like this in DB:
{
name: 'my list',
items: [
{ type: 'book', id: 5364 },
{ type: 'car', id: 354 },
{ type: 'laptop', id: 228 }
]
}
I need to grab data of each item from its own collection, based on type value.
I searched about it but couldn't figure out the correct approach.
Expected output:
{
name: 'my list',
items: [
{ type: 'book', id: 5364, data: [{...}] },
{ type: 'car', id: 354, data: [{...}] },
{ type: 'laptop', id: 228, data: [{...}] }
]
}
Mongoose schema of first collection (above):
{
name: String,
items: {
type: Array,
default: []
}
}
And other collections that must be looked up has corresponding _id field.
There are a few different ways to do this. To be most similar to what you have currently, you just need to make one small change. type is a keyword in Mongoose, so if you want to have a field in your schema which is actually called "type", you need to use the word twice. Once for the Mongoose keyword and again to define your schema.
{
name: String,
items: [{
type: { type: String},
id: Number,
data: []
}]
}
If the data field is coming from another collection, you could use a reference and then call populate() on your find method.
// ItemSchema
{
name: String,
items: [{
type: { type: String },
id: Number,
data: [{
type: Schema.Types.ObjectId,
ref: 'OtherSchemaName'
}]
}]
}
// Find Method with populate
const myList = await ItemSchema.find({type: "book"}).populate('data')
// Result
{
name: 'my list',
items: [
{ type: 'book', id: 5364, data: [{...}] },
]
}

Within a subDocument _id appends at last of the document, why?

Using this schema
mongoose.Schema({
world: String,
color: [{ name: String }]
});
Gives me a document that has sub-documents containing _id fields.
{ _id: 'a9ec8475bf0d285e10ca8d42'
world: 'matrix',
color: [
{ name: 'blue', _id: '4a8c0e12135fa32e13db9ce9' },
{ name: 'red', _id: '4a8c0a62254cd32e13db4ad8' },
{ name: 'white', _id: '4a8c04e2687ea32e13db1da7' }
]
Why is the _id added/appended last in the case of the subdocument?
Is there a way to keep _id first in the document?
define color as a separate schema as below, then in the main schema put color of type colorSchema
var colorSchema= mongoose.Schema({
// your subschema content
}, { _id : false });

Yadcf integrate with Meteor simple schema

I want to filter column header data from my tabular table.
My goal is to filter:
Numbers (greater than, equal etc...)
Strings
Dates
as in the following example
Thus I want to integrate the filters of yadcf with my tabular table by using the Orion schema, by I can´t conclude,
FIRST OPTION WITH SCHEMA
Mi schema
Tickets = new orion.collection('tickets', {
singularName: 'Tickets',
pluralName: 'Tickets',
title: 'Tickets',
parentPath: '/admin',
link: {title: 'Tickets', parent: '_template'},
tabular: {
scrollX: true,
"processing": true,
dom: 'lBfrtip',
columns: [
{ data: "id", title: "ID" },
{ data: 'employeeName', title: 'Name' }
]
}
});
Tickets.attachSchema(new SimpleSchema({
id: { type: Number, label:'Id del Empleado', optional: true },
employeeName: { type: String, label:'Name', optional: true }
}));
if (Meteor.isServer) {
Meteor.publish('get_Tickets', function() {return Tickets.find();});
};
if (Meteor.isClient) {
Meteor.subscribe('get_Tickets');
};
My.html
{{> tabular table=collection.tabularTable class="table table-striped bordered" id=collection.pluralName }}
SECOND OPTION WITH INSTANCE OF DATATABLE
my.js
var TicketsTab=new Tabular.Table({
name: 'Tickets',
collection: Tickets,
searching:true,
columns: [
{data: "id",title:"ID"},
{data: "employeeName",title:"Name"}
]
});
var myTable = $('#TicketsTab').DataTable();
yadcf.init(myTable, [{column_number:0}]);
In this point I can´t conclude because I don´t know how to add .dataTable().yadcf([...]);

ag-Grid, try to make Tree Demo work using own data

I like the ag-Grid because it's less buggy, fast and works with many frameworks.
So I tried the Tree Data, no need to tell the link between parents and children, simply lay down the data in structure, specify some options, Bingo! But, when I plug in my API, it tells me
"TypeError: rowData is undefined"
from inside of ag-grid.js even though Watch clearly shows it has the array. There are some answered Question here regarding customization with internal api. Mine is not.
I then use the official demo as a base, set up a Fiddler to grab the raw data in JSON replace demo data to make it hardcoded for a test to determine if it's problem with own API or something else. Here is the Plunker. Note it's totally based on the official javaScript Demo of Tree Data, Tree Data Example, the first one.
In case you don't want to see Plunker, here is my .js:
var columnDefs = [
{headerName: "Client", field: "Client", cellRenderer: 'group'},
{headerName: "Program", field: "Program"}
/*{headerName: "Group", field: "xgroup", cellRenderer: 'group'}, // cellRenderer: 'group'}, -- this "group" is one of the default value option for built-in cellRenderer function, not field.
//{headerName: "Athlete", field: "athlete"},
//{headerName: "Year", field: "year"},
{headerName: "Country", field: "country"}
*/
];
var myData = [
{
'Client': 'Goodle',
'Program': 'no grid',
'kids': []
},
{
'Client': 'Facebrook',
'Program': 'grids',
'kids': [
{
'Client': 'Facebrook',
'Program': 'ag-Grid'
},
{
'Client': 'Facebrook',
'Program': 'ui-grid'
}
]
}
/*{xgroup: 'Group A',
participants: [
/*{athlete: 'Michael Phelps', year: '2008', country: 'United States'},
{athlete: 'Michael Phelps', year: '2008', country: 'United States'},
{athlete: 'Michael Phelps', year: '2008', country: 'United States'}*/
/*]},
{xgroup: 'Group B', athlete: 'Sausage', year: 'Spaceman', country: 'Winklepicker',
participants: [
{athlete: 'Natalie Coughlin', year: '2008', country: 'United States'},
{athlete: 'Missy Franklin ', year: '2012', country: 'United States'},
{athlete: 'Ole Einar Qjorndalen', year: '2002', country: 'Norway'},
{athlete: 'Marit Bjorgen', year: '2010', country: 'Norway'},
{athlete: 'Ian Thorpe', year: '2000', country: 'Australia'}
]},
{xgroup: 'Group C',
participants: [
{athlete: 'Janica Kostelic', year: '2002', country: 'Crotia'},
{athlete: 'An Hyeon-Su', year: '2006', country: 'South Korea'}
]}*/
];
var gridOptions = {
columnDefs: columnDefs,
rowData: myData,
rowSelection: "single",
enableSorting: "true", unSortIcon: "true",
enableColResize: "true",
enableRangeSelection: "true",
suppressCellSelection: "false",
showToolPanel: "true",
supressCopyRowsToClipboard: true,
supressCellSelection: false,
getNodeChildDetails: getNodeChildDetails,
onGridReady: function(params) {
params.api.sizeColumnsToFit();
}
};
function getNodeChildDetails(rowItem) {
if (rowItem.Client) {
return {
group: true,
// open C be default
//expanded: rowItem.ClientName === 'Group C',
// provide ag-Grid with the children of this group
children: rowItem.kids,
// this is not used, however it is available to the cellRenderers,
// if you provide a custom cellRenderer, you might use it. it's more
// relavent if you are doing multi levels of groupings, not just one
// as in this example.
//field: 'group',
// the key is used by the default group cellRenderer
key: rowItem.Client
};
} else {
return null;
}
}
function onFilterChanged(value) {
gridOptions.api.setQuickFilter(value);
}
// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function() {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
});
HTML:
<html>
<head>
<!-- you don't need ignore=notused in your code, this is just here to trick the cache -->
<script src="https://ag-grid.com/dist/ag-grid/ag-grid.js"></script>
<script src="script.js"></script>
</head>
<body>
<input placeholder="Filter..." type="text"
onpaste="onFilterChanged(this.value)"
oninput="onFilterChanged(this.value)"
onchange="onFilterChanged(this.value)"
onkeydown="onFilterChanged(this.value)"
onkeyup="onFilterChanged(this.value)"/>
<div id="myGrid" class="ag-fresh" style="height: 450px; margin-top: 4px;"></div>
</body>
</html>
Need some experts!
You need to alter getNodeChildDetails to have this:
function getNodeChildDetails(rowItem) {
if (rowItem.Client && rowItem.kids && rowItem.kids.length > 0) {
As you have it you're telling the grid that any item with Client is a parent node, but what you really mean in your data is any item with Client AND kids is a parent.
Remember that the grid can have multiple levels so a child can be a parent too.

Dojo Grid to html or report

Is there a way to get the results from a Dojo Grid to a report or PDF? Cant really find any info on that. Maybe convert the records in the Dojo Grid into HTML and then to a report?
This is what I am doing right now. Just need to figure out a way to get the results of the grid into html or some sort of report (PDF maybe)
HTML
id="gridNoColumnSets_impediments" class="gridclassGrid"
gridNoColumnSets_impediments = new (declare([Grid, Selection, ColumnSet]))({
// use Infinity so that all data is available in the grid
bufferRows: Infinity,
cellNavigation: false,
escapeHTMLInData: false,
showHeader: true,
noDataMessage: "No results for this search",
loadingMessage: "Loading data...",
selectionMode: "single",
}, "gridNoColumnSets_impediments");
gridNoColumnSets_impediments.on(".field-id:mouseover", selectStateimpediments);
var ColumnSets_impediments = [
[
[
{label: 'id', field: 'id', sortable: false},
{label: 'ID__', field: 'ID__'},
{label: 'IMPEDIMENT', field: 'IMPEDIMENT'},
{label: 'OTHER_NAME', field: 'OTHER_NAME'},
{label: 'RIVER', field: 'RIVER'},
{label: 'COUNTY', field: 'COUNTY'},
{label: 'HU_NAME', field: 'HU_NAME'},
{label: 'DAM_TYPE', field: 'DAM_TYPE'},
{label: 'OWNER', field: 'OWNER'},
{label: 'STATE_AGCY', field: 'STATE_AGCY'},
{label: 'FED_AGCY', field: 'FED_AGCY'}
]
],
];
gridNoColumnSets_impediments.set("columnSets", ColumnSets_impediments);
function updateGridimpediments(featureSet) {
var data = arrayUtils.map(featureSet.features, function (entry, i) {
return {
ID__: entry.attributes.ID__,
id: entry.attributes.OBJECTID,
IMPEDIMENT: entry.attributes.IMPEDIMENT,
OTHER_NAME: entry.attributes.OTHER_NAME,
RIVER: entry.attributes.RIVER,
COUNTY: entry.attributes.COUNTY,
HU_NAME: entry.attributes.HU_NAME,
DAM_TYPE: entry.attributes.DAM_TYPE,
OWNER: entry.attributes.OWNER,
STATE_AGCY: entry.attributes.STATE_AGCY,
FED_AGCY: entry.attributes.FED_AGCY
};
});
// If you use a store...
dataStore = new Memory({
"data": data,
"idProperty": "id"
});
gridNoColumnSets_impediments.set("store", dataStore);
gridNoColumnSets_impediments.startup();
}