I'm using the Meteor autoform select2 package and I'm trying to figure out how to set a selected value. Currently trying the following but then I can't see the rest of the countries list
options: function () {
var user = Meteor.users.findOne();
if (user && !_.isEmpty(user.profile.country)) {
return {value: user.profile.country};
}
return countriesList;
}
You should always return label & value to selectize options
return {
value: user.profile.country ,
label:"//someName "
}
Related
I have a FullCalendar scheduler on a webapp which has 2 way databinding for resources and events, all working great. I want to be able to present the user with a dropdown that enables them to toggle the visibility of a column, ideally completely client side.
I have tried a combination of addResource / removeResource however my issue here is that a rerender of the calendar (e.g. when a new event is added) then displays the previously removed resource. I can work around this however would prefer a really simple approach using JS / CSS. I currently cannot find a way to set a resource to not be visible, or to have zero width - is this possible?
There is an easy way to do this:
Store resources in an array variable resourceData.
Create another array called visibleResourceIds to store the ids of any resources you want to show.
In the resources callback function, filter resourceData to only contain the resources where the resource id exists in visibleResourceIds. Return the filtered array and fullcalendar will only add the desired resources for you.
To remove a resource from view, simply remove the resource id from visibleResourceIds and refetchResources. To add the resource back in, add the id to visibleResourceIds and refetchResources. DONE.
JSFiddle
var resourceData = [
{id: "1", title: "R1"},
{id: "2", title: "R2"},
{id: "3", title: "R3"}
];
var visibleResourceIds = ["1", "2", "3"];
// Your button/dropdown will trigger this function. Feed it resourceId.
function toggleResource(resourceId) {
var index = visibleResourceIds.indexOf(resourceId);
if (index !== -1) {
visibleResourceIds.splice(index, 1);
} else {
visibleResourceIds.push(resourceId);
}
$('#calendar').fullCalendar('refetchResources');
}
$('#calendar').fullCalendar({
defaultView: 'agendaDay',
resources: function(callback) {
// Filter resources by whether their id is in visibleResourceIds.
var filteredResources = [];
filteredResources = resourceData.filter(function(x) {
return visibleResourceIds.indexOf(x.id) !== -1;
});
callback(filteredResources);
}
});
I had the same challenge. Instead of a dropdown, I use checkboxes, but the workings will be the same.
My resources are stored in a variable, when I uncheck a box, the resource is removed and the resource's object is added to another array with the resourceId as key, and the index added to the object to restore the object in the same column as it originally was. When re-checking the box, the object is added to the resources array and the resources refetched.
/* retrieve the resources from the server */
var planningResources;
var removedResource = [];
$.ajax({
url: '/planning/resources/',
method: 'get',
success: function (response) {
planningResources = response;
showCalendar();
}
, error: function () {
if (typeof console == "object") {
console.log(xhr.status + "," + xhr.responseText + "," + textStatus + "," + error);
}
}
});
/* create the calendar */
showCalendar = function () {
$('#calendar').fullCalendar({
...
});
}
/* checkbox on click */
$('.resource').click(function() {
var resourceId = $(this).val();
var hideResource = !$(this)[0].checked;
$('.status:checkbox:checked').each(function () {
});
if(hideResource) {
$.each(planningResources, function(index, value){
if( value && value.id == resourceId ) {
value.ndx = index;
removedResource[resourceId] = value;
planningResources.splice(index,1);
return false;
}
});
$('#planningoverview').fullCalendar(
'removeResource',
resourceId
);
}
else {
planningResources.splice(removedResource[resourceId].ndx, 0, removedResource[resourceId]);
$('#planningoverview').fullCalendar('refetchResources');
}
});
showCalendar();
It probably doesn't get first price in a beauty contest, but it works for me ...
Cheers
You can use the resourceColumns option for this. In the column objects you can set the width property to a number of pixels or a percentage. If you pass a function here you can easily handle the width property someplace else. Your hide/show function can then set the width to 0 to hide the column. After that you can trigger reinitView to update the view: $('#calendar').fullCalendar("reinitView");
I have a selectbox in template A which selects an item "name and id".
I also have an "item" template that needs an ID as parameter to load its data from its database. I am using a session variable for the id and I pass the id to the "item" template using return Session.get . This only works for on load. When the session variable change the "item" template is not updated. How do I get the "item" template to re-initialize
Some code:
Template.selectBox.helpers({
selectList: function () {
return Templates.find({}, {fields: {'_id': 1, 'name': 1}});
},
selectedId: function() {
return Session.get("selectedId");
}
});
Template.selectBox.events({
'change #item-chooser': function (event) {
var selectedId = $(event.currentTarget).find(":selected").val();
if (typeof(selectedId) === 'undefined'
|| selectedId === "new") {
Session.set("selectedId", "new");
}
else {
Session.set("selectedId", selectedId);
}
}
});
The items template is called using
{{> item selectedId}}
Template.item.onCreated(function() {
var selectedId = this.data.selectedId;
this.selectedItem = new ReactiveVar;
if (typeof(selectedId) === 'undefined'
|| selectedId === "new") {
this.selectedItem.set(emptyItem);
}
else {
var selectedItemData = Templates.findOne({_id: selectedId});
this.selectedItem.set(selectedItemData );
}
});
It's important to note that the Template.onCreated method is not reactive so if you have reactive variables, this method does not automatically re-run when a reactive data source changes unlike Template.helpers
The easiest way to fix your problem would be to use autorun
Template.item.onCreated(function(){
var self = this;
self.autorun(function(){
// some code that has a reactive data source (e.g. Session Var, Collection, or Reactive Var
// NOTE: you can access template instance data using self.data
});
});
However, based on your description, I think there could be a better way to handle your problem using Template.helpers
Template.item.helpers({
selectedItem: function(){
return Templates.findOne({_id: Session.get("selectedId")});
}
});
I've got a form created through AutoForm.
As far as data sources, I can fill in parts of the form and use:
AutoForm.getFormValues('form-id').insertDoc // returns the contents of the form
When I validate the form I can do:
var formValues = AutoForm.getFormValues('form-id').insertDoc;
var isValid = MyCollection.simpleSchema().namedContext("myContext").validate(formValues);
// if isValid returns true, then I enable the Submit button
Instead of filling in parts of the form, I want to manually add information into whatever object Autoform uses for validation and submission to a collection.
For example, there are data fields in the schema that simply don't need to appear in the form itself.
Take a shopping cart:
ShoppingCartSchema = {
totalPrice: {
type: Number,
optional: false
},
itemsSelected: {
type: [Object],
optional: false
}
};
The data for itemsSelected is obviously provided through user input on the form.
The data for totalPrice is something that should not be from a form input. It's generated in the code.
But totalPrice still needs to be validated as a required field before AutoForm submits the form to a collection.
So how do you add totalPrice onto the object that Autoform eventually validates?
You could use an autovalue if you wanted to.
ShoppingCartSchema = new SimpleSchema({
'items': {
type: [Object],
},
'items.$.name': {
type: String
},
'items.$.price': {
type: Number
},
totalPrice: {
type: Number,
autoValue: function () {
if (this.field('items').isSet) {
let total = this.field('items').value.reduce(function (sum, item) {
return sum + item.price;
}, 0);
if (this.isInsert) {
return total;
} else {
return { $set: total };
}
}
}
},
});
Autoform Hooks can help you manipulate the data before you save it into the Collection.
In your case .
AutoForm.hooks({
form-id: { // The Autoform ID
onSubmit: function (insertDoc, updateDoc, currentDoc) {
if (customHandler(insertDoc)) { // Your Logic here
this.done(); // This is Required
} else {
this.done(new Error("Submission failed"));
}
return false;
}
}
});
For More Information Please refer Autoform Readme
I'm using the following package in my project - https://github.com/matteodem/meteor-easy-search
Has anyone used it and was able to set custom mongo selectors for the query parameter? The leaderboard example isn't very clear to me. I need to be able to pass meteor user id to:
EasySearch.createSearchIndex('producers', {
'collection': Producers,
'field': ['name', 'producerIdNumber', 'blocksCount', 'totalHectares', 'totalArea'],
'limit': 8,
'use' : 'mongo-db',
'sort': function() {
return { 'created': -1, 'name': -1 };
},
'query': function() {
var selector = {};
return selector
}
});
How can pass or get the meteor user id? EasySearch.createSearchIndex function runs on both server and client.
I don't have the answer to your problem - but I may be able to point you in the right direction. If you are using the meteor-accounts package, and you need to pull the user ID out of the Meteor.users() collection - you first have to publish your users.
On the server-code ->
Meteor.publish(null, function() {
return Meteor.users.find({}, {
fields: {
username: 1,
profile: 1
}
});
});
on the client, you should be able to return Meteor.users.find() or findOne() to get a userId. not the complete answer but may help?
I was able to do this like so
'query': function(searchString, opts) {
// Default query that will be used for the mongo-db selector
var query = EasySearch.getSearcher(this.use).defaultQuery(this, searchString);
if (this.props.formName != '') {
query.formName = this.props.formName;
}
if (this.props.producerId != '') {
query.producerId = this.props.producerId;
}
if (this.props.blockUnitCodeSubCode != '') {
query.blockUnitCodeSubCode = this.props.blockUnitCodeSubCode;
}
if (this.props.created.length != 0) {
query.created = {$gte:new Date(this.props.created[0]), $lt:new Date(this.props.created[1])};
}
In my meteor app I need to change the value of an array based on the item clicked.
This is how I fetch items from db.
Template.templatename.vname = function(){
return Db.find();
}
On clicking a button I need to change the items in the array vname.
Can I do something like
'click #item1' : function()
{
Template.templatename.vname = function(){
return Db.find({id : this._id});
}
}
You could use a Session variable
Template.templatename.vname = function(){
var searchId = Session.get("searchId");
if(searchId) {
return Db.find();
}
else {
return Db.find({_id: searchId});
}
}
Then
'click #item1' : function()
{
Session.set("searchId", this._id);
}
A couple of notes
The search helper returns an array, but you're fetching a single item (_id is unique)
You would need to clear the session variable to null to show all the results again.