I have a checkbox that needs to show/hide another input box. I'm doing the following:
Schema:
isFlexibleTime:
type: Boolean
label: 'Is the start time flexible?'
flexibleTimeDetails:
type: String
label: 'Flexible time details'
optional: true
Template:
+afQuickField(name='isFlexibleTime')
if afFieldValueIs name='isFlexibleTime' value=true
+afQuickField(name='flexibleTimeDetails')
The helper will trigger one time and show the other field but it won't trigger again. Any help into what is wrong would be much appreciated.
EDIT
Actually on further inspection it seems there is currently a bug with the checkbox event as of AutoForm 5.1.2 https://github.com/aldeed/meteor-autoform/issues/861
The issue has been open a little while, so you can use a quick workaround like:
In your template event:
'click [name=isFlexibleTime]': function() {
Session.set('isFlexibleTime', AutoForm.getFieldValue('isFlexibleTime','ID_OF_YOUR_AUTOFORM'));
}
Template helper:
isChecked: function() {
return Session.get('isFlexibleTime');
}
then:
{{#if isChecked}}
{{> afQuickField name="flexibleTimeDetails"}}
{{/if}}
I'm not sure if that's your actual syntax but following the example from: http://autoform.meteor.com/fieldvalues it should look like this:
{{> afQuickField name="isFlexibleTime"}}
{{#if afFieldValueIs name="isFlexibleTime" value="true"}}
{{> afQuickField name="flexibleTimeDetails"}}
{{/if}}
Related
I'm using Meteor in combination with autoForm / quickForm. I have on collection, lets call it "Sports" for this example. The collection asks the question which sports the user has done this week using a dropdown (allowedValues in autoForm). Now if the user selects running, I want to show 'distance', 'area', etc. If the user selects basketball, I might want to show 'shots taken', etc.
How should I go about this? Create multiple Collections or SimpleSchema's, or is there a different preferred approach? Could not find anything on Google, though I am sure this is not an uncommon question. If anyone has a link with more info that is already very much appreciated.
Update:
I am using an 'each' loop to loop through all possible sports I have defined earlier. Do you think it would make more sense to create a form item for each different sport? If so, how can I make sure this is correctly configured in the schema? Thank you in advance!
{{#autoForm collection="Sports" type="update" doc=this id="FieldValueIsForm"}}
{{#each sports}}
<h3>{{this.name}}</h3>
{{> afQuickField name="sports.$.sportTrue" noselect=true }}
{{#if afFieldValueIs name="sports.$.sportTrue" value=true}}
{{> afQuickField name="sports.$.sportDistance" value=this.frequency}}
{{/if}}
{{/each}}
<div>
<button type="submit">Submit</button>
</div>
{{/autoForm}}
Update 2:
My schema can be found here: http://pastebin.com/SbBSbqW2
I simplified it a bit, but this is the main content. For different sports I would need different input fields.
Sounds like you want to use the afQuickField option with a conditional. The documentation talks about it here. There is also a demo of what the code should look like here; however, it looks like this:
{{#autoForm collection="FieldValueIs" type="insert" id="FieldValueIsForm"}}
{{> afQuickField name="a" options="allowed" noselect=true}}
{{#if afFieldValueIs name="a" value="foo"}}
{{> afQuickField name="b"}}
{{/if}}
{{/autoForm}}
You would just need to make sure you set up "a" and "b" to be the select fields you want by setting them up properly in your schema.
UPDATE:
I assume you want to store the distance, shots taken, etc. in the SingleSport collection. Exactly how you store it is up to you, but it could look something like the following:
SingleSport = new SimpleSchema({
sportType: {
type: String
},
distanceRun: {
type: Number,
decimal: true,
optional: true
},
shotsTaken: {
type: Number,
optional: true
},
sportTrue: {
type: Boolean,
label: "Sport completed",
autoform:{
type: "boolean-radios",
trueLabel: "Enabled",
falseLabel: "Disabled",
value: false
}
}
});
Then, you could change the conditional section of your form like so:
{{#if afFieldValueIs name="sportType" value="running"}}
{{> afQuickField name="distanceRun"}}
{{/if}}
{{#if afFieldValueIs name="sportType" value="basketball"}}
{{> afQuickField name="shotsTaken"}}
{{/if}}
I have this in my routes:
Router.map(function() {
...
this.route('studentEdit', {
path: '/student/:_id/edit',
data: function() {
return Students.findOne(this.params._id);
},
});
this.route('studentDetail', {
path: '/student/:_id',
data: function() {
return Students.findOne(this.params._id);
}
});
...
});
And I have this in my template using autoform:
{{#autoForm collection="Students" id="studentEdit" doc=this type="update"}}
{{> afQuickField name='name'}}
{{> afQuickField name='phone'}}
{{> afQuickField name='address' rows=6}}
{{> afQuickField name='remarks' rows=6}}
<button type="submit" class="btn waves-effect waves-light"><i class="material-icons">save</i></button>
{{/autoForm}}
The edit page loads fine, with the prepopulated fields. And when I save, it does save, yet, it doesn't redirect to the detail page, and returns this error in console:
Exception in delivering result of invoking '/students/update': Error: Missing required parameters on path "/student/:_id". The missing params are: ["_id"]. The params object passed in was: {}.
UPDATE
Routing to the detail page now works, yet the error still exist in the console. I must be missing something. This is what I've done to get it working for the time being:
var moveOnRouter = {
onSuccess: function(formType, result) {
Router.go('studentDetail', {_id: this.docId});
}
}
AutoForm.addHooks('studentEdit', moveOnRouter);
You need to explicitly go to the other route on submit from your form. But since your button is a submit you also need to prevent the default submit action.
With template events you'd do something like:
Template.myTemplate.events({
'submit .btn'(ev) {
ev.preventDefault();
router.go('studentDetail',{ _id: this.docId });
}
});
But since you're hooking autoform perhaps it's easier just to remove the type="submit" from your button definition.
Template works fine (in terms of data being displayed), but event doesn't. Particularly odd because I have a different template with almost the identical code in which it works.
<template name="profile_sidebar">
{{#if opened}}
{{> profile_sidebar_contents}}
{{/if}}
</template>
<template name="profile_sidebar_contents">
{{#if dataReady}}
{{#unless equalsCurrentUsername profile.login}}
<span>
<a class="message-user"><i class="ion-chatbox"></i> Message</a>
</span>
{{/unless}}
{{/if}}
</template>
Template.profile_sidebar_contents.events({
'click .message-user': function(e,t){
// this is {}
// t.data is null
Session.set('selectedConversation', this._id);
Router.go('/messages');
}
});
Thank you!
Found a solution!
I wrapped the entire template in a {{#with profile}} ... {{/with}} block and then added the data I needed to be within the profile object returned in the helper. It seems as though the context of the event was empty object because the event target was not within a scope.
Elaborated below
I assumed that the context would default to an object which had as fields all helpers. Ex. I had
Template.profile_sidebar_contents.helpers({
profile: function(){ return something },
id: function() {return somethingelse }
});
and I expected the context of this to be {profile: something, id: somethingelse}
but it seems that this isn't done and the context is empty. I moved it to be
Template.profile_sidebar_contents.helpers({
profile: function(){ return {profile:something, id:somethingelse} }
});
and then set {{#with profile}} ... {{/with}} and had access to the profile helper returned object, by which I could retrieve id by this.id and profile by this.profile
I am trying to insert various templates depending on which button is clicked. For this I created an event that sets a session variable with the id of the button.
'click .task-option-button': function (e) {
var template = e.target.id;
Session.set('addTaskTemplate', template);
console.log(template);
}
and a helper that returns the session variable
addTaskTemplate: function () {
var taskTemplate = Session.get('addTaskTemplate');
return taskTemplate;
},
and then the template gets inserted like this
{{> Template.dynamic template= "{{addTaskTemplate}}"" }}
However, clicking the button doesn't add the template. When I put
{{> Template.dynamic template= "SomeStaticTemplate" }}
it works. Also using {{addTaskTemplate}} as a normal variable in <p></p> tags works and returns the id of the button as a string. Is there anything I am missing here?
{{> Template.dynamic template= addTaskTemplate }} will do. Just remove the {{ }} brackets.
I've got some linked schemas and am trying to access properties of a subschema from the form for the primary schema. It's a mouthful, I know. Code may help:
//js
Collection = new Meteor.Collection('collection');
Schemas = {};
Schemas.secondary = new SimpleSchema({
unitType: {
type: String,
autoform: {
type: 'select',
options: //function with all the options
}
}
});
Schemas.primary= new SimpleSchema({
name: {
type: String,
},
units: {
type: [ Schemas.secondary ]
}
});
Collection.attachSchema(Schemas.primary);
//HTML
{{#autoForm collection="Collection" id="someId" type="insert"}}
{{> afQuickField name='name'}} // this works
{{> afQuickField name='units'}} // this works
{{> afQuickField name='units.unitType'}} // this doesn't work :-(
{{/autoForm}}
The reason I'm doing this is because there are other properties in the secondary schema that I want to show conditionally, based on the value of the select box. I also tried to put a form inside a form and then run {{#each afFieldNames name='"units"}} but that didn't quite work either. Instead of giving me just the fields contained in units (i.e., the secondary schema), it looped through all fields of both primary and secondary.
Thoughts? I'm not married to this pattern but I can't think of another way.
Thanks again, all.
db
I had this issue myself.
Give this a go
{{> afQuickField scope='units.unitType' name='units.unitType'}}
If you dump your modifier in your before submit hook you should be able to see the subdocument successfully filled out
AutoForm.hooks({
someId: {
before: {
'insert': function(modifier) {
console.log(modifier);
}
}
}
});
Let me know if this works for you!
All the best,
Elliott