I have my json from the server as
[
{
"guid":"54db86c947b39358ab2c266a",
"modified":0,
"created":0,
"name":"iOS",
"criteria":[
{
"name":"Supportability",
"value":1,
"reasons":[
"we do not know the tech"
]
},
{
"name":"Core Image",
"value":1,
"reasons":[
"Some reason",
"Reason 2"
]
},
{
"name":"Deployment",
"value":1,
"reasons":[
"no servers"
]
},
{
"name":"Hardware",
"value":1,
"reasons":[
"hardware too expensive"
]
},
{
"name":"Security",
"value":1,
"reasons":[
"plain text password"
]
},
{
"name":"Application",
"value":0.85,
"reasons":[
"332 out of 1600 apps are not package for W10"
]
}
],
"type":"Software"
},
{
"guid":"54db81ab47b3187eceaef46e",
"modified":0,
"created":0,
"name":"Windows 8",
"criteria":[
{
"name":"Supportability",
"value":1,
"reasons":[
"we do not know the tech"
]
},
{
"name":"Core Image",
"value":1,
"reasons":[
"Some reason",
"Reason 2"
]
},
{
"name":"Deployment",
"value":1,
"reasons":[
"no servers"
]
},
{
"name":"Hardware",
"value":1,
"reasons":[
"hardware too expensive"
]
},
{
"name":"Security",
"value":1,
"reasons":[
"plain text password"
]
},
{
"name":"Application",
"value":0.405,
"reasons":[
"332 out of 1600 apps are not package for W10"
]
}
],
"type":"Software"
},
{
"guid":"54db81ab47b3187eceaef46f",
"modified":0,
"created":0,
"name":"Windows 10.1",
"criteria":[
{
"name":"Supportability",
"value":1,
"reasons":[
"we do not know the tech"
]
},
{
"name":"Core Image",
"value":1,
"reasons":[
"Some reason",
"Reason 2"
]
},
{
"name":"Deployment",
"value":1,
"reasons":[
"no servers"
]
},
{
"name":"Hardware",
"value":1,
"reasons":[
"hardware too expensive"
]
},
{
"name":"Security",
"value":1,
"reasons":[
"plain text password"
]
},
{
"name":"Application",
"value":0.85,
"reasons":[
"332 out of 1600 apps are not package for W10"
]
}
],
"type":"Software"
}
]
How do i use ng-repeat in table so that I get the table as
<th>Criteria</th>
<th>iOs</th>
<th>windows</th>..(basically json.name)
and my table body as
<tr>
<td>Supportability (json.criteria[0].name)</td>
<td>1</td>(value for iOs)
<td>1</td>(value for Windows10.1)
<td>...................and so on.
</tr>
<tr><td>Core Image</td>
<td>1</td> ......
</tr>
?
As other comments have said, this data structure is not suitable for tables. Not optimal this way either, but if you really want to, you can manage it using divs. But you have to use multiple ng-repeats over the same data (not good).
<div class="section">
<div class="header"> </div>
<div class="body" ng-repeat="y in mydata[0].criteria">
{{y.name}}
</div>
</div>
<div class="section" ng-repeat="x in mydata">
<div class="header">{{x.name}}</div>
<div class="body" ng-repeat="y in x.criteria">
{{y.value}}
</div>
</div>
plunkr: http://plnkr.co/edit/FpsTe36oYh5t6a0XI2Dc?p=preview
I'll say it again, you're better off restructuring your data to suit your output.
Related
I am looking for a best approach to convert a static form to an angular dynamic form. I am not sure how to bind multiple values to the same answer.
The static page is available at: https://jsfiddle.net/hvuq5h46/
<div ng-repeat="i in items">
<select ng-model="i.answer" ng-options="o.id as o.title for o in i.answersAvailable" ng-visible="y.TYPE = 'SINGLE'"></select>
<input type="checkbox" ng-model="i.answer" ng-visible="y.TYPE = 'MULTIPLE'" />
</div>
The JSON file
[
{
"id": 1,
"title": "Are you a student?",
"type": "SINGLE",
"answersAvailable": [
{
"id": 1,
"title": "Yes"
},
{
"id": 2,
"title": "No"
}
],
"answer": [
1
]
},
{
"id": 2,
"title": "Would you like to be an astronaut?",
"type": "SINGLE",
"answersAvailable": [
{
"id": 4,
"title": "Yes"
},
{
"id": 5,
"title": "No"
},
{
"id": 6,
"title": "I am not sure"
}
],
"answer": [
4
]
},
{
"id": 3,
"title": "What is your favourite planet?",
"type": "MULTIPLE",
"answersAvailable": [
{
"id": 7,
"title": "Earth"
},
{
"id": 8,
"title": "Mars"
},
{
"id": 9,
"title": "Jupiter"
}
],
"answer": [
7,
8
]
}
]
Things would be much simpler if you can use a multiple select, but I understand it might be difficult for user to interact (consider something like md-select, which transforms multiple select into a list of checkbox for you)
Multiple select:
<select multiple
ng-model="i.answer"
ng-options="o.id as o.title for o in i.answersAvailable"
ng-if="i.type == 'MULTIPLE'"></select>
Anyway it is completely ok to use HTML checkbox. To do that we would need to bind checkbox model into the data as usual, and then update the answer array simultaneously.
ng-model="o.selected"
ng-change="updateAnswer(i)"
Also, we'll need to copy existing data to model during init.
ng-init="initMultiple(i)"
Working code:
angular.module('test', []).controller('Test', Test);
function Test($scope) {
$scope.items = [{
"id": 1,
"title": "Are you a student?",
"type": "SINGLE",
"answersAvailable": [{
"id": 1,
"title": "Yes"
},
{
"id": 2,
"title": "No"
}
],
"answer": [
1
]
},
{
"id": 2,
"title": "Would you like to be an astronaut?",
"type": "SINGLE",
"answersAvailable": [{
"id": 4,
"title": "Yes"
},
{
"id": 5,
"title": "No"
},
{
"id": 6,
"title": "I am not sure"
}
],
"answer": [
4
]
},
{
"id": 3,
"title": "What is your favourite planet?",
"type": "MULTIPLE",
"answersAvailable": [{
"id": 7,
"title": "Earth"
},
{
"id": 8,
"title": "Mars"
},
{
"id": 9,
"title": "Jupiter"
}
],
"answer": [
7,
8
]
}
]
$scope.initMultiple = function(item) {
item.answersAvailable.forEach(function(option) {
option.selected = item.answer.indexOf(option.id) != -1;
});
}
$scope.updateAnswer = function(item) {
item.answer = item.answersAvailable.filter(function(option) {
return option.selected;
})
.map(function(option) {
return option.id;
});
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app='test' ng-controller='Test'>
<div ng-repeat="i in items">
<select ng-model="i.answer[0]"
ng-options="o.id as o.title for o in i.answersAvailable"
ng-if="i.type == 'SINGLE'"></select>
<label ng-repeat="o in i.answersAvailable"
ng-if="i.type == 'MULTIPLE'"
ng-init="initMultiple(i)">
<input type="checkbox"
ng-model="o.selected"
ng-change="updateAnswer(i)" /> {{o.title}}
</label>
<div>{{i.answer}}</div>
</div>
</div>
Based on my experience, I will make a separation as two Angular models (or usually called services) for the form questions and another one which will collect the answers and eventually will be passed to the backend for further processing. This will provide me a flexibility to maintain both logic and presentation.
var myModule = angular.module('myModule', []);
myModule.factory('QuestionsFormService', function() {
var _question1;
var _question2;
var _question3;
function init(data){
//questions initiation
}
return init;
});
var myModule = angular.module('myModule', []);
myModule.factory('FormDataService', function() {
var _dataAnswer = {}
function init(){
//data initialization
}
function insertData(key, value){
_dataAnswer[key] = value
}
return init;
});
From the example of service models above, you need to make these available to your presentation through the Angular controller with Dependency Injection.
myModule.controller("MyCtrl", function($scope, FormDataService, QuestionsFormService) {
$scope.form_questions = QuestionsFormService.init();
$scope.form_answers = FormDataService.init()
//further logic to make these available on your view on your convenience
});
What you write on the HTML page as an Angular view is already close enough. You only need to change the binding to two models as I propose above. Thank you.
I'm trying to dosomething similar to this Angular Code but using React. I'm very new to react and can't figure it out.
I have a json that is storing data fields and a field called classes. I want to be able to pull the classes in json fields to attach them to each row. This is the angular way I have done in the past successfully.
<tr ng-repeat="row in vm.widget10.table.rows">
<td ng-repeat="cell in row">
<span class="{{cell.classes}}">
{{cell.value}}
</span>
</td>
</tr>
with a json structured this way
{
"widget10": {
"title": "Table Details",
"table": {
"columns": [{
"title": "Item Name"
},
{
"title": "Some Data"
},
{
"title": "Other Data ($)"
},
{
"title": "Visual Data (%)"
},
{
"title": "Profit/Loss ($)"
},
{
"title": "Profit/Loss (%)"
}
],
"rows": [
[{
"value": "Data Field One",
"classes": "text-boxed m-0 deep-orange-bg white-fg",
"icon": ""
},
{
"value": "$14,880.00",
"classes": "text-bold",
"icon": ""
},
{
"value": "$14,000.00",
"classes": "",
"icon": ""
},
{
"value": "%94.08",
"classes": "red-fg",
"icon": "trending_down"
},
{
"value": "$880.00",
"classes": "",
"icon": ""
},
{
"value": "%5.92",
"classes": "",
"icon": ""
}
]
]
}
}
In my react component render() I have something like this:
<TableBody
displayRowCheckbox={this.state.showCheckboxes}
deselectOnClickaway={this.state.deselectOnClickaway}
showRowHover={this.state.showRowHover}>
{statsData.map( (row, index) => (
<TableRow key={index}>
<TableRowColumn><span style={{backgroundColor:"{statsData.bgColor[index]}"}}>{row.name}</span></TableRowColumn>
<TableRowColumn>{row.data}</TableRowColumn>
<TableRowColumn>{row.o_data}</TableRowColumn>
<TableRowColumn>{row.v_data}</TableRowColumn>
<TableRowColumn>{row.o_pl}</TableRowColumn>
<TableRowColumn>{row.v_pl}</TableRowColumn>
</TableRow>
))}
</TableBody>
and a json this way (in the component)
const statsData = [
{
name: "Data Field One",
bgColor: "red",
data: "$14,880.00",
o_data: "$14,000.00",
v_data: "%94.08",
o_pl: "$880.00",
v_pl: "%5.92",
},
{
name: "Data Field Two",
bgColor: "blue",
data: "$14,880.00",
o_data: "$14,000.00",
v_data: "%94.08",
o_pl: "$880.00",
v_pl: "%5.92",
},
{
name: "Data Field Three",
bgColor: "yellow",
data: "$14,880.00",
o_data: "$14,000.00",
v_data: "%94.08",
o_pl: "$880.00",
v_pl: "%5.92",
}
];
So far the data comes through fine, but I can't figure out how to pull the bgColor as either a backgroundColor style or as a class.
Any help is appreciated.
Thanks
Remove the quotes from around the value for backgroundColor and read from the row iterator variable (based on the JSON you pasted):
<span style={{backgroundColor: row.bgColor}}>{row.name}</span>
I am trying to filter my data which I am getting from a HTTP GET endpoint by an array of values
filters = ['Full Time', 'LinkedIn', ...]
The general structure of the response I am getting back is an array of objects where each object can look like this:
{
"preferences": {
"jobType": {
"type": "Full Time"
}
},
"profile": {
"additionalinfo": {
"organization": [
{
"name": "Google"
},
{
"name": "LinkedIn"
}
],
"university": [
{
"name": "UC Berkeley",
"degrees": [ {"name": "Computer Engineering"}]
}
}
}
}
So if I filter by ["Google", "Full Time"], the above object should be included.
Is there a built in filter to handle this?
I am having trouble writing the custom filter to handle such a heavily nested object.
Any ideas on how to implement this?
You can use built in filter like this jsfiddle
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.data = [{
"preferences": {
"jobType": {
"type": "Full Time"
}
},
"profile": {
"additionalinfo": {
"organization": [{
"name": "Google"
}, {
"name": "LinkedIn"
}],
"university": [{
"name": "UC Berkeley",
"degrees": [{
"name": "Computer Engineering"
}]
}]
}
}
}, {
"preferences": {
"jobType": {
"type": "Remote"
}
},
"profile": {
"additionalinfo": {
"organization": [{
"name": "Yandex"
}, {
"name": "LinkedIn"
}],
"university": [{
"name": "UC Berkeley",
"degrees": [{
"name": "Computer Engineering"
}]
}]
}
}
}];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<h3>Jobs</h3>
<input ng-model="filterModelJobType" placeholder="filter jobType">
<input ng-model="filterModelJob" placeholder="filter job">
<table class="table table-striped table-bordered">
<tbody>
<tr ng-repeat="x in data|filter:{profile: {additionalinfo:{organization:{name:filterModelJob}}},preferences: {jobType:{type:filterModelJobType}}}">
<td>{{ $index + 1 | number }}</td>
<td class="text-center">{{ x.preferences.jobType.type }}</td>
<td class="text-left">
<div ng-repeat="org in x.profile.additionalinfo.organization">
<hr> {{org.name}}
</div>
</td>
</tr>
</tbody>
</table>
</body>
In the latest version of AngularJS
If there is nested object then
var foo = $filter('filter')($scope.welcome, {
additionalinfo: { name: 'google' }
});
Reference: GitHub issue
I´m working with bootstrap and angularjs for the user interface and google appengine with java as a backend.
Just now I have a problem filling a dropdown menu, I see an empty list so I suspect that the problem is in the html code.
Front end:
<div class="dropdown" >
<select id="mySelPartido" class="form-control">
<option ng-repeat="partido in data.locations.partidos"
ng-selected="partido.selected" ng-model="partido.partido">{{partido.partido}}</option>
</select>
</div>
js in angular code (I debug this code and it works!):
$scope.status = 'loading...';
$scope.partido = "Select partidos";
$scope.data = {
"locations": {}
};
$http.get('https://myservice.appspot.com/_ah/api/partidoendpoint/v1/partido')
.then(function (res) {
$scope.data.locations.partidos = res.data.items;
$scope.status = "loaded "
+ $scope.data.locations.partidos.length
+ " partidos.";
});
My service response from app engine backend:
{
"items": [
{
"id": {
"kind": "Partido",
"appId": "s~myservice",
"id": "5066549580791808",
"parent": {
"kind": "Provincia",
"appId": "s~myservice",
"id": "5086253011697664",
"complete": true
},
"complete": true
},
"name": "Florencio Varela",
"kind": "partidoendpoint#resourcesItem"
},
{
"id": {
"kind": "Partido",
"appId": "s~myservice",
"id": "5094432508477440",
"parent": {
"kind": "Provincia",
"appId": "s~myservice",
"id": "5086253011697664",
"complete": true
},
"complete": true
},
"name": "La Matanza",
"kind": "partidoendpoint#resourcesItem"
}
],
"kind": "partidoendpoint#resources",
"etag": "\"PQS12KaO4-dKVfv_BcCoEkbIN9g/GvZKzZUnrHEP8TKWybTkd_fJbnc\""
}
Check the angular documentation for select.
Maybe try use the ngOptions directive in the select element. Example :
function demo($scope) {
$scope.items = [
{ name: 'foo' },
{ name: 'bar' },
{ name: 'baz' }
];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="demo">
<select ng-options="item.name for item in items"
ng-model="selected">
</select>
<p>You have selected : {{ selected }}
</div>
Here is my code to select the country based on ng-options and get tabs based on ng-repeat:
<select ng-model="country" ng-options= "countryName.country for countryName in countryNames" ng-change="getCountry()">
</select>
<ul id="configPhoneTab" class="nav nav-tabs equipmentTab agenttabs">
<li class="active" ng-repeat= "configTab in config" val="configTab[0]">
{{configTab.tabs}}
</li>
</ul>
My tabs in the json file is
[
{
"country": "India",
"tabs": [
{
"title": "India Number",
"type": [
"VOICE",
"FAX",
"VN"
],
"carrier": "L3",
},
{
"title": "Toll Free",
"type": [
"TF"
],
"carrier": "L3",
}
]
},
{
"country": "Aus",
"tabs": [
{
"title": "Aus Number",
"type": [
"VOICE",
"FAX",
"VN"
],
"carrier": "L3",
},
{
"title": "Toll Free",
"type": [
"TF"
],
"carrier": "L3",
}
]
}
How can I retrieve the tabs title from json based on country selection?
You could use a third-party library like [underscorejs] (website address) and retrieve the desired data using some of it's functions for example _.where(...) if '_.fined(...)'
the pivot which your search will be based on would be the $scope.country which in bound to your <select> tag (<select ng-model="country" ng-options= ...)
sorry I cannot provide any working demos right away as I'm answering from a mobile device.
Hope it helped.