问题
I've been trawling SO questions for an answer to something that should be very simple but for the life of me I cannot figure it out.
Basically I have a meteor-autoform with two select controls:
<template name="processFormTemplate">
{{#autoForm id="processForm" collection="Processes" type=formAction doc=doc validation="blur"}}
<div class="col-md-12">
{{> afQuickField name="elementId" options=elements}}
{{> afQuickField name="categoryId" options=categories}}
{{> afQuickField name="title"}}
{{> afQuickField name="desc" rows=4}}
</div>
{{>formButtons}}
{{/autoForm}}
</template>
These then have helpers to populate the options:
Template.processFormTemplate.helpers({
elements: function() {
return getFormElements();
},
categories: function(elementId) {
return getFormCategories(this.doc.elementId);
}
});
lib/methods.js
getFormElements = function() {
var options = [];
Elements.find({}, {sort: {ref:1}}).forEach(function (element) {
options.push({
label: element.title, value: element._id
});
});
return options;
};
getFormCategories = function(elementId) {
var options = [];
var filter = {};
if (!isBlank(elementId)) {
filter.elementId = elementId;
}
Categories.find(filter, {sort: {ref:1}}).forEach(function (d) {
options.push({
label: d.title, value: d._id
});
});
return options;
};
Now I know this isn't working because the helper isn't reactive, however I don't know how to change this behaviour. I've also tried hooking into the 'change' event but this never fires for some reason:
Template.processFormTemplate.events({
'change #elementId': function(e) {
console.log($('[name="elementId"]').val() + ' is now selected');
}
});
The required behaviour is that when a new elementId is selected in the first list, the list of options in the second should be refreshed based on the selected elementId.
Any help much appreciated.
Thanks, David
回答1:
I had the same problem before that took me hours to resolve. You have to use simple schema to get the value of selected option like this using autoform's api call Autoform.getFieldValue:
Schemas.Store = new SimpleSchema({
center: {
type: String,
optional: true,
autoform: {
type: "select",
options: function () {
return Centers.find().map(function (c) {
return {label: c.name, value: c._id};
});
}
}
},
region: {
type: String,
optional: true,
autoform: {
type: "select",
options: function () {
if (Meteor.isClient) {
var docId = '';
docId = AutoForm.getFieldValue('storesForm', 'center');
return Regions.find({center: docId}).map(function (c) {
return {label: c.name + ' (' + c.code + ')', value: c._id};
});
}
}
}
},
store_name: {
type: String
}
});
BTW, I'm still using autoform@4.2.2 due to issues encountered when using Autoform.getFieldValue in 5.0
Issue in 5.0.3 I've reported to aldeed: https://github.com/aldeed/meteor-autoform/issues/785#issuecomment-84600515
回答2:
I've managed to get this working - couple of things were wrong:
I needed to add an 'id' to the first select control so i could capture it's change event:
{{> afQuickField name="elementId" id="elementId" options=elements}}
I then used a Reactive Dict variable which I then set in the changed event. A session variable would probably do the same job.
Template.processFormTemplate.events({
'change #elementId': function() {
dict.set('activeElementId', $('select#elementId').val());
}
});
and use this as a parameter in my categories helper:
categories: function(elementId) {
return getFormCategories(dict.get('activeElementId'));
}
Hopefully this helps anyone else having a similar issue.
来源:https://stackoverflow.com/questions/28685163/meteor-autoform-how-to-update-select-options-based-on-another-control