How to get array index of nested object in autoform? - meteor

I need to set slugs of my subcategories ,and i am using autovalue for this. I need to know the index of actual field for when i use arrays. There is a wild card for this?
Eg:
subcategories.$.subs.$.name
subcategories: {
type: [Object],
optional: true,
},
"subcategories.$.name": {
type: String,
optional: true,
},
"subcategories.$.slug": {
type: String,
optional: true,
autoform: {
omit: true
},
autoValue: function() {
if (this.field('subcategories.$.name').isSet) {
return s.slugify( (this.field('subcategories.$.name').value).toLowerCase() );
}
},
},
"subcategories.$.subs": {
type: [Object],
optional: true,
},
"subcategories.$.subs.$.name": {
type: String,
optional: true,
},
"subcategories.$.subs.$.slug": {
type: String,
optional: true,
autoform: {
omit: true
},
autoValue: function(i) {
if (this.field('subcategories.$.subs.$.name').isSet) {
return s.slugify( (this.field('subcategories.$.subs.$.name').value).toLowerCase() );
}
},
},
Thanks,

I got the expected result by changing the schema. Besides getting more organized, this.siblingField('name') works!
Code:
Categories = new Mongo.Collection('categories');
Schemas = {};
Schemas.Subs = new SimpleSchema({
"name": {
type: String,
optional: true,
},
"slug": {
type: String,
optional: true,
autoform: {
omit: true,
},
autoValue: function() {
if (this.siblingField('name').isSet) {
return s.slugify( (this.siblingField('name').value).toLowerCase() );
}
},
},
});
Schemas.Subcategories = new SimpleSchema({
"name": {
type: String,
optional: true,
},
"slug": {
type: String,
optional: true,
autoform: {
omit: true,
},
autoValue: function() {
if (this.siblingField('name').isSet) {
return s.slugify( (this.siblingField('name').value).toLowerCase() );
}
},
},
"subs": {
type: [Schemas.Subs],
optional: true,
},
});
Schemas.Categories = new SimpleSchema({
name: {
type: String,
},
slug:{
type: String,
unique: true,
index: 1,
autoform: {
omit: true
},
autoValue: function() {
if (this.field('name').isSet) {
return s.slugify( (this.field('name').value).toLowerCase() );
}
},
},
subcategories: {
type: [Schemas.Subcategories],
optional: true,
},
});
Categories.attachSchema(Schemas.Categories);

Related

Kendo grid displaying multiple page

This is my code for kendo the page is displaying multiple time given in
i tried every this but its still not working please suggest me what to do to solve this problem. picture.And validation message is also not showing its validation but not displaying message
$(document).ready(function() {
$("#production-grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: {
url: "#Html.Raw(Url.Action("ProductAttributeList", "Production"))",
type: "POST",
dataType: "json",
contentType: "application/json"
},
create: {
url: "#Html.Raw(Url.Action("SettingAdd", "Production"))",
type: "POST",
dataType: "json"
//data: addAntiForgeryToken
},
update: {
url: "#Html.Raw(Url.Action("SettingUpdate", "Production"))",
type: "POST",
dataType: "json"
//data: addAntiForgeryToken
},
destroy: {
url: "#Html.Raw(Url.Action("SettingDelete", "Production"))",
type: "POST",
dataType: "json"
//data: addAntiForgeryToken
},
parameterMap: function(data, operation) {
if (operation != "read") {
return data;
} else {
//for some reasons only such "Filter" data be parsed
return JSON.stringify(data);
}
}
},
schema: {
data: "Data",
total: "Total",
errors: "Errors",
model: {
id: "Id",
fields: {
Image: { editable: false, type: "string" },
IteamId: { editable: false, type: "number" },
ProductId: { editable: false, type: "number" },
UserName: { editable: false, type: "string" },
FoundInProductName: { false: true, type: "string" },
FoundInProductDescription: { editable: false, type: "string" },
TaggedKeyword: { editable: false, type: "string" },
TaggedComment: { editable: false, type: "string" },
AttributeName: { editable: true, type: "string" },
Comment: { editable: true, type: "string" },
ShelfID: { editable: true, type: "string" },
ShelfName: { editable: true, type: "string" },
ProductType: { editable: true, type: "string",
validation: { required: true , message: "Product Type is required" } } ,
Remark: { editable: true, type: "string" },
Id: { editable: false, type: "number" }
}
}
},
requestEnd: function(e) {
if (e.type == "create" || e.type == "update") {
this.read();
}
},
error: function(e) {
display_kendoui_grid_error(e);
// Cancel the changes
this.cancelChanges();
},
pageSize: 50,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
pageable: {
refresh: true,
pageSizes:[ 50, 100, 150, 200, 250]
},
scrollable: true,
editable: true,
columns: [
{
field: "Id",
headerTemplate: "<input id='mastercheckbox' type='checkbox'/>",
headerAttributes: { style: "text-align:center" },
attributes: { style: "text-align:center" },
template: "<input type='checkbox' value='#=Id#' class='checkboxGroups'/>",
width: 50
},{
field: "Image",
title: "Image",
width: 300
},{
field: "IteamId",
title: "IteamId",
width: 300
},
{
field: "ProductId",
title: "ProductId",
width: 300
}, {
field: "UserName",
title: "UserName",
width: 300
}, {
field: "FoundInProductName",
title: "Keyword found(PN)",
width: 300
}, {
field: "FoundInProductDescription",
title: "Keyword found(PD)",
width: 300
}, {
field: "TaggedKeyword",
title: "Tagged Keyword",
width: 300
}, {
field: "TaggedComment",
title: "Tagged Comment",
width: 300
},
{
field: "AttributeName",
title: "Attribute Name(the attribute which is worked upon- E.g. Color)",
width: 300
},
{
field: "Comment",
title: "Comment",
editor: CommentTypeDropDownEditor,
template: "#:Comment#",
width: 300
},
{
field: "ShelfID",
title: "Suggested Shelf ID",
width: 300
},
{
field: "ShelfName",
title: "Suggested Shelf Name",
width: 300
},
{
field: "ProductType",
title: "Product Type",
width: 300
},
{
field: "Remark",
title: "Remarks (Free Text)",
width: 300
}
]
});
i can able to fingure out what the issue and validation message is also not displaying

Update array of objects leads to blank array

Please tell me what I'm missing here. When I update the Array of objects my collection updates with an empty array. I'm using meteor-collection2-core and node-simple-schema.
Path: Method
testArray = [{
"institution": "Swinburn",
"uniqueId": 1501036480813,
"qualification": "Bachelor of Commerce",
"completed": "2017"
}]
ProfileCandidate.update('Ntzj6kE8qZsvSPMEP', {$set: {educationQualifications: testArray}});
Path: Collection
export const ProfileCandidate = new Mongo.Collection('profileCandidate');
const ProfileCandidateSchema = new SimpleSchema({
userId: {
type: String,
regEx: SimpleSchema.RegEx.Id
},
educationQualifications: { type: Array, optional: true },
'educationQualifications.$': { type: Object, optional: true },
'educationQualifications.$.uniqueId': { type: Number, optional: true },
'educationQualifications.$.institution': { type: String, optional: true },
'educationQualifications.$.qualification': { type: String, optional: true },
'educationQualifications.$.completed': { type: String, optional: true }
});
ProfileCandidate.attachSchema(ProfileCandidateSchema);
In your method, try this:
ProfileCandidate.update({userId: 'Ntzj6kE8qZsvSPMEP'}, {$set: {educationQualifications: testArray}});

Handlebars Nested Each Statement

I am attempting nest an each statement to handle the two objects that are available within my view. There is a relationship between the two objects with the userId on the card as the connection to the userId on the user table, which might be how this could work. I figure that I might have to end up registering a helper to have this work, but I'm not sure where to start. I attempted to bypass this process with the following handlebars syntax, but I get TypeError: inverse is not a function:
{{#each this.fullNameSlug ../user.fullNameSlug}}
<h5>{{this.fullNameSlug}}</h5>
{{/each}}
Here is the full view:
{{#each card}}
<div class="row">
<div class="card col-md-6 col-md-offset-3">
<div class="card-date">
<p class="card-date">{{this.cardDateSlug}}</p>
</div>
<div class="card-header">
<h3 class="card-title">{{this.title}}</h3>
{{#each this.fullNameSlug ../user.fullNameSlug}}
<h5>{{this.fullNameSlug}}</h5>
{{/each}}
</div>
<div class="card-body">
{{/each}}
Here is the route with the two objects (card, user) that are accessible in the view:
/*==== / ====*/
appRoutes.route('/')
.get(function(req, res){
models.Card.findAll({
order: 'annotationDate DESC',
include: [{
model: models.User,
where: { organizationId: req.user.organizationId },
attributes: ['organizationId', 'userId', 'fullNameSlug']
}],
limit: limitAmount.limit
}).then(function(annotation){
res.render('pages/app/activity-feed.hbs',{
card: card,
user: req.user
});
});
})
Card object:
module.exports = function(sequelize, DataTypes) {
var path = require('path');
var moment = require('moment');
var Card = sequelize.define('card', {
cardId: {
type: DataTypes.INTEGER,
field: 'card_id',
autoIncrement: true,
primaryKey: true
},
cardDate: {
type: DataTypes.DATE,
field: 'card_date',
isDate: true
},
reportLink: {
type: DataTypes.TEXT,
field: 'report_link'
},
fileAttachment: {
type: DataTypes.STRING,
field: 'file_attachment'
},
userId: {
type: DataTypes.INTEGER,
field: 'user_id'
},
discoverySourceId: {
type: DataTypes.INTEGER,
field: 'discovery_source_id'
}
},
{
freezeTableName: true,
getterMethods: {
cardDateSlug: function(){
var date = new Date(this.getDataValue('annotationDate'));
var momentDate = moment(date).utc().format("MM/DD/YYYY");
return momentDate;
}
},
classMethods: {
associate: function(db) {
Card.belongsTo(db.User, {foreignKey: 'user_id'}),
}
}
});
return Card;
}
User object:
var bcrypt = require('bcrypt-nodejs');
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('user', {
userId: {
type: DataTypes.INTEGER,
field:'user_id',
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
},
email: {
type: DataTypes.STRING,
isEmail: true,
unique: true,
set: function(val) {
this.setDataValue('email', val.toLowerCase());
}
},
password: DataTypes.STRING,
organizationId: {
type: DataTypes.INTEGER,
field: 'organization_id',
allowNull: true
},
authenticationToken: {
type: DataTypes.STRING,
field: 'authentication_token'
},
resetPasswordToken: {
type: DataTypes.STRING,
field: 'reset_password_token'
},
resetPasswordExpires: {
type: DataTypes.DATE,
field: 'reset_password_expires'
}
}, {
freezeTableName: true,
getterMethods: {
fullNameSlug: function(){
var fullName = this.getDataValue('firstName') + ' ' + this.getDataValue('lastName');
return fullName;
}
},
classMethods: {
associate: function(db) {
User.belongsToMany(db.Organization, { through: 'member', foreignKey: 'user_id'})
},
generateHash: function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
},
},
instanceMethods: {
validPassword: function(password) {
return bcrypt.compareSync(password, this.password);
},
},
});
return User;
}

Googleplace not saving to collection

I'm currently using lukemadera:autoform-googleplace to save the users address. When the user saves their address it only saves the fullAddress field in the schema. I thought it broke the address up into its parts; street, state, zip etc. That way you could publish the address parts individually if required. I would like to be able to publish just the state in certain circumstances but I'm not sure how to do that since all I have is a fullAddress field string. Let me know if you need more clarification.
Path: address.js
Template.address.helpers({
optsGoogleplace: function() {
return {
// type: 'googleUI',
// stopTimeoutOnKeyup: false,
googleOptions: {
componentRestrictions: { country:'au' }
}
}
},
});
Path: address.html
{{#autoForm collection="Meteor.users" id="user" doc=currentUser type="update"}}
{{> afQuickField name="profile.address" type="googleplace" opts=optsGoogleplace class="form-control"}}
{{autoForm}}
Path: Schema.js
Schema.Address = new SimpleSchema({
fullAddress: {
type: String
},
lat: {
type: Number,
decimal: true
},
lng: {
type: Number,
decimal: true
},
geometry: {
type: Object,
blackbox: true
},
placeId: {
type: String
},
street: {
type: String,
max: 100
},
city: {
type: String,
max: 50
},
state: {
type: String,
regEx: /^A[LKSZRAEP]|C[AOT]|D[EC]|F[LM]|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEHINOPST]|N[CDEHJMVY]|O[HKR]|P[ARW]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY]$/
},
zip: {
type: String,
regEx: /^[0-9]{5}$/
},
country: {
type: String
}
});
If you have it set up correctly, something like this should work:
Schemas = {};
Schemas.Address = new SimpleSchema({
fullAddress: {
type: String
},
lat: {
type: Number,
decimal: true
},
lng: {
type: Number,
decimal: true
},
geometry: {
type: Object,
blackbox: true
},
placeId: {
type: String
},
street: {
type: String,
max: 100
},
city: {
type: String,
max: 50
},
state: {
type: String,
},
zip: {
type: String,
},
country: {
type: String
},
});
Schemas.MainSchema = new SimpleSchema({
address: {
type: Schemas.Address,
optional: true
}
});
MainSchema = new Mongo.Collection("MainSchema");
MainSchema.attachSchema(Schemas.MainSchema);
MainSchema.allow({
insert: function () { return true; },
update: function () { return true; },
remove: function () { return true; }
});
Maybe check these out:
https://github.com/lukemadera/meteor-autoform-googleplace/issues/24
https://github.com/lukemadera/meteor-autoform-googleplace/issues/25
http://www.curtismlarson.com/blog/2015/12/11/meteor-location-search-engine-mongodb-google-maps/
My only other guess is something is wrong with you google options helper. I'm not using that right now and the above setup works for me.

Meteor collection2 not updating

I'm having some trouble with updating a user account. I use the following schema (collection2):
lib/collections/users.js
Users = Meteor.users;
var Schemas = {};
Schemas.User = new SimpleSchema({
gender: {
type: Number,
min: 1
},
s_gender: {
type: Number,
min: 1,
optional:false
},
picture: {
type: String,
custom: function() {
var base64Matcher = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");
var value = this.value.replace("data:image/png;base64,","");
if(!base64Matcher.test(value))
{
return 'no picture';
}
else
{
return true;
}
}
}
});
Users.attachSchema(Schemas.User);
Now I do the update with the following code:
client/templates/start.js
Users.update({_id: Meteor.userId()}, {
$set: {picture: picture, gender: gender, s_gender: s_gender}
}, {validationContext: "updateUser"}, function (error, result) {
if (error) {
errorObjs = Users.simpleSchema().namedContext("updateUser").invalidKeys();
console.log(errorObjs);
}
console.log(result);
});
The validation passes, but I only get a "0" in results (errors are null) - the update isn't working. Errors are shown if I have an empty field, so the validation is working well. If I detach the schema, the update works fine.
Did I forget something here or why isn't he updating when validation passes?
// Edit: Also I see, that Meteor doesn't create users anymore.
I believe you need to use Users.profile.foo instead of Users.foo, because Users is a special meteor collection and you can only save new fields inside the profile field. Try using Simple Schema/Collection 2 suggested User schema as a starting point (I'll copy it bellow). Notice the "profile schema" is loaded before the user schema:
Schema = {};
Schema.UserProfile = new SimpleSchema({
firstName: {
type: String,
regEx: /^[a-zA-Z-]{2,25}$/,
optional: true
},
lastName: {
type: String,
regEx: /^[a-zA-Z]{2,25}$/,
optional: true
},
birthday: {
type: Date,
optional: true
},
gender: {
type: String,
allowedValues: ['Male', 'Female'],
optional: true
},
organization : {
type: String,
regEx: /^[a-z0-9A-z .]{3,30}$/,
optional: true
},
website: {
type: String,
regEx: SimpleSchema.RegEx.Url,
optional: true
},
bio: {
type: String,
optional: true
}
});
Schema.User = new SimpleSchema({
username: {
type: String,
regEx: /^[a-z0-9A-Z_]{3,15}$/
},
emails: {
type: [Object],
optional: true
},
"emails.$.address": {
type: String,
regEx: SimpleSchema.RegEx.Email
},
"emails.$.verified": {
type: Boolean
},
createdAt: {
type: Date
},
profile: {
type: Schema.UserProfile,
optional: true
},
services: {
type: Object,
optional: true,
blackbox: true
}
});
Meteor.users.attachSchema(Schema.User);
source: https://github.com/aldeed/meteor-collection2

Resources