Ember js iterating through a json array of objects to create elements - javascript

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/

Related

Angularjs - Get other properties of selected object on ng-change outside ng-repeat

I am fairly new to Angularjs and I have come across a situation that no other questions seem to quite answer.
this is my view
<select id = "nameField" class = "form-control" ng-model = "name" ng-change = "fillDataType(userDefinedVariable)">
<option ng-repeat = "userDefinedVariable in userDefinedWorkflowVariables">{{userDefinedVariable.name}}</option>
</select>
This is my controller
$scope.userDefinedVariables = [{name:"object1",dataType:"number",description:"description1"},
{name:"object2",dataType:"number",description:"description2"}]
$scope.fillDataType = function(userDefinedVariable) {
console.log(userDefinedVariable) //undefined
var dataType = userDefinedVariable.dataType; //not working
}
Is there a way i can pass "userDefinedVariable" object to my fillDataTypefunction as a parameter.
As a workaround, I am passing the ng-model(name) as a parameter to my fillDataType function and in that function Iam looping through userDefinedVariables to match the selected name, hence retrieving the object.
Is there no way I can access an object outside the ng-repeat scope? Or am I doing something wrong here.
No you can not use variable in ng-repeat outside of it.
But here there is another way to access selected object.You might want to take a look at ng-options directive.
You can replace code for looping by this
<select ng-options="userDefinedVariable as userDefinedVariable.name for userDefinedVariable in userDefinedWorkflowVariables" ng-model="name"></select>
Then in in you will get complete object in name instead of just label.
Please run and check if it is working, if not I will try to create working code.
In your case, you can select whole object in ng-model instead of single name property of object userDefinedVariables. Try following code..
<select ng-model="selectedName" ng-options="item as item.name for item in userDefinedWorkflowVariables" ng-change = "fillDataType(selectedName)">
</select>
use ng-options
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<select id="nameField" class="form-control" ng-model="selectedOption" ng-change="fillDataType()" ng-options="obj.name for obj in userDefinedWorkflowVariables">
</select>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.selectedOption={};
$scope.userDefinedWorkflowVariables = [{name:"object1",dataType:"number",description:"description1"},
{name:"object2",dataType:"number",description:"description2"}]
$scope.selectedOption =$scope.userDefinedWorkflowVariables[0]
$scope.fillDataType = function() {
console.log( $scope.selectedOption)
var dataType = $scope.selectedOption.dataType;
}
});
</script>
</body>
</html>

Angular 1.5 "track by" ruines binding in ng-options

I need to select option in combobox from ajax loaded data. That data comes as list of objects. The problem is that ng-option compares objects by reference and thus setting model to objects element results in appearing new empty option in combobox instead of selecting correct option.
The known workaround is to use track by expression.
And here is example code:
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.roles =[
{ key:"administrator", value:"ROLE_ADMIN" },
{ key:"operator", value:"ROLE_OPERATOR" },
];
// this emulates data from server
// won't work without 'track by'
$scope.role={ key:"administrator", value:"ROLE_ADMIN" };
});
Template:
<body ng-app="myApp" ng-controller="myCtrl">
0: <input ng-model="roles[0].key" />
<br>
1: <input ng-model="roles[1].key" />
<br>
select role: <select ng-model="role" ng-options="r.key for r in roles track by r.value">
</select>
<pre>selected role={{role|json}}</pre>
</body>
Here another problem arises. When one selects role in combobox and then
changes it's "key" property in textbox, then selected role stays unchanged. So it looks like binding is suddenly gets broken.
https://jsfiddle.net/xLqackxw/8/
from Angular documentation https://docs.angularjs.org/api/ng/directive/ngOptions
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
So:
<select ng-model="role" ng-options="r as r.key for r in roles track by r.value"></select>
'$scope.role' value will be object like { key:"administrator", value:"ROLE_ADMIN" } or { key:"operator", value:"ROLE_OPERATOR" }

handlebars with two different sets of properties. helper or partial?

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

angularjs JSON object filter select option

I'm having trouble with filtering JSON entries by defined categories with a select option element. Any help is much appreciated.
What my App should do:
Load JSON data from file by http.get (working)
The JSON data contains a job title and a job category (and other data) for each entry
Read each of these entries from JSON into a list-tag on html (working)
filter this list by a job category by a select option element (not working)
I guess the problem lies somewhere in my controller function. But I'm quite new to angularjs so I couldn't find out what the problem is... Any help is much appreciated.
first two entries of my JSON file with the tag "categories" in it:
[{
"jobtitle":"Multimedia Producer",
"name":"A. Text",
"shortname":"atext",
"shortdescription":"Werbeagentur",
"team":"XXX",
"lookingfor":"XXX",
"jobdescription":"XXX",
"portfolio":"XXX",
"contact":"XXX" ,
"categories":"none"
},
{
"jobtitle":"Kameraassistent",
"name":"Movie & Art",
"shortname":"movie_art",
"shortdescription":"Corporate Movies and more...",
"team":"XXX",
"lookingfor":"XXX",
"jobdescription":"XXX",
"portfolio":"XXX",
"contact":"XXX",
"categories":"photography"
}]
The controller.js:
var myApp = angular.module('myApp', []);
myApp.controller('MyController', ['$scope', '$http', function ($scope, $http){
$http.get('js/data.json').success(function(data){
$scope.jobs = data;
$scope.catchange = 'categories'
});
}]);
Part of the HTML-page setup with the select option element:
<div ng-controller="MyController">
<span class="input">
<select ng-model="catchange" class="cs-select cs-skin-underline">
<option value="none">Suche nach Kategorien</option>
<option value="photography">Fotografie</option>
<option value="text">Text</option>
<option value="digital">Digital</option>
<option value="print">Print</option>
<option value="consulting">Beratung</option>
<option value="advertising">Werbung</option>
<option value="socialmedia">Social Media</option>
<option value="strategy">Strategie</option>
<option value="conception">Konzeption</option>
<option value="film">Film</option>
<option value="tv">TV</option>
</select>
</span>
</div>
<div class="searchlisting" ng-controller="MyController">
<ul class="portfolio-grid">
<li class="grid-item" ng-repeat="item in jobs | filter: catchange" data-jkit="[show:delay=300;speed=500;animation=fade]">
<img ng-src="img/searchlist/{{item.shortname}}_tn.jpg" alt="Photo of {{item.name}}">
<a class="ajax-link" href="single.html">
<div class="grid-hover">
<h1>{{item.jobtitle}}</h1>
<p>{{item.name}}</p>
</div>
</a>
</li>
</ul>
</div>
Many thanks for any help.
Cheers
catchange will be a string, and when you filter, you are iterating over each object that is a job. So really, you need to be comparing each job.categories against catchange model.
Therefore, when you are doing filter:catchange, you are comparing each job object against the selected string in catchange, where you need to be comparing job.categories to catchange. You can tell angular what to track an iterator by to make sure it is comparing, or you can do the following:
Write a filter function that returns a boolean. This is just one way
this will be the filter in the view, angular passes each job as a param
filter: filterCategory
This will be a function in your controller that needs to compare the incoming job category with the categories that need to be filtered out. Just have it return a boolean.
$scope.filterCategory = function(job){
return $scope.catchange.filter(category){
job.categories === category
}
}
edit: Above assumes multi-select options, where catchange is an array of selected options stored via string. If it only ever going to be a single category select then
$scope.filterCategory = function(job){
if($scope.catchange){
return job.categories === $scope.catchange
}
else {
return true
}
}
Try specifying the property name that you want filter:
<li class="grid-item" ng-repeat="item in jobs | filter: {categories: catchange}" data-jkit="[show:delay=300;speed=500;animation=fade]">

Simple Dropdownbox Select in meteor helpers

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}}

Categories

Resources