meteor autoform _id field - meteor

I have this Schema :
Schemas = {};
Schemas.Id = {
type: String,
optional: true,
label: 'Id',
//max: ID_LENGTH,
defaultValue : Random.id(ID_LENGTH),
denyUpdate: true
};
Schemas.Name = {
type: String,
label: 'Name',
max: 75
};
Schemas.Description = {
type: String,
label: 'Description',
max: 500,
optional: true,
autoform: {
rows: 5
}
};
//-- Attribute
Schemas.Attribute = {
_id: Schemas.Id,
attribute_name : Schemas.Name,
attribute_description : Schemas.Description
};
Collections.Attributes.attachSchema(Schemas.Attribute);
i have a request from client they can insert _id manually.
but autoform cant permit it,
this the template :
<template name="pg_attr_insert">
{{#autoForm _id="afInsertDemo" type="insert" collection=Collections.Attributes}}
<div class="form-group {{#if afFieldIsInvalid name='_id'}}has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name='_id'}}</label>
{{> afFieldInput name='_id'}}
{{#if afFieldIsInvalid name='_id'}}
<span class="help-block">{{{afFieldMessattribute_description name='_id'}}}</span>
{{/if}}
</div>
<div class="form-group {{#if afFieldIsInvalid name='attribute_name'}}has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name='attribute_name'}}</label>
{{> afFieldInput name='attribute_name'}}
{{#if afFieldIsInvalid name='attribute_name'}}
<span class="help-block">{{{afFieldMessattribute_description name='attribute_name'}}}</span>
{{/if}}
</div>
<div class="form-group {{#if afFieldIsInvalid name='attribute_description'}}has-error{{/if}}">
<label class="control-label">{{afFieldLabelText name='attribute_description'}}</label>
{{> afFieldInput name='attribute_description'}}
{{#if afFieldIsInvalid name='attribute_description'}}
<span class="help-block">{{{afFieldMessattribute_description name='attribute_description'}}}</span>
{{/if}}
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add Person</button>
<button type="reset" class="btn btn-default">Reset Form</button>
</div>
{{/autoForm}}
</template>
this is the error :
Uncaught Error: Every autoForm and quickForm must have an "id"
attribute set to a unique string.
is there anyway autoform permit insert _id manually? and how?

Oke i know my false, i create
{{#autoForm _id="afInsertDemo" type="insert" collection=Collections.Attributes}}
i just convert it to :
{{#autoForm id="afInsertDemo" type="insert" collection=Collections.Attributes}}

Related

MeteorJS update AutoForm not loading doc

I have a template with an update Autoform:
<template name = "editLocationPage">
<div class="flow-text">
{{#if Template.subscriptionsReady}}
<div>
<br>
{{#autoForm collection="Locations" doc=currentDoc id="editLocationPage" type="update"}}
<fieldset>
{{testDoc}}
<legend>Edit Location / Asset</legend>
{{> afQuickField name='id'}}
{{> afQuickField name='text'}}
{{> afQuickField name='description' rows=3}}
{{> afQuickField name='type'}}
{{> afQuickField name='parent'}}
</fieldset>
<button type="submit" class="btn waves-effect waves-light">Submit</button>
<button type="reset" class="btn waves-effect waves-light red">Reset</button>
{{/autoForm}}
</div>
{{/if}}
</div>
</template>
Some helpers to subscribe and pass the doc to the template:
Template.editLocationPage.onCreated(function() {
var self = this;
self.autorun(function() {
self.subscribe('singleLocation', Session.get("idTreeView").toString());
});
});
Template.editLocationPage.helpers({
currentDoc: function() {
return Locations.find({"id":Session.get("idTreeView").toString()}).fetch()[0];
}
});
A schema:
// Data subset subscribed to on client
Meteor.publish('locations', function() {
return Locations.find({}, {fields: {
text: true,
id: true,
type:true,
parent:true
}});
});
Meteor.publish('singleLocation', function(locationId) {
return Locations.find({id:locationId});
});
The document is ok (findOne returns a valid doc) but the form does not work. Any ideas?
I just found the problem. I needed to add the schema:
{{#autoForm schema=locationFormSchema id="editLocationPage" type="update" collection=Locations doc=currentDoc}}
with a helper:
Template.editLocationPage.helpers({
currentDoc: function() {
return Locations.findOne({"id":Session.get("idTreeView").toString()});
},
locationFormSchema: function() {
return Schema.locations;
}
});

meteoric autoform select-radio does not work

The field does not exists in the Schema of form,
i am using ionic template in form, this code does not work to me:
Template.example.helpers({
cardOptions: [
{ value: 0, label:'Visa' },
{ value: 1, label:'MasterCard' },
{ value: 2, label:'Elo' },
{ value: 3, label:'Hipercard' },
{ value: 4, label:'Hiper' }
]
});
<template name="example">
{{> afQuickField name="payment.card" type="select-radio" options=cardOptions }}
</template>
You need to use the autoForm component if you want to define fields individually.
For example:
<template name="example">
{{#autoForm collection="Payments" id="insertPaymentForm" type="insert"}}
<fieldset>
<legend>Add a Payment Method</legend>
{{> afQuickField name='title'}}
{{> afQuickField name="card" type="select-radio" options=cardOptions }}
</fieldset>
<button type="submit" class="btn btn-primary">Insert</button>
{{/autoForm}}
</template>
Here is a MeteorPad.

AutoForm with Meteor – Check validity of entire form?

I'm trying to make some helpers in the template where my AutoForm form lives to change some elements out side of the form to reflect errors. I've tried using
Template.signUp.helpers
isValid: ->
AutoForm.getValidationContext('signUp').isValid()
But that just returns the following error:
Exception in template helper: TypeError: Cannot read property '_resolvedSchema' of undefined
Here's the template:
<template name="signUp">
{{#if isValid}} do something {{/if}}
{{#autoForm id="signUp" schema="Schemas.SignUp" type="normal"}}
<div class="input {{#if afFieldIsInvalid name='firstName'}}error{{/if}}">
<label for="firstName">{{data.firstName}}</label>
{{> afFieldInput name="firstName" type="text"}}
</div>
<div class="input {{#if afFieldIsInvalid name='lastName'}}error{{/if}}">
<label for="lastName">{{data.lastName}}</label>
{{> afFieldInput name="lastName" type="text"}}
</div>
<div class="input {{#if afFieldIsInvalid name='email'}}error{{/if}}">
<label for="email">{{data.email}}</label>
{{> afFieldInput name="email" type="email"}}
</div>
<div class="input">
{{> afFieldInput name="optIn" type="boolean-checkbox"}}
</div>
<button type="submit" class="btn full" data-analytics='{"eventCategory":"Sign Up","eventAction":"Click","eventLabel":"{{data.submit}}"}'><span>{{data.submit}}</span></button>
{{/autoForm}}
</div>
</div>
Any help is greatly appreciated, thanks!
****UPDATE – Found Solution****
So after lots of playing I discovered that when you're trying to validate an AutoForm outside of the AutoForm context, you should use SimpleSchema to validate.
Here's where I'm defining the schema and saving the named context (coffeescript)
#Schemas = {}
#Schemas.SignUp = new SimpleSchema
firstName:
type: String
optional: false
lastName:
type: String
optional: false
email:
type: String
regEx: SimpleSchema.RegEx.Email
optional: false
optIn:
type: Boolean
label: Localization.signUp.optIn
optional: true
defaultValue: false
#SignUpForm = Schemas.SignUp.namedContext('signUp')
And here is where I'm using SimpleSchema to validate the entire form.
Template.signUp.helpers
isValid: ->
SignUpForm.isValid()
sds

PickAdate not working with autoform materialize

i get the below error when trying to use PickAdate with gildaspk:autoform-materialize version :0.0.7
here's my schema field :
when: {
type: Date,
autoform: {
type: 'pickadate'
}
here's my form declaration :
{{#autoForm id="addEvents" collection="Events" type="insert"}}
{{> afFieldInput name='when' type="pickadate"}}
<div>
<button type="submit">Submit</button>
</div>
{{/autoForm}}

Autoform: How to dynamically show and add fields of a sub-schema depending on another field?

What is the best approach to dynamically show fields of a sub-schema (Object) depending on another field?
In the following example a document (Schemas.Main) can include several items defined in Schemas.Items. The fields that are needed to fill in items are dependendent on the selected type.
For example if a user selects type=="type1", fields "type1_field1" and "type1_field2" need to be filled.
A solution probably needs to use autoForm and combine AutoForm.getFieldValue and setting fields of an afArrayField, correct? I have tried a lot of combinations but either the ability to add additional items is lost (missing plus-sign) or I cannot add different items (i.e. all items are type1). Any hints how to solve this?
//Schemas.js
Schemas = {}; Collections = {};
Main = Collections.Main = new Mongo.Collection("Main");
Main.attachSchema(Schemas.Main);
Meteor.isClient && Template.registerHelper("Schemas", Schemas);
Schemas.Main = new SimpleSchema({
name: {
type: String
},
items: {
type: [Schemas.Items]
}
});
Schemas.Items = new SimpleSchema({
type: { //FormActions...
type: String,
allowedValues: ['type1', 'type2', 'type3'],
autoform: {
type: "selectize"
}
},
type1_field1: {
type: String
},
type1_field2: {
type: String
},
type2_field1: {
type: String
},
type2_field2: {
type: String
},
type3_field1: {
type: String
},
type3_field2: {
type: String
}
});
//form.html
{{#autoForm id="testForm" type="insert" collection=Collections.Main}}
{{> afFieldInput name='name'}}
{{> afArrayField name='items' fields="items.$.type, items.$.type1_field1"}} //How to set these fields dynamically depending on type?
<div class="form-group">
<button type="submit" class="btn btn-primary">Create</button>
</div>
{{/autoForm}}
I finally used another approach and created an own template based on afArrayField, which uses
{{> UI.dynamic template=currentFieldValue}}
Not sure if this is the best approach but seems to be working for my situation:
Template.registerHelper("currentFieldValue", function() {
return AutoForm.getFieldValue("testForm", this.current.type) || "no type so far";
});
{{#autoForm id="testForm" type="insert" collection=Collections.Main}}
{{> afFieldInput name='name'}}
{{> afArrayField name='items' id="something" template="mycustom"}}
<div class="form-group">
<button type="submit" class="btn btn-primary">Create</button>
</div>
{{/autoForm}}
<template name="afArrayField_mycustom">
<div class="panel panel-default">
<div class="panel-heading">{{afFieldLabelText name=this.atts.name}}</div>
{{#if afFieldIsInvalid name=this.atts.name}}
<div class="panel-body has-error">
<span class="help-block">{{{afFieldMessage name=this.atts.name}}}</span>
</div>
{{/if}}
<ul class="list-group">
{{#afEachArrayItem name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
<li class="list-group-item autoform-array-item">
<div>
<div class="autoform-remove-item-wrap">
{{#if afArrayFieldHasMoreThanMinimum name=../atts.name minCount=../atts.minCount maxCount=../atts.maxCount}}
<button type="button" class="btn btn-primary autoform-remove-item"><span class="glyphicon glyphicon-minus"></span>
</button>
{{/if}}
</div>
<div class="autoform-array-item-body">
<!--all actions have a type -->
{{> afFieldInput name=this.current.type label=false options="auto"}}
<!--branch here for other fields that depend on type -->
{{> UI.dynamic template=currentFieldValue}}
</div>
</div>
</li>
{{/afEachArrayItem}}
{{#if afArrayFieldHasLessThanMaximum name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
<li class="list-group-item">
<button type="button" class="btn btn-primary autoform-add-item" data-autoform-field="{{this.atts.name}}" data-autoform-minCount="{{this.atts.minCount}}" data-autoform-maxCount="{{this.atts.maxCount}}"><span class="glyphicon glyphicon-plus"></span>
</button>
</li>
{{/if}}
</ul>
</div>
</template>
<template name="type1">
<!--include type1 fields here-->
</template>
<template name="type2">
<!--include type2 fields here-->
</template>
<template name="type3">
<!--include type3 fields here-->
</template>
Based on Miriam's answer, I would also like to share what i did to get things working. May be it could benifit.
Schemas -> actions
Schemas.actions = new SimpleSchema({
actions : {
type : Array,
optional: false,
minCount: 1,
autoform: {
name: "actions"
}
},
"actions.$" : {
type: Object
},
"actions.$.action_type": {
type : String,
optional: false,
label : "Action Type",
autoform: {
type : "select",
class : "action_type form-control",
name : "action_type",
label : "Select type of action",
options: function()
{
let returnValue = [
{label: "Action 1", value: "action_1"},
{label: "Action 2", value: "action_2"},
];
return returnValue;
}
}
},
"actions.$.action_1" : {
type : Schemas.action1,
minCount: 1,
optional: true,
label : "Action 1",
}
});
Schemas -> action1
Schemas.action1 = new SimpleSchema({
"action1_to" : {
type : String,
optional: false,
label : "Email To",
autoform: {
type : "text",
label : "Email To",
placeholder: "Comma seperated values...",
class : "form-control"
}
},
"action1_cc" : {
type : String,
optional: true,
label : "Email Cc",
autoform: {
type : "text",
label : "Email Cc",
placeholder: "Comma seperated values...",
class : "form-control"
}
},
"action1_subject": {
type : String,
optional: false,
label : "Subject",
autoform: {
type : "text",
label : "Subject",
placeholder: "Subject for the Email",
class : "form-control"
}
},
"action1_body" : {
type : String,
optional: false,
label : "Email Content",
autoform: {
label : "Email Content",
rows : 6,
class : "form-control auto-size",
placeholder: "Email Content goes here...",
style : "font-size: 120%;"
}
}
});
Please note that Schemas.action1 should be loaded before Schemas.actions else you would only have a textbox rendered instead of the form
Templates
<template name="actions">
{{#autoForm id="actions-form" doc=step.data schema=schema}}
{{> afArrayField name="actions" template="actions" step=step}}
{{> wizardButtons}}
{{/autoForm}}
</template>
<template name="afArrayField_actions">
<div class="panel panel-default">
<div class="panel-heading">{{afFieldLabelText name=this.atts.name}}</div>
{{#if afFieldIsInvalid name=this.atts.name}}
<div class="panel-body has-error">
<span class="help-block">{{{afFieldMessage name=this.atts.name}}}</span>
</div>
{{/if}}
<ul class="list-group">
{{#afEachArrayItem name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
<li class="list-group-item autoform-array-item">
<div>
<div class="autoform-remove-item-wrap">
{{#if afArrayFieldHasMoreThanMinimum name=../atts.name minCount=../atts.minCount maxCount=../atts.maxCount}}
<button type="button" class="btn btn-primary autoform-remove-item"><span
class="glyphicon glyphicon-minus"></span></button>
{{/if}}
</div>
<div class="autoform-array-item-body">
{{> afQuickField name=this.current.action_type label=false options=actionOptions}}
{{> UI.dynamic template=currentFieldValue data=this }}
</div>
</div>
</li>
{{/afEachArrayItem}}
{{#if afArrayFieldHasLessThanMaximum name=this.atts.name minCount=this.atts.minCount maxCount=this.atts.maxCount}}
<li class="list-group-item">
<button type="button" class="btn btn-primary autoform-add-item"
data-autoform-field="{{this.atts.name}}" data-autoform-minCount="{{this.atts.minCount}}"
data-autoform-maxCount="{{this.atts.maxCount}}"><span
class="glyphicon glyphicon-plus"></span></button>
</li>
{{/if}}
</ul>
</div>
</template>
<template name="action_1">
{{> afQuickField name=this.current.action_1 }}
</template>
You would see {{> wizardButtons}} in the template which is because I am using the form-wizard package
and a Template.registerHelper for currentFieldValue helper
Template.registerHelper("currentFieldValue", function()
{
let val = AutoForm.getFieldValue(this.current.action_type, "actions-form");
return val || null;
});
Hope this helps some-one and saves time.
Thanks Mariam for this solution

Resources