How to use ng-repeat with ng-model and get an ID - javascript

I have a form with ng-model="award.myProperty". There are some inputs and texareas. In my service I have an array for textareas:
allQuestions = [
id: 'XXX', question: 'some text',
id: 'YYY', question: 'some text',
id: 'ZZZ', question: 'some text',
];
My goal is to get data from textareas in such structure
questions: [{
'XXX': 'data from textarea1',
'YYY': 'data from texarea2',
'ZZZ': 'data from textarea3',
}];
I've tried to use ng-repeat with ng-model, but ng-model doesn't return ID's. If I use $index with ng-repeat then I get an array:
[{ 0: 'data from textarea1',
1: 'data from textarea2',
2: 'data from textarea3',}]
Structure is good, but that's not my ID's from service.
SERVICE
const allQuestions = [
{ id: 'XXX', question: 'question1' },
{ id: 'YYY', question: 'question2' },
{ id: 'ZZZ', question: 'question3' },
];
getQuestion() {
return allQuestions;
},
CONTROLLER
$scope.allQuestions = awards_service.getQuestion();
$scope.award = {
description: '',
questions: [],
};
VIEW
<form name="awardForm">
<input ng-model="award.description"></input>
<div ng-repeat="question in allQuestions">
<textarea ng-model="award.questions"></textarea>
</div>
</form>
Maybe there is a better solution than ng-repeat.

In your controller change $scopre.award.questions to:
$scope.allQuestions = awards_service.getQuestion();
$scope.award = {
description: '',
questions: [{}]
};
Then in the view:
<form name="awardForm">
<input ng-model="award.description"></input>
<div ng-repeat="question in allQuestions">
<textarea ng-model="award.questions[0][question.id]"></textarea>
</div>
</form>
Demo:
angular.module("myApp", [])
.controller('myCtrl', ['awards_service', '$scope', function(awards_service, $scope) {
$scope.allQuestions = awards_service.getQuestion();
$scope.award = {
description: '',
questions: [{}],
};
$scope.submit = function() {
console.log($scope.award);
// submit your form then reset the award object
// ...
$scope.award = {
description: '',
questions: [{}],
};
}
}])
.factory('awards_service', function() {
const allQuestions = [
{ id: 'XXX', question: 'question1' },
{ id: 'YYY', question: 'question2' },
{ id: 'ZZZ', question: 'question3' },
];
return {
getQuestion() {
return allQuestions;
}
}
});
.as-console-wrapper { height: 70px !important; overflow: auto; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="myCtrl">
<form name="awardForm" ng-submit="submit()">
<label>Description</label><br>
<input ng-model="award.description"></input><br>
<label>Questions</label><br>
<div ng-repeat="question in allQuestions">
<textarea ng-model="award.questions[0][question.id]" placeholder="Enter a question"> </textarea>
</div>
<input type="submit" value="submit" />
</form>
</div>
</div>

Related

Push data into array of objects using JavaScript

I have an Array of Objects, once the user fill out and click on the button with id: 'add', I want to push this data into the first master.review.
I tried with push() but I am getting 'list[0].review[j].push is not a function'.
I did some research and I saw I should do like this:
list[0].review[j] = newData
But not even this one is working. Plus I want to add data all the time the user wants to add something.
let list = [
{
master: "Leo",
review: [{
name: 'Bob',
text: 'good'
},
{
name: 'Elly',
text: 'ok ok'
},
]
},
{
master: "Emily",
review: [{
name: 'Greg',
text: 'omg!'
},
{
name: 'Joe',
text: 'SO so..'
},
]
},
]
$('#add').on('click', function() {
let name = document.getElementById('name').value;
let text = document.getElementById('text').value;
let newData = [{
name: name,
text: text,
}]
for (let i = 0; i < list.length; i++) {
for (let j = 0; j < list[i].review.length; j++) {
list[0].review[j].push(newData)
console.log(list)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="name" placeholder="Your Name" required/>
<input type="text" id="text" placeholder="Your Name" required/>
<input type="button" id="add" />
You are trying to push into an Object. Method push is not available on type Object. push is available on type Array in javascript. Try below code
list[0].review.push(newData)
There is no need of loop as you want to push the newData object into the list[0]. In order to push into the array use push function - list[0].review.push(newData);
let list = [
{
master: "Leo",
review: [{
name: 'Bob',
text: 'good'
},
{
name: 'Elly',
text: 'ok ok'
},
]
},
{
master: "Emily",
review: [{
name: 'Greg',
text: 'omg!'
},
{
name: 'Joe',
text: 'SO so..'
},
]
},
]
$('#add').on('click', function() {
let name = document.getElementById('name').value;
let text = document.getElementById('text').value;
let newData = {
name: name,
text: text,
};
list[0].review.push(newData);
console.log(list[0].review);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="name" placeholder="Your Name" required/>
<input type="text" id="text" placeholder="Your Name" required/>
<input type="button" id="add" value= "add" />

Multi level json filter in angular js

I am new in angular js i want to put filter in ng-repeat i have json like this
var data = [
{name:test1,b1:{lastValue:0},b2:{lastValue:6},b3:{lastValue:6},b4:{lastValue:0}}
{name:test2,b1:{lastValue:6},b2:{lastValue:0},b3:{lastValue:6},b4:{lastValue:0}}
{name:test3,b1:{lastValue:6},b2:{lastValue:0},b3:{lastValue:6},b4:{lastValue:0}}
]
I want to put filter on lastValue i tested like this
ng-repeat = "d in data | filter:{*.lastValue:filterStatus}"
filterStatus // contain value of filter which user selected but its not working
I don't know how to do this i tried google but nothing found please help me
<input ng-model="filterStatus" type="text">
your filterStatus should hold model value
ng-repeat = "d in data | filter:filterStatus"
var app = angular.module("Profile", []);
app.controller("ProfileCtrl", function($scope) {
$scope.filter_val = {}
$scope.data = [{
name: 'test1',
b1: {
lastValue: 0
},
index: 'b1'
}, {
name: 'test2',
b2: {
lastValue: 6
},
index: 'b2'
}, {
name: 'test3',
b3: {
lastValue: 6
},
index: 'b3'
}, {
name: 'test4',
b4: {
lastValue: 0
},
index: 'b4'
}, {
name: 'test5',
b5: {
lastValue: 89
},
index: 'b5'
}, {
name: 'test6',
b6: {
lastValue: 68
},
index: 'b6'
}]
$scope.own_filter = function(val) {
if (!$scope.filter_val.value)
return true;
else {
return (String(val[val['index']]['lastValue'] || '').indexOf($scope.filter_val.value) != -1)
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="Profile" ng-controller="ProfileCtrl">
<input type="text" ng-model="filter_val.value" placeholder="Enter Last Value">
<div class="row" ng-repeat="event in data |filter:own_filter track by $index ">
<h4>{{'Name : ' + event.name}}------{{'Last Value : '+event[event['index']]['lastValue']}}</h4>
</div>
</body>
Use {$:filterStatus} construction:
angular.module('app', []).controller('ctrl',function($scope){
$scope.data = [
{name:'test1',b1:{lastValue:1},b2:{lastValue:6},b3:{lastValue:6},b4:{lastValue:0}},
{name:'test2',b1:{lastValue:2},b2:{lastValue:0},b3:{lastValue:6},b4:{lastValue:0}},
{name:'test3',b1:{lastValue:3},b2:{lastValue:0},b3:{lastValue:6},b4:{lastValue:0}}
]
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js">
</script>
<div ng-app='app' ng-controller='ctrl'>
<input type='number' ng-model='filterStatus' ng-init='filterStatus=1'>
<ul>
<li ng-repeat='item in data | filter: {$:filterStatus}'>{{item.name}}</li>
</ul>
</div>

Angular: How to filter by deep object property in array?

I have an objects formatted like this:
id: 1,
name: MyObj
properties: {
owners: [
{
name:owner1,
location: loc1
},
{
name:owner2,
location: loc1
}
]
}
Number of owners is different for each object. When I try to filter it using ng-repeat with filter:searchBox and search box inputs
<input name="search-filter" class="form-control" type="search" ng-model="searchBox.properties.title" />
<input name="search-filter" class="form-control" type="search" ng-model="searchBox.properties.owners" />
filtering by title works perfectly, however owners filtering doesn't work at all but I supposed it will filter based on both location and name. What am I doing wrong?
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.objs =
{
id: 1,
name: 'MyObj',
properties: {
owners: [
{
name: 'owner1',
location: 'loc1'
},
{
name: 'owner2',
location: 'loc2'
}
]
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<input name="search-filter" class="form-control" type="search" placeholder="Search by location" ng-model="searchBox.properties.location" />
<input name="search-filter" class="form-control" type="search" placeholder="Search by name" ng-model="searchBox.properties.owners" />
<div ng-repeat="owner in objs.properties.owners | filter:{'location': searchBox.properties.location} |filter:{'name': searchBox.properties.owners}">
{{owner}}
</div>
</div>
You can filter manually
var list = [
{
id: 1,
name: 'MyObj',
properties: {
owners: [
{
name: 'owner1',
location: 'loc1'
},
{
name: 'owner2',
location: 'loc1'
}
]
}
}
];
function filter(filter) {
return list.filter(function(item) {
return item.properties.owners.find(function(owner) {
return Object.keys(filter).every(function(key) {
return filter[key] === owner[key];
});
});
});
}
console.log(filter({ name: 'owner1', location: 'loc1' }));
I used es6 shim for that.

Filter Data in nested json

My angular controller is following -
how to filter nested data like first row of json-
<script>
var myApp = angular.module('myApp', ['angular.filter']);
function VersionFilterCtrl($scope) {
$scope.limit=6;
$scope.orders = [
{ id:1, customer:[{ name: 'John1', id: 10 },{ name: 'John2', id: 100 }] },
{ id:2, customer: { name: 'William', id: 20 } },
{ id:3, customer: { name: 'John', id: 10 } },
{ id:4, customer: { name: 'William', id: 20 } },
{ id:5, customer: { name: 'Clive', id: 30 } }
];
}
</script>
and my html
<div ng-app="myApp">
<div ng-controller="VersionFilterCtrl">
<input type='text' name='name' ng-model='search.customer.name'>
<input type='text' name='name' ng-model='search.customer.id'>
<li ng-repeat="order in orders| filterBy: ['customer.name']: search.customer.name| filterBy: ['customer.id']: search.customer.id">
{{order.id}}{{order.customer.name}}
</li>
</div>
</div>
JSFIDDLE EXAMPLE
You approached this correctly in how you set up your search models to match the structure of the data you are filtering, i.e. search.customer.name and search.customer.id.
All you need to do is to apply the search object as the filter:
<li ng-repeat="order in orders | filter: search">
{{order.id}} | id: {{order.customer.id}} name: {{order.customer.name}}
</li>
plunker
A few other issues:
There is no filterBy (unless you create your own)
Your first order record has an array of customers - was this intentional? This plunker handles that case

Concat multiple arrays with Angular

I am trying to make a list where the user can select what information they want to view below.
The user selects this from a check list.
So if the user just checks obj1 they will see
obj1 title 1
obj1 title 2
etc.
I have tried a few things (see commented out code below) but in this codepen I just have it hard coded so on check it shows obj1 and obj2.
How can I get it to show what the user checks and multiple items in concact, or is there a better way to approach this?
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Checkboxes</title>
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body ng-controller="MainCtrl">
<ion-header-bar class="bar-positive">
<h1 class="title">Checkboxes</h1>
</ion-header-bar>
<ion-content>
<div class="list">
<ion-checkbox ng-repeat="item in objList"
ng-model="item.checked"
ng-checked="item.checked"
ng-change="itemChange($index)">
{{ item.name }}
</ion-checkbox>
<div class="item" ng-repeat="item in finalObj">{{ item.title }}</div>
</div>
</ion-content>
</body>
</html>
<script>
angular.module('ionicApp', ['ionic'])
.controller('MainCtrl', function($scope) {
$scope.objList = [
{ id:"1", name: "obj1", checked: false },
{ id:"2", name: "obj2", checked: false },
{ id:"3", name: "obj3", checked: false },
{ id:"4", name: "obj4", checked: false }
];
var obj1 = [{id: 1111, title: 'obj1 title 1'},{id: 1112, title: 'obj1 title 2'}];
var obj2 = [{id: 2221, title: 'obj2 title 1'},{id: 2222, title: 'obj2 title 2'}];
var obj3 = [{id: 3331, title: 'obj3 title 1'},{id: 3332, title: 'obj3 title 2'}];
var obj4 = [{id: 4441, title: 'obj4 title 1'},{id: 4442, title: 'obj4 title 2'}];
var finalObj1 = obj1;
var finalObj2 = obj2;
//var finalObj2 = obj2,obj3; Tried this instead for my finalObj2 however it only showed obj2 data
$scope.itemChange = function(indx) {
if($scope.objList[indx].checked) {
/* Tried to get the var called obj plus the index (+1) and push it in this returns undefined.
$scope.finalObj = [];
$scope.finalObj.push(this["obj" + (indx + 1)]);
console.log($scope.finalObj);
*/
/* Tired to get the name of the selected item, this seems to return the correct information for finalObj1 and finalObj2 but when I console.log($scope.finalObj) I can see it is just joining 2 strings?
$scope.finalObj1=$scope.objList[indx].name;
$scope.finalObj2=$scope.objList[indx+1].name;
$scope.finalObj = $scope.finalObj1.concat([$scope.finalObj2]);
console.log($scope.finalObj);
*/
$scope.finalObj1=finalObj1;
$scope.finalObj2=finalObj2;
$scope.finalObj = $scope.finalObj1.concat($scope.finalObj2);
}
else {
$scope.finalObj1=[];
$scope.finalObj2=[];
$scope.finalObj = $scope.finalObj1.concat($scope.finalObj2);
}
};
});
</script>
I would restructure the way you are storing the data. There is no need to have two sets of data for one tree of objects. I've gone ahead and changed some of the variable names mostly out of personal preference.
angular.module('ionicApp', ['ionic'])
.controller('MainCtrl', function($scope) {
$scope.displayObj = [];
$scope.objList = [
{
id: '1',
name: 'obj1',
active: false,
contents: [
{id: 1111, title: 'obj1 title 1'},
{id: 1112, title: 'obj1 title 2'}
]
},
{
id: '2',
name: 'obj2',
active: false,
contents: [
{id: 2221, title: 'obj2 title 1'},
{id: 2222, title: 'obj2 title 2'}
]
},
{
id: '3',
name: 'obj3',
active: false,
contents: [
{id: 3331, title: 'obj3 title 1'},
{id: 3332, title: 'obj3 title 2'}
]
},
{
id: '4',
name: 'obj4',
active: false,
contents: [
{id: 4441, title: 'obj4 title 1'},
{id: 4442, title: 'obj4 title 2'}
]
}
];
/* I left this in here in case you were uncomfortable adding more DOM elements
$scope.itemChange = function() {
$scope.displayObj = [];
for(var x = 0; x < $scope.objList.length; x++) {
if($scope.objList[x].active === true) {
for(var y = 0; y < $scope.objList[x].contents.length; y++) {
$scope.displayObj.push($scope.objList[x].contents[y]);
}
}
}
} */
});
Then for the DOM
<ion-header-bar class="bar-positive">
<h1 class="title">Checkboxes</h1>
</ion-header-bar>
<ion-content>
<div class="list">
<ion-checkbox ng-repeat="item in objList"
ng-model="item.active"
ng-checked="item.active">
{{ item.name }}
</ion-checkbox>
<div ng-repeat="item in objList">
<div class="item" ng-show="item.active" ng-repeat="c in item.contents">{{ c.title }}</div>
</div>
</div>
</ion-content>
Here's the updated pen : http://codepen.io/anon/pen/emYZLa

Categories