AutoForm with Meteor – Check validity of entire form? - meteor

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

Related

Meteor Flow Router issue with update

I have a Meteor app and I'm transitioning from IronRouter to FlowRouter. So far so good, but there are aspects I don't understand yet.
I have a route as follows:
FlowRouter.route('/documents/:docId/edit', {
name: 'documentEdit',
subscriptions: function (params, queryParams) {
this.register('documentEdit', Meteor.subscribe('documentSingle', params.docId));
},
action: function (params, queryParams) {
BlazeLayout.render('layout', { top: 'header', main: 'documentEdit' });
},
});
First option:
Then I also have a template:
<template name="documentEdit">
<div class="container">
<h1>Edit document</h1>
{{#if isReady 'documentEdit'}}
{{#autoForm collection="Documents" doc=this id="documentForm" type="update" meteormethod="documentUpdateMethod"}}
<fieldset>
{{> afQuickField name='title'}}
{{> afQuickField name='content' rows=6}}
</fieldset>
<button type="submit" class="btn btn-primary">Update</button>
<a class="btn btn-link" role="button" href="{{pathFor 'documentsList'}}">Back</a>
{{/autoForm}}
{{/if}}
</div>
</template>
with a template helper as follows:
Template.documentEdit.helpers({
isReady: function(sub) {
if(sub) {
return FlowRouter.subsReady(sub);
} else {
return FlowRouter.subsReady();
}
}
});
This is as it is mentioned here, but I'm not getting the values pre-filled in the textboxes on the UI (which is normal when editing fields).
Second option:
When I do the following it works and I don't really understand why it works (found it browsing in different forums and tried it out):
<template name="documentEdit">
<div class="container">
<h1>Edit document</h1>
{{#with getDocument }}
{{#autoForm collection="Documents" doc=this id="documentForm" type="update" meteormethod="documentUpdateMethod"}}
<fieldset>
{{> afQuickField name='title'}}
{{> afQuickField name='content' rows=6}}
</fieldset>
<button type="submit" class="btn btn-primary">Update</button>
<a class="btn btn-link" role="button" href="{{pathFor 'documentsList'}}">Back</a>
{{/autoForm}}
{{/with}}
</div>
</template>
and the helper:
Template.documentEdit.helpers({
getDocument: function () {
return Documents.findOne();
}
});
So the questions are:
for the 1st option: any idea why it does not work. I would prefer that one as it's the documented way of doing things
for the 2nd option: not sure why I need (in the template helper) to do a Document.findOne() without even having to pass the id of the doc I want to edit:
You want to do template level subscriptions with Flow Router, that's one of the primary pattern changes.
So you'd do:
Setup the subscription at the template level. Autorun so it'll resubscribe on route changes.
Template.documentEdit.onCreated(function() {
var self = this;
this.autorun(function() {
var docId = FlowRouter.getParam('docId');
self.subscribe('documentSingle', docId));
};
};
Setup the template helper to pick up from the route, and grab the id and populate the helper/document.
Template.documentEdit.helpers({
getDocument: function () {
var docId = FlowRouter.getParam('docId');
var doc = Documents.findOne(docId) || {};
return doc;
}
});
Do a template level load check and if it's there render it, otherwise show loading...
<template name="documentEdit">
<div class="container">
<h1>Edit document</h1>
{{#if Template.subscriptionReady}}
{{#with getDocument }}
{{#autoForm collection="Documents" doc=this id="documentForm" type="update" meteormethod="documentUpdateMethod"}}
<fieldset>
{{> afQuickField name='title'}}
{{> afQuickField name='content' rows=6}}
</fieldset>
<button type="submit" class="btn btn-primary">Update</button>
<a class="btn btn-link" role="button" href="{{pathFor 'documentsList'}}">Back</a>
{{/autoForm}}
{{/with}}
{{else}}
Loading...
{{/if}}
</div>
</template>
Not knowing how this worked, seeing that all the tutorials I have read that deals with update used Iron router, I have spent 7 days worth of trying retrying, looking through others code, reading tutorials. Happy it now works.

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}}

meteor autoform _id field

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}}

Meteor get ID of template parent

I have two Collection : a collection A which include array of B ids.
Template A :
<template name="templateA">
Name : {{name}} - {{_id}}
{{#each allBsOfThisA}}
{{> Bdetail}}
{{/each}}
Add B for this A
</template>
Note : in this templateA, I list all A and their detail informations. At bottom of the A, I putted a link to add a B.
Template of Bsubmit :
<div class="form-group {{errorClass 'nameOfB'}}">
<label class="control-label" for="nameOfB">nameOfB</label>
<div class="controls">
<input name="nameOfB" id="nameOfB" type="text" value="" placeholder="nameOfB" class="form-control"/>
<span class="help-block">{{errorMessage 'nameOfB'}}</span>
</div>
</div>
<input type="submit" value="Submit" class="btn btn-primary"/>
On the Bsubmit script : I want to get the ID of A. I tried with template.data._id but it's not working :
Template.Bsubmit.events({'submit form': function(e, template) {
e.preventDefault();
console.log("template.data._id: " + template.data._id);
var B = {
name: $(e.target).find('[name=name]').val(),
AId : template.data._id
};
}
});
EDIT :
BSubmit's iron-router part :
Router.route('Bsubmit ', {name: 'Bsubmit '});
Neither the template nor the route does know about the A-instance of the other template/route.
So one solution would be to pass the id to the route, which allows you to fetch the instance or use the id directly:
Template:
<template name="templateA">
Name : {{name}} - {{_id}}
{{#each allBsOfThisA}}
{{> Bdetail}}
{{/each}}
Add B for this A
</template>
Route:
More information about passing arguments to a route
Router.route('/Bsubmit/:_id', function () {
var a = A.findOne({_id: this.params._id});
this.render('Bsubmit', {data: a});
});
Then you could use template.data._id in the event.
Another solution would be to embed the form into the other view, so you can access the data of the parent template in there (documentation of parentData).

show checkbox value checked/unchecked from mongo data in meteor

i have created collection named as "tbl_dynamic" in that a field named "dynamicField" created in that i'm storing data like this
"_id":"LoBTiSo3oqr54Ac5R",
"text":"test",
"dynamicField" : {
"text1" : {
"checkedValue" : false
},
"text2" : {
"checkedValue : true
}
}
and in meteor side i have a template like this
<template name="tmpChecked">
<input id="newField" name="field" type="text" placeholder="Field" readonly="readonly" class="form-control" value={{key}}>
<div class="checkbox">
<label>
<input id="chkChecked" type="checkbox" name="chk_checked" checked={{checkedValue}}>
</label>
</div>
</template>
and my helper contains following code to fetch data from collection
//helper to view fields
Template.tmpChecked.helpers({
values: function() {
return tbl_dynamic.find({},{dynamicField:1,text:1});
}
});
now the problem is when i tried to display checkbox value it doesn't show me the checkedValue.
any suggestion ?
Thanks,
I understand that you want to show list of checkboxes and each checkbox followed by input box.
For this, You need to do following 2 things -
Change the data model little bit. Make the dynamicField properties as the array. Each array element containing information about field name and checked property
{
"_id":"LoBTiSo3oqr54Ac5R",
"text":"test",
"dynamicField" : [
{
"name": "text1",
"checkedValue" : false
},
{
"name": "text2",
"checkedValue : true
}
]
}
2.In template code, iterate over objects dynamicFields array and display them
<template name="tmpChecked">
{{#with values}}
{{ #each dynamicField}}
<input id="newField" name="field" type="text" placeholder="Field" readonly="readonly" class="form-control" value={{name}}>
<div class="checkbox">
<label>
<input id="chkChecked" type="checkbox" name="chk_checked" checked={{checkedValue}}>
</label>
</div>
{{/each}}
{{/with}}
</template>
You can keep helper function as it is. No need to change.
Hope this helps

Resources