I'm creating a simple dropdownbox using select tag and templates as shown below:
<template name="serviceTypes">
<select id="servicetypes">
{{#each serviceNames}}
<option>{{name}}</option>
{{/each}}
</select>
and in .js file
Template.serviceTypes.helper({
serviceNames : function () {
var names = [{name: Yoga}, {name: Dance}];
return names;
}
});
But still the dropdown seems to be empty.
{{still a newbie in meteor}}
Related
I have a Vue where the AJAX fetched select options are not available the FIRST time the Vue is rendered.
I have done as suggested here: https://v2.vuejs.org/v2/guide/list.html#Object-Change-Detection-Caveats.
The form is dynamically generated from a "schema" object.
<b-form-group v-for="(obj, key) in schema"
v-if="obj.type !== 'hidden'"
:label="createInputLabel(obj, key)" :label-for="key" >
...
<div v-else-if="obj.type == 'select'" role="group"
class="form-group">
<select v-model="attributes[key]" :id="key" :name="key"
class="custom-select">
<option v-for="option in optionsList[key]"
v-bind:value="option.value">
{{ option.text }}
</option>
</select>
</div>
...
</b-form-group>
optionsList is a keyed object containing lists of all the select elements on the form. optionsList is created by watching the "schema" object. The Rest API code is:
var idx = key;
Rest('GET', '/table/' + schema[key].table, requestParams,
this.$root.user.token)
.then(response => {
var localOptionsList = [];
response.data.forEach(function(row) {
var obj = { value: row[schema[idx].listColumns],
text: row[schema[idx].listColumns] };
localOptionsList.push(obj);
});
Vue.set(me.optionsList, idx, localOptionsList);
})
.catch(error =>
...
As mentioned, the code works fine, apart from the FIRST time the Vue is rendered.
This is obviously because the data has not yet been returned from the Rest API, so my problem is how to get the Vue to react when the data arrives?
Can anyone help?
I have a json object, let's call it teamData with Teams.
I want to be able to pass a variable such as Primary or Secondary to a call and have it render a states dropdown with the State of the TeamType selected.
I've been reading many handlebars tutorials but none of them really deal with more than one property of an object or show how to link a value from one property to another.
the states dropdown is simple
<script type="text/x-handlebars-template" id="tmpl-states">
<select>
{{#eachProperty States}}
<option name="{{property}}">{{value}}</option>
{{/eachProperty}}
</select>
</script>
Handlebars.registerHelper('eachProperty', function (context, options) {
var ret = "";
for (var prop in context) {
ret = ret + options.fn({ property: prop, value: context[prop] });
}
return ret;
});
but what I want to do is more like (in sudo)
renderTemplate("tmps-all", "container", "data", "variable");
<script type="text/x-handlebars-template" id="tmps-all">
{{#each Teams}}
{{#if TeamType == variable}} // e.g. Primary
var State = this.State;
{{/if}}
{{/each}}
<select>
{{#eachProperty States}}
{{#if property == State}} // e.g NY
<option name="{{property}}" selected>{{value}}</option>
{{/else}}
<option name="{{property}}">{{value}}</option>
{{/if}}
{{/eachProperty}}
</select>
</script>
var teamData = {"Teams":[{"TeamType":"Primary","State":"NY"},{"TeamType":"Secondary","State":"CA"}],"States":{"AK":"Alaska","AL":"Alabama","AR":"Arkansas","AZ":"Arizona","CA":"California","CO":"Colorado","CT":"Connecticut","DC":"District of Columbia","DE":"Delaware","FL":"Florida","GA":"Georgia","HI":"Hawaii","IA":"Iowa","ID":"Idaho","IL":"Illinois","IN":"Indiana","KS":"Kansas","KY":"Kentucky","LA":"Louisiana","MA":"Massachusetts","MD":"Maryland","ME":"Maine","MI":"Michigan","MN":"Minnesota","MO":"Missouri","MS":"Mississippi","MT":"Montana","NC":"North Carolina","ND":"North Dakota","NE":"Nebraska","NH":"New Hampshire","NJ":"New Jersey","NM":"New Mexico","NV":"Nevada","NY":"New York","OH":"Ohio","OK":"Oklahoma","OR":"Oregon","PA":"Pennsylvania","PR":"Puerto Rico","RI":"Rhode Island","SC":"South Carolina","SD":"South Dakota","TN":"Tennessee","TX":"Texas","UT":"Utah","VA":"Virginia","VT":"Vermont","WA":"Washington","WI":"Wisconsin","WV":"West Virginia","WY":"Wyoming"}};
There is no need for your eachProperty helper. The functionality it is giving you exists already in Handlebars. Let's remove that helper and update our template to the following (Note: I will replace the name attribute with value):
<select>
{{#each States}}
<option value="{{#key}}">{{this}}</option>
{{/each}}
</select>
Now on to the task of setting the selected attributed.
You are trying too much logic into your template. It is not for the template to initialize variables. That work should be done before the template is rendered. We want our code the calls the template method to give the template all the data it needs. This would mean passing to our template a data structure like this:
[
{
value: 'AK',
label: 'Alaska',
selected: false
},
{
value: 'AL',
label: 'Alabama',
selected: false
},
// and so on...
]
Our code will do the work of building this data structure:
var selected_team = teamData.Teams.find(team => team.TeamType === 'Primary');
var states = Object.keys(teamData.States).map(key => ({
value: key,
label: teamData.States[key],
selected: (key === selected_team.State)
}));
Now we can modify our template to handle our new data structure:
<select>
{{#each this}}
<option value="{{value}}" {{#if selected}}selected{{/if}}>{{label}}</option>
{{/each}}
</select>
When we call our template, we simply pass in our states variable:
renderTemplate(states);
However:
With all of that work behind us, I want to add that I see no purpose in re-rendering this template just to reflect a changed selected option. It makes more sense to me to use the DOM to make the change. Something like the following would suffice:
document.querySelector('#Select [value="NY"]').selected = true;
See: https://stackoverflow.com/a/7373115/3397771
I am new to Meteor but acquired some fair knowledge of this framework. I am creating one App in which I have to Build a Category Management Module, I am using a Category collection for this and in the document my values are like this
{
_id:
name:
parentID:
.....
}
I have tried few things to make it recursive, but failed to do it, what I need is a drop down which contains all the categories with their children. like this:
http://blog.digibali.com/wp-content/uploads/2011/03/menutree2.jpg
I would appreciate if anyone here can help in this issue:
Right Now what I am doing is fetching me to only 2 levels, I mean Top Parent and a Sub Child, I want unlimited levels for this, I know it might be possible through recursive function, but unable to find the way
Template:
<template name="categoryselect">
<select id="category" name="category" class="category">
<option value="">--Select--</option>
{{#each get_categories}}
<option value="{{_id}}">{{name}}</option>
{{#each get_sub_categories}}
{{> subcategoryselect}}
{{/each}}
{{/each}}
</select>
</template>
<template name="subcategoryselect">
<option value="{{_id}}">--{{name}}</option>
</template>
Template Helpers :
Template.categoryselect.helpers({
'get_categories': function(){
return Categories.find({parentID:''});
},
'get_sub_categories': function(){
return Categories.find({parentID:this._id});
}
});
Here's a tested solution:
html
<template name="categoryselect">
<select id="category" name="category" class="category">
<option value="">--Select--</option>
{{#each get_categories}}
<option value="{{_id}}">{{name}}</option>
{{/each}}
</select>
</template>
js
Template.categoryselect.helpers({
get_categories: function() {
var results = [];
var mapChildren = function(category, level) {
// add the appropriate number of dashes before each name
var prefix = Array(2 * level).join('--');
results.push({_id: category._id, name: prefix + category.name});
// repeat for each child category
var children = Categories.find({parentID: category._id}).fetch();
_.each(children, function(c) {
// make sure to increment the level for the correct prefix
mapChildren(c, level + 1);
});
};
// map each of the root categories - I'm unsure if the parent
// selector is correct or if it should be {parentId: {$exists: false}}
_.each(Categories.find({parentID: ''}).fetch(), function(c) {
mapChildren(c, 0);
});
// results should be an array of objects like {_id: String, name: String}
return results;
}
});
I have the following HTML code:
<select id="select_opt" class="form-control">
{{# each manageprofile_data}}
<option>{{Usergroup}}</option>
{{/each}}
</select>
and its corresponding JS event helper in meteorjs as:
'change #select_opt': function(event){
var select_data = [];
var val = $('#select_opt option:selected').val();
select_data.push(val);
console.log(select_data);
}
I want to push each selected option in the select_data array but it is only inserting a single element all the times and not saving all the elements.
on clicking each select option the value of the selected option must be saved in the array like ["ROOT", "ADMINISTRATOR", "ROOT"...]
but currently I am getting: ["ROOT"], ["ADMINISTRATION"] on clicking each option.
Just put your array outside of the function, like this:
var select_data = [];
'change #select_opt': function(event){
var val = $('#select_opt option:selected').val();
select_data.push(val);
console.log(select_data);
}
It seems that you are using backbone.js. You only have to make your select_data global. Inside your view add below line
select_data : [],
Trying to dynamically create a select input with options from a json array of objects.
The JSON array of objects looks like this:
var curr_sel = [
{v:"1", n:"USD"},
{v:"2", n:"GBP"},
{v:"3", n:"CAD"},
{v:"4", n:"AUD"},
{v:"5", n:"EUR"}
];
And my view template has the following:
<select>
{{#each opt in curr_sel}}
<option value="{{ opt.v }}" >{{ opt.n }}</option>
{{/each}}
</select>
But that produces a select element with no options. Kindly help. Even better if it means using the EmberJS select class http://emberjs.com/api/classes/Ember.Select.html
The better way to use the select tag is using Ember.Select.
Here is a sample:
Template
<script type="text/x-handlebars" data-template-name="application">
{{view Ember.Select content=curr_sel
optionLabelPath="content.n"
optionValuePath="content.v"
selection=selectedCurrency}}
</script>
Javascript
App = Ember.Application.create({});
App.ApplicationController = Ember.Controller.extend({
curr_sel: [
{v:"1", n:"USD"},
{v:"2", n:"GBP"},
{v:"3", n:"CAD"},
{v:"4", n:"AUD"},
{v:"5", n:"EUR"}
],
selectedCurrency: null,
selectedCurrencyChanged: function() {
console.log(this.get('selectedCurrency.n'));
}.observes('selectedCurrency')
});
Give a look in this fiddle to see this in action http://jsfiddle.net/marciojunior/FJkEr/