Reputation: 1334
I have a number of 'multiple' selectors, but for the sake of this example, let's say I have two.
<form class="input-field col s10">
<select multiple id="jans-room21">
<option value="" disabled selected>Add Names</option>
{{#each Jans21}}
<option value= '{{FullName}}' selected = {{formatSelectedNames21 RoomJans}} >{{FullName}}</option>
{{/each}}
</select>
</form>
<form class="input-field col s10">
<select multiple id="jans-room22">
<option value="" disabled selected>Add Names</option>
{{#each Jans22}}
<option value='{{FullName}}' selected = {{formatSelectedNames22 RoomJans}}>{{FullName}}</option>
{{/each}}
</select>
</form>
Jans21 and Jans22 are returning a number of documents from the DB. They'll display the selected names for that room, or those that have no 'RoomJans' property or have a 'RoomJans' equal to ''. They will exclude those names that were chosen in the other selector.
Template.jansNameSelect.helpers({
Jans21: function () {
return Programs.find({ $and: [{ CampYear: Session.get('GlobalCurrentCampYear') }, { $or: [{ RoomJans: '' }, { RoomJans: { $exists: 0 }}, { RoomJans: { $in: ['21A', '21B'] }}]}]}, { sort: { FullName: 1 }}).fetch();
},
Jans22: function () {
return Programs.find({ $and: [{ CampYear: Session.get('GlobalCurrentCampYear') }, { $or: [{ RoomJans: '' }, { RoomJans: { $exists: 0 }}, { RoomJans: { $in: ['22A', '22B'] }}]}]}, { sort: { FullName: 1 }}).fetch();
}
});
When a button is clicked, a method is called to update the DB and store those names.
// ...
$('#room_21_jans_button').on('click', function() {
var roomValue = $('input[name="room_select_21_jans"]:checked').val();
if (roomValue) {
var selectedValues = [];
$r21jans.find("option:selected").each(function () {
selectedValues.push($(this).val());
});
selectedValues.splice(0, 1);
var unselectedValues = [];
$r21jans.find("option:not(:selected)").each(function () {
unselectedValues.push($(this).val());
});
Meteor.call('roomUpdateSN',
selectedValues,
unselectedValues,
roomValue,
Session.get('GlobalCurrentCampYear')
);
//...
What I'm after is when names are selected in the first selector, and subsequently saved to the database, the second selector will update its list of names to remove those names that were selected from the first. I had thought that this would be reactive since I am performing a database action, such that the 'Jans22' function would fire again if names were chosen from the first selector and saved to the DB. But it isn't. It will, however, load the right names on a refresh. Is there a way to get this to be reactive?
Upvotes: 0
Views: 41
Reputation: 6097
When using a UI component framework on top of Meteor templates, you need to tell the framework when the template underneath it has changed. This is because the framework (materialize in this case) uses the <select>
rendered by the template as an input, and then creates a new set of DOM elements to render the desired UI look-and-feel. If the <option>
's change, you need to tell the framework to re-run this process.
In this case you need to re-run the
$('select').material_select();
every time there is a change. The easiest way to do this in my opinion is using a deferred function from the helper itself:
Template.jansNameSelect.helpers({
Jans21: function () {
Meteor.defer( function() { $('select#jans-room21').material_select(); } );
return Programs.find({ $and: [{ CampYear: Session.get('GlobalCurrentCampYear') }, { $or: [{ RoomJans: '' }, { RoomJans: { $exists: 0 }}, { RoomJans: { $in: ['21A', '21B'] }}]}]}, { sort: { FullName: 1 }}).fetch();
},
Jans22: function () {
Meteor.defer( function() { $('select#jans-room22').material_select(); } );
return Programs.find({ $and: [{ CampYear: Session.get('GlobalCurrentCampYear') }, { $or: [{ RoomJans: '' }, { RoomJans: { $exists: 0 }}, { RoomJans: { $in: ['22A', '22B'] }}]}]}, { sort: { FullName: 1 }}).fetch();
}
});
Upvotes: 1