In angular, how would I change this selection to a list while maintaining the same functionality and data?
<select ng-if="main.fbWriteup.data"
name="selectGroup"
class="form-control"
ng-model="main.selectedGroup"
ng-options="key as key for (key,group) in main.fbWriteup.data"
ng-change="main.selectedMessage=-1">
</select><br/>
here is my full code: http://codepen.io/Zancrash/pen/KVYdqP/
You can add a group and the groups added are displayed within the dropdown menu. But I want all of them to be shown as a list item instead.
OK, I think I know what you're looking for.
I've created a new demo fiddle because your code is hard to read.
Just use ng-repeat to loop over your list of groups and add ng-click for selecting the group.
Please have a look at the demo below or in this fiddle.
angular.module('demoApp', [])
.controller('mainController', MainController);
function MainController($scope) {
var vm = this,
defaultEntries = [{
id: 0,
name: 'group1'
},{
id: 1,
name: 'group2'
}];
angular.extend(vm, {
groups: defaultEntries,
selectedGroup: defaultEntries[0],
addGroup: function() {
var newGroupName = prompt('enter group name'),
newItem = {id: vm.groups.length+1, name: newGroupName}
vm.groups.push(newItem);
vm.selectedGroup = newItem; // select new item
}
});
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp" ng-controller="mainController as ctrl">
<button ng-click="ctrl.addGroup()">
Add Group
</button>
<select ng-model="ctrl.selectedGroup" ng-options="group as group.name for group in ctrl.groups"></select>
group selected: {{ctrl.selectedGroup}}
<h1>
Group list
</h1>
<ul>
<li ng-repeat="group in ctrl.groups">{{group.name}}</li>
</ul>
</div>
Related
I currently am getting to sets of JSON data back from a restul GET call. The first response set is used to build a HTML table of data. One of those values is an numeric ID from a data table in the DB.
In the other set of JSON data is a set of the values that correspond to the numeric id value in the first data set.
I'm trying to look up a value in the second set, based on the numeric value in the first set.
I've been able to accomplish this using a tag and ng-options, but this particular column need to just be a static tag with a data value.
My tag looks like
<td><select id="basOrgs" class="form-control grid-input" ng-model-options="{updateOn: 'blur'}" ng-model="item.OrgUid" ng-options="org.OrganizationUid as org.OrganizationDisplay for org in Orgs"></select></td>
What I'm trying to accomplish is to use the model item.OrgUid to look up a value in the Orgs data set to display Orgs.OrganizationDisplay based on the item.OrgUid value.
I've experimented with ng-repeat without any success.
<td ng-model="item.OrgUid" ng-repeat="org in Orgs track by org.OrganizationUid">{{org.OrganizationDisplay}}</td>
The item model looks like{OrgUid: 123456, Active:'Y',StartDate'}
The Org model looks like '{OrgUid: 123456, OrgDisplay: 'The Name of the Org'}
What I would like to do is display the OrgDisplay value in the tag based on the item.OrgUid value.
Any help would be appreciated.
Thanks,
--Jim
Assuming you have $scope.orgs in your controller, how about
<td ng-model="item.OrgUid" ng-repeat="org in Orgs track by org.OrganizationUid">{{lookup[org.OrganizationUid].OrganizationDisplay}}</td>
I'll edit this to include the right lookup code, but this is the idea.
You could make a lookup object to facilitate this:
var lookup = {};
for (var i = 0, len = orgs.length; i < len; i++) {
lookup[array[i].OrganizationUid] = array[i];
}
Here is a working snippet that uses lookup between two "data sets".
var myApp = angular.module('myApp', []);
myApp.controller('myController',
function($scope) {
$scope.Orgs = [{
OrgUid: 1,
OrgDisplay: 'Org 1'
}, {
OrgUid: 2,
OrgDisplay: 'Org 2'
}, {
OrgUid: 3,
OrgDisplay: 'Org 3'
}];
$scope.Items = [{
OrgUid: 1,
Active: 'Y',
StartDate: "12/1/1984"
}, {
OrgUid: 2,
Active: 'Y',
StartDate: "12/1/1984"
}, {
OrgUid: 3,
Active: 'Y',
StartDate: "12/1/1984"
}];
$scope.lookup = {};
for (var i = 0, len = $scope.Orgs.length; i < len; i++) {
$scope.lookup[$scope.Orgs[i].OrgUid] = $scope.Orgs[i];
}
});
.item {
border:1px solid green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="myApp" ng-controller="myController">
<body>
<span class="item" ng-model="item.OrgUid" ng-repeat="item in Items">{{lookup[item.OrgUid].OrgDisplay}}</td>
</body>
</html>
I'm attempting to make a dynamic form in Angular 1.4.7 in which:
There are multiple reports (vm.reports = [];)
Each report can be assigned ONE report object via vm.reportOptions.
Each vm.reportOptions can only be selected ONCE across multiple reports, which is filtered via exclude.
Each report supports MANY dimension objects via vm.dimensionOptions.
Each dimension can only be selected ONCE per report, which is filtered via excludeDimensions (subsequent reports have access to all the dimensionOptions and filter on their own).
These requirements are all working (roughly) with the exception of:
If I add two reports, and add the exact same dimensions (ie: Report One > Dimension One > Enable Dimension Filter and Report Two > Dimension One > Enable Dimension Filter) for each of the reports, changing the select inside of Enable Dimensions Filter changes it in both the reports.
I assume that this is happening due to the fact that I'm pushing the actual dimension objects in to each reports dimensions: [] array and that they are still pointing to the same object.
-- EDITS --
I realize angular.clone() is a good way to break this reference, but the <select> code I wrote is automatically piping in the object to the model. I was tempted to give each report their own controller and giving each report their own copy() of the options.
Would this work? Or is there a better way?
I have a working JSBin here.
Pertinent Code:
HTML:
<body ng-app="app">
<div ng-controller="AlertsController as alerts">
<pre>{{alerts.output(alerts.reports)}}</pre>
<div class="container">
<div
ng-repeat="report in alerts.reports"
class="report"
>
<button
ng-if="$index !== 0"
ng-click="alerts.removeItem(alerts.reports,report)"
>Delete Report</button>
<label>Select Report</label>
<select
ng-model="alerts.reports[$index].report"
ng-init="report"
ng-options="reportSelect.niceName for reportSelect in alerts.reportOptions | exclude:'report':alerts.reports:report"
></select>
<div
ng-repeat="dimension in report.dimensions"
class="condition"
>
<div class="select">
<h1 ng-if="$index === 0">IF</h1>
<h1 ng-if="$index !== 0">AND</h1>
<select
ng-model="report.dimensions[$index]"
ng-change="alerts.checkThing(report.dimensions,dimension)"
ng-init="dimension"
ng-options="dimensionOption.niceName for dimensionOption in alerts.dimensionOptions | excludeDimensions:report.dimensions:dimension"
>
<option value="123">Select Option</option>
</select>
<button
class="delete"
ng-if="$index !== 0"
ng-click="alerts.removeItem(report.dimensions,dimension)"
>Delete</button>
</div>
<input type="checkbox" ng-model="dimension.filtered" id="filter-{{$index}}">
<label class="filter-label" for="filter-{{$index}}">Enable Dimension Filter</label>
<div ng-if="dimension.filtered">
<select
ng-model="dimension.operator"
ng-options="operator for operator in alerts.operatorOptions">
</select>
<input
ng-model="dimension.filterValue"
placeholder="Text"
></input>
</div>
</div>
<button
ng-click="alerts.addDimension(report)"
ng-if="report.dimensions.length < alerts.dimensionOptions.length"
>Add dimension</button>
</div>
<button
ng-if="alerts.reports.length < alerts.reportOptions.length"
ng-click="alerts.addReport()"
>Add report</button>
<!--
<div ng-repeat="sel in alerts.select">
<select ng-model="alerts.select[$index]" ng-init="sel"
ng-options="thing.name for thing in alerts.things | exclude:alerts.select:sel"></select>
</div>
-->
</div><!-- container -->
</div>
</body>
JS:
var app = angular.module('app', []);
app.controller('AlertsController', function(){
var vm = this;
vm.reportOptions = [
{id: 1, niceName: 'Report One'},
{id: 2, niceName: 'Report Two'},
{id: 3, niceName: 'Report Three'},
];
vm.dimensionOptions = [
{id: 1, niceName: 'Dimension One'},
{id: 2, niceName: 'Dimension Two'},
{id: 3, niceName: 'Dimension Three'},
];
vm.operatorOptions = [
'>',
'>=',
'<',
'<=',
'=',
'!='
];
////// DEBUG STUFF //////
vm.output = function(value) {
return JSON.stringify(value, undefined, 4);
}
////////////////////////
vm.reports = [];
vm.addReport = function() {
vm.reports.push({report: {id: null}, dimensions: []});
}
vm.removeItem = function(array,item) {
if(array && item) {
var index = array.indexOf(item);
if(index > -1) {
array.splice(index,1);
}
}
}
vm.addDimension = function(report) {
console.log('addDimension',report);
if(report) {
report.dimensions.push({})
}
};
// init
if(vm.reports.length === 0) {
vm.reports.push({report: {}, dimensions: [{}]});
// vm.reports.push({report: vm.reportOptions[0], dimensions: [vm.dimensionOptions[0]]});
}
});
app.filter('excludeDimensions', [function() {
return function(input,select,selection) {
// console.log('ed',input,select,selection);
var newInput = [];
for(var i = 0; i < input.length; i++){
var addToArray=true;
for(var j=0;j<select.length;j++){
if(select[j].id===input[i].id){
addToArray=false;
}
}
if(addToArray || input[i].id === selection.id){
newInput.push(input[i]);
}
}
return newInput;
}
}]);
app.filter('exclude', [function () {
return function(input,type,select,selection){
var newInput = [];
for(var i = 0; i < input.length; i++){
var addToArray=true;
for(var j=0;j<select.length;j++){
if(select[j][type].id===input[i].id){
addToArray=false;
}
}
if(addToArray || input[i].id === selection[type].id){
newInput.push(input[i]);
}
}
return newInput;
};
}]);
How do I get around pushing same object reference to array
Use angular.copy()
array.push(angular.copy(vm.formObject));
// clear object to use again in form
vm.formObject={};
I ended up using select as so that it just set an id on the object instead of pointing to the original object. This solved the problem.
I am developing one prototype application in ionic framework. I am newbie for angular js, HTML, CSS , Java Script and all this stuff.
I have one json file which I am using as an input. I am able to parse this Json file and able to get json object from this. This json object contains array of items. You can refer below json content for this. Here items are application A,B.....
Updated Input Json :
{
"data": [
{
"applicationname": "A",
"permissions": [
{
"text": "at"
},
{
"text": "at1"
}
]
},
{
"applicationname": "B",
"permissions": [
{
"text": "bt"
},
{
"text": "bt1"
}
]
}
]
}
When the application loads for the first time, application should load only the first item from above json array which means only application "A" (first item) data.
Once user clicks on any button (install/cancel) in Footer then it should changed its data and display application "B"'s contents. This process should continue till the end of json array.
My current code is not loading even the first item data in. Am I doing something wrong in HTML?
Updated Code :
HTML file :
<ion-header-bar class="bar-calm">
<h1 class="title">Application Permissions</h1>
</ion-header-bar>
<ion-nav-view name="home" ng-repeat="app in applicationdata">
<div class="bar bar-subheader bar-positive">
<h3 class="title"> {{app.applicationname }}</h3>
</div>
<ion-content class="has-subheader">
<div class="list" ng-controller="CheckboxController">
<ion-checkbox ng-repeat="item in app.permissions" ng-model="item.checked" ng-checked="selection.indexOf(item) > -1" ng-click="toggleSelection(item)">
{{ item.text }}
<h3 class="item-text-wrap"> details come soon </h3>
</ion-checkbox>
<div class="item">
<pre ng-bind="selection | json"></pre>
</div>
<div class="item">
<pre ng-bind="selection1 | json"></pre>
</div>
</div>
</ion-content>
<ion-footer-bar align-title="left" class="bar-light" ng-controller="FooterController">
<div class="buttons">
<button class="button button-balanced" ng-click="infunc()"> Install </button>
</div>
<h1 class="title"> </h1>
<div class="buttons" ng-click="doSomething()">
<button class="button button-balanced"> Cancel </button>
</div>
</ion-footer-bar>
</ion-nav-view>
app.js file :
pmApp.controller('CheckboxController', function ($scope, $http, DataService) {
// define the function that does the ajax call
getmydata = function () {
return $http.get("js/sample.json")
.success(function (data) {
$scope.applicationdata = data;
});
}
// do the ajax call
getmydata().success(function (data) {
// stuff is now in our scope, I can alert it
$scope.data = $scope.applicationdata.data;
$scope.devList = $scope.data[0].permissions;
console.log("data : " + JSON.stringify($scope.data));
console.log("first application data : " + JSON.stringify($scope.devList));
});
$scope.selection = [];
$scope.selection1 = [];
// toggle selection for a given employee by name
$scope.toggleSelection = function toggleSelection(item) {
var idx = $scope.selection.indexOf(item);
var jsonO = angular.copy(item);
jsonO.timestamp = Date.now();
DataService.addTrackedData(jsonO);
$scope.selection1 = DataService.getTrackedData();
// is currently selected
if (idx > -1) {
$scope.selection.splice(idx, 1);
}
// is newly selected
else {
DataService.addSelectedData(item);
$scope.selection = DataService.getSelectedData();
/* $scope.selection.push(item);*/
}
};
});
Problems :
1 : Why is the data of first item not getting loaded? I have done changes in HTML as per my understanding.
2 : How Can I navigate through all items. I will try #John Carpenter's answer. Before that first problem should be resolved.
Please help me, thanks in advance.
OK, so I'm not 100% sure what you want but I'll take a stab at it. In the future, it would be helpful to post less code (probably not the entire project you are working on). It is a good idea to make a simpler example than the "real" one, where you can learn what you need to learn and then go apply it to the "real" code that you have.
Anyways, this example is a simple button that you click on to change what is displayed.
var app = angular.module('MyApplication',[]);
app.controller('MyController', ['$scope', function($scope){
$scope.indexToShow = 0;
$scope.items = [
'item 1',
'item 2',
'item 3'
];
$scope.change = function(){
$scope.indexToShow = ($scope.indexToShow + 1) % $scope.items.length;
};
}]);
.simple-button {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApplication" ng-controller="MyController">
<div ng-repeat="item in items track by $index" ng-show="$index == indexToShow">
{{item}}
</div>
<div class="simple-button" ng-click="change()">click me!</div>
</div>
This is going to be a rather longwinded question, so please bear with me...
I have an array of about 25-30 items. They are sorted through various filters such as brand, type, material, size, etc.. How can I go about building a searchable filter. All of the ones I've seen just include a filter:query | in their filters. However I can't get mine to query my existing array.
Here is what my array looks like, only going to show 1 item to keep size down..
$scope.products = [
{
src: 'images/img/image1.jpg',
name: 'XXX-1A',
brand: 'Brand A',
material: 'dry',
size: '00',
type: 'dry pipe',
color:'red'
}];
Function for filtering (only included 1 to save space):
$scope.brandIncludes = [];
$scope.includeBrand = function(brand) {
var i = $.inArray(brand, $scope.brandIncludes);
if (i > -1) {
$scope.brandIncludes.splice(i, 1);
} else {
$scope.brandIncludes.push(brand);
}
}
$scope.brandFilter = function(products) {
if ($scope.brandIncludes.length > 0) {
if ($.inArray(products.brand, $scope.brandIncludes) < 0)
return;
}
return true;
}
This is what I am using to filter from the HTML, I am using checkboxes to select each filter:
<div class="info" ng-repeat="p in products |
filter:brandFilter |
filter:materialFilter |
filter:typeFilter |
filter:styleFilter">
</div>
My search bar mark up:
<div class="filtering">
<div class="search-sect">
<input name="dbQuery" type="text" placeholder="Search pieces" class="search-input" ng-model="query"/>
</div>
One of the filter's mark up:
<input type="checkbox" ng-click="includeStyle('adaptor')"/>Adaptor<br>
Now that you have all the code, here are some of the things I've tried that don't seem to be running right:
My Attempt:
Search bar:
<input type="text" id="query" ng-model="query"/>
Filter:
<li ng-repeat="p in products | filter:query | orderBy: orderList">
I understand that to some experienced with angular, this is a relatively easy task, but I am just learning and can't seem to wrap my head around searching a query. It's probably a simple solution that I am overlooking. This is my first Angular app and I am trying to bite off more than I can chew in order to learn more.
I appreciate all responses, thanks in advance!
As per request: CodePen
The simple built-in angular filter is not smart enough to to work with your checkbox design, so try writing a custom filter. You will need to bind the checkboxes you mentioned to variables in your scope, e.g. brandFilterIsEnabled. See the tutorial for writing custom filters. Here is a working example.
var myApp = angular.module('myApp', []);
myApp.controller('ctrl', function ($scope) {
$scope.items = [{
name:'foo',
color:'red'
},{
name:'bar',
color:'blue'
},{
name:'baz',
color:'green'
}];
$scope.searchNames = true;
$scope.searchColors = true;
$scope.$watch('searchColors', function(){
$scope.searchKeys = [ $scope.searchNames ? 'name' : null, $scope.searchColors ? 'color' : null ];
});
$scope.$watch('searchNames', function(){
$scope.searchKeys = [ $scope.searchNames ? 'name' : null, $scope.searchColors ? 'color' : null ];
});
});
myApp.filter('advancedSearch', function($filter) {
return function(data, keys, query) {
results = [];
if( !query ){
return data;
} else {
angular.forEach( data, function( obj ){
var matched = false;
angular.forEach( keys, function( key ){
if( obj[key] ){
// match values using angular's built-in filter
if ($filter('filter')([obj[key]], query).length > 0){
// don't add objects to results twice if multiple
// keys have values that match query
if( !matched ) {
results.push(obj);
}
matched = true;
}
}
});
});
}
return results;
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html ng-app="myApp">
<div ng-controller="ctrl">
<input type='checkbox' ng-model='searchNames'>search names</input>
<input type='checkbox' ng-model='searchColors'>search colors</input>
<input type='text' ng-model='query'>search objects</input>
<ul>
<li ng-repeat="item in items | advancedSearch : searchKeys : query">
<span style="color:{{item.color}}">{{item.name}}</span>
</li>
</ul>
</div>
</html>
I have code that populates then dropdownlist and the javascript variable that gets the last item in the list. Now all I want to do is select that last item as the default .What am I missing ?
<div class="row">
<div>
<select ng-init="lastItem" ng-model="congressFilter" ng-options="cc.congressLongName for cc in ccList"></select>
</div>
<div class="grid-style" data-ng-grid="userGrid">
</div>
ccResource.query(function (data) {
$scope.ccList.length = 0;
angular.forEach(data, function (ccData) {
$scope.ccList.push(ccData);
})
//Set default value for dropdownlist?
$scope.lastItem = $scope.ccList[$scope.ccList.length - 1];
});
You simply need to asign a value to congressFilter in your controller.
$scope.congressFilter = 'someVal';
It depends a little on how your data looks however.
It might help to new developers. need to add default id for display default item in option.
The below code sample we add [ $scope.country.stateid = "4" ] in controller $scope to set the default.
var aap = angular.module("myApp", []);
aap.controller("MyContl", function($scope) {
$scope.country = {};
$scope.country.stateid = "4";
$scope.country.states = [{
id: "1",
name: "UP"
}, {
id: "4",
name: "Delhi"
}];
});
<body ng-app="myApp">
<div ng-controller="MyContl">
<div>
<select ng-model="country.stateid" ng-options="st.id as st.name for st in country.states">
</select>
ID : {{country.stateid}}
</div>
</div>
</body>