AngularJS - Dynamic Checkboxes to hide/show Divs - javascript

I'm new to front-end web development. I am creating checkboxes dynamically using AngularJS.
<div ng-repeat="x in Brands" style="margin-left: 20px">
<input type="checkbox" ng-model="newObject[x.product_brand]">
<label> {{ x.product_brand }} </label>
</div>
Following the methods given on the links below, I want to hide/show divs using
using the dynamically created checkboxes.
Dynamic ng-model
ng-show
Here's the code-
<div class="item panel panel-default" ng-repeat="x in Brands" ng-show="newObject[x.product_brand]">
<div class="panel-heading">
{{x.product_brand}}
</div>
<div class="panel-body">
</div>
</div>
Controller-
app.controller('BrandController', function($scope, $http) {
getProductsInfo();
function getProductsInfo() {
$http.get("sql.php").success(function(data) {
$scope.Brands = data;
});
};
});
But it is not working. Checking/Unchecking the checkboxes does nothing.

I think you need something like this runnable fiddle. This kind of handle is easy to manage with AngularJS. Welcome =) !!! Please note: The $timeout is to simulate your async $http request - its not a part of the solution.
View
<div ng-controller="MyCtrl">
<div ng-repeat="x in Brands" style="margin-left: 20px">
<input type="checkbox" ng-model="x.active">
<label> {{ x.product_brand }} </label>
</div>
<div class="item panel panel-default" ng-repeat="x in Brands" ng-show="x.active">
<div class="panel-heading">
{{x.product_brand}}
</div>
<div class="panel-body">
</div>
</div>
</div>
AngularJS demo application
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope, $timeout) {
$scope.Brands = [];
init();
function init () {
$timeout(function () {
$scope.Brands = [{
product_brand: 'brand 1'
},{
product_brand: 'brand 2'
},{
product_brand: 'brand 3'
},{
product_brand: 'brand 4'
}];
});
}
});

Probably it is not working because you never defined newObject on the $scope. So actually you are trying to access undefined[x.product_brand].
Something like $scope.newObject = {}; in your Controller should do the trick.

Related

Angular - loop over nested javascript arrays

How can I use ng-repeat to loop over data that contains many nested array data?
I have data that will have many "Segments"
Example:
confirm.booking.flightData[0].Segments[0].FlightNumber
confirm.booking.flightData[0].Segments[1].FlightNumber
confirm.booking.flightData[0].Segments[2].FlightNumber
I have done both ng-repeat with angular, and without angular I would end up resorting to javascript that loops over data and creates the html dynamically, but I wish to do this the ANGULAR way.. HOW?
HTML with Angular/Javascript Arrays:
<div class="container-fluid">
<div class="row">
<div class="col-md-4">
<span style="font-weight: bold;">Flight</span>
</div>
<div class="col-md-4">
<span style="font-weight: bold;">Departs</span>
</div>
<div class="col-md-4">
<span style="font-weight: bold;">Arrives</span>
</div>
</div>
<div class="row">
<div class="col-md-4">
{{confirm.booking.flightData[0].Segments[0].FlightNumber}}
</div>
<div class="col-md-4">
({{confirm.booking.flightData[0].Segments[0].DepartureAirport}})
</div>
<div class="col-md-4">
({{confirm.booking.flightData[0].Segments[0].ArrivalAirport}})
</div>
</div>
</div>
Nesting can be done in repeats, but repeating too much in ng-repeats can be costly in terms of performance as angular creates scopes for each element repeated. Hence, filtering data till the perfect abstracted values that you need in terms of html should be done in the js file.
For eg: if u need only segements in the html form do this, or if u need even flight data in html form follow #Rachel's post
<ul data-ng-repeat="item in confirm.booking.flightData[0].Segments">
<li>{{ item.FlightNumber}}</li>
</ul>
Let's say your data is in flightdetails, then you can go about it like this:
<div ng-repeat="a in flightdetails ">
<div ng-repeat="b in a.booking">
<div ng-repeat="c in b.flightdata">
<div ng-repeat="d in c.segments">
{{d.flightnumber}}
</div>
</div>
</div>
</div>
You can use nested ng-repeat to bind your data - see a demo below:
angular.module("app", []).controller("ctrl", function($scope) {
$scope.confirm = {
booking: {
flightData: [{
Segments: [{
FlightNumber: 1
}, {
FlightNumber: 2
}]
}, {
Segments: [{
FlightNumber: 3
}, {
FlightNumber: 4
}]
}]
}
}
// console.log($scope.confirm);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="wrapper" ng-app="app" ng-controller="ctrl">
<div ng-repeat="x in confirm.booking.flightData">
Data {{$index + 1}}:
<div ng-repeat="y in x.Segments">
<div>Flight No: {{y.FlightNumber}}</div>
</div>
<br/>
</div>
</div>
If you want to display only the following:
confirm.booking.flightData[0].Segments[0].FlightNumber
confirm.booking.flightData[0].Segments[1].FlightNumber
confirm.booking.flightData[0].Segments[2].FlightNumber
then you can use limitTo - see demo below:
angular.module("app", []).controller("ctrl", function($scope) {
$scope.confirm = {
booking: {
flightData: [{
Segments: [{
FlightNumber: 1
}, {
FlightNumber: 2
}]
}, {
Segments: [{
FlightNumber: 3
}, {
FlightNumber: 4
}]
}]
}
}
// console.log($scope.confirm);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="wrapper" ng-app="app" ng-controller="ctrl">
<div ng-repeat="x in confirm.booking.flightData | limitTo : 1">
Data {{$index + 1}}:
<div ng-repeat="y in x.Segments">
<div>Flight No: {{y.FlightNumber}}</div>
</div>
<br/>
</div>
</div>
I created an example here:
http://codepen.io/ackzell/pen/ENBymo
It ultimately looks like this, but check the pen as it has some more info:
<ul>
<li ng-repeat="flight in vm.flightData">
<ul>
<li ng-repeat="segment in flight.Segments">
<em>FlightNumber</em> {{ segment.FlightNumber }}
<br />
<em>Departure:</em> {{ segment.DepartureAirport }}
<br />
<em>Arrival:</em> {{ segment.ArrivalAirport }}
</li>
</ul>
</li>
</ul>
Nesting ng-repeats would help, but maybe you want to give your data some treatment first.

nested ng-repeat with json and rest api call back

I am trying to make a UI using list of product in a json(products.json) file on local and their availability in number from wp rest api call back in html(ionic) I have this:
Controller:
.controller('ShopCtrl', function($scope, $ionicActionSheet, BackendService, CartService, $http, $sce ) {
$scope.siteCategories = [];
$scope.cart = CartService.loadCart();
$scope.doRefresh = function(){
BackendService.getProducts()
.success(function(newItems) {
$scope.products = newItems;
console.log($scope.products);
})
.finally(function() {
// Stop the ion-refresher from spinning (not needed in this view)
$scope.$broadcast('scroll.refreshComplete');
});
};
$http.get("http://example.com/wp-json/wp/v2/categories/").then(
function(returnedData){
$scope.siteCategories = returnedData.data;
console.log($scope.siteCategories);
}, function(err){
console.log(err);
});
Template view:
<div ng-repeat = "product in products">
<div class="item item-image" style="position:relative;">
<img ng-src="{{product.image}}">
<div ng-repeat = "siteCategory in siteCategories">-->
<button class="button button-positive product-price" ng-click="addProduct(product)">
<p class="white-color product-price-price">post <b>{{siteCategory[$index].count}}</b></p>
</button>
</div>
</div>
<div class="item ui-gradient-deepblue">
<h2 class="title white-color sans-pro-light">{{product.title}} </h2>
</div>
<div class="item item-body">
{{product.description}}
</div>
</div>
so how can I achieve that? I tried to use nested ng-repeat but it didn't work out.

Angular Material Dropdown with Router ( UI - Router )

when user clicks on the person it calls a form (form.html) using ui-router logic defined in app.js. I have 2 type of drop-down boxes, (1) using select tag and (2) using md-select tag. Pages works fine until i click on 2nd dropdown, which doesn't open the dropdown option window instead it freezes the page. I added code here in plunker however page routing doesn't work in plunker but you can reference the code.
index.html
<body ng-app="myApp">
<div class="col-sm-3 sidenav">
<div class="well"> <!-- container to hold status bar and form -->
<nav class="navbar navbar-default navbar-custom">
<a style="font-size:2.5em;position: absolute; left: 50%;" ui-sref="form"><span class="glyphicon glyphicon-user fa-5x" id="Icon"></span></a>
</nav>
<div class="column-nav-form" ui-view="formColumn" > <!--holds the form -->
</div>
</div>
</div>
</body>
form.html
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<h4> Normal DropDown </h4>
<select ng-model="selectedName" ng-options="x for x in names">
</select>
</div>
<p>I have three elements in my list, you should be able to pick whichever you like</p>
<div ng-app="myApp" ng-controller="myCtrl">
<h4> Material DropDown </h4>
<md-select onclick='console.log("clicked")' ng-model="selectedFilter" placeholder="Select a filter"> <md-select-label>{{ selectedFilter.name }}</md-select-label>
<md-option ng-value="opt" ng-repeat="opt in filters">{{ opt.name }}</md-option>
</md-select>
</div>
</body>
app.js
var myApp = angular.module('myApp', [ 'ngAnimate', 'ngAria', 'ui.bootstrap', 'ngMaterial', 'ngMessages', 'ui.router' ]);
//routing
angular.module('myApp').config(function ($stateProvider){
$stateProvider
.state('form', {
url:"/form",
views: {
"listColumn": {
},
"formColumn": {
templateUrl: "/form.html"
}
}
})
});
//dropdown
myApp.controller('myCtrl', function($scope) {
//log
console.log($scope.names);
$scope.names = ["Emil", "Tobias", "Linus"];
$scope.filters = [
{
value: 'mine',
name: 'Assigned to me'
},
{
value: 'undefined',
name: 'Unassigned'
},
{
value: 'all',
name: 'All Tickets'
},
{
value: 'new',
name: 'New Tickets'
}
];
//log
console.log($scope.filters);
console.log($scope.selectedFilter);
});
http://plnkr.co/edit/SB7MUM44Ly01aWyL5M28?p=preview
View upon clicking person icon
Note: Dropdown for md-select doesn't load.
Thanks in advance
Changed .css and .js version to have the same and it fixed it.
angular-material.js ( v 1.0.6 )
angular-material.css ( v 1.0.6 )
Links:
<link rel="stylesheet" href="https://rawgit.com/angular/bower-material/master/angular-material.css">
<script src="https://rawgit.com/angular/bower-material/master/angular-material.js"></script>-->

angular clear form

Totally new to angular and appreciate any help received. I'm trying to build a satisfaction app in angular, I am using ng-show to pose the questions one at a time and collecting the data and sending it to firebase at the end. The difficulty I am having is clearing the answers previously give. I have tried resetting the scope and using $setPristine() but keep getting an error.
HTML
<div id = "question" class="row" ng-show="question">
<div id="badResponse" ng-click="selectResponse('bad')">
</div>
<div id="goodResponse" ng-click="selectResponse('good')">
</div>
</div>
<div ng-show="why">
<ul ng-repeat="option in whyOptions">
<li><input type="checkbox" class="reason" checklist-model="form.why" checklist-value="option">{{option}}</li>
</ul>
<button id ="enterBtn" ng-click="responseReason()">Next</button>
</div>
<div ng-show="more" class="more">
<button id ="skipBtn" ng-click="moreInfo()">{{form.extraInfo.length != 0 ? 'Next' : 'Skip'}}</button>
</div>
<div ng-show="thankYou">
<button id ="thankYouBtn" ng-click="thankYouFunction()">Home</button>
</div>
JS
$scope.form = {
experience: '',
extraInfo: ''
};
$scope.whyOptions = [
'reason 1',
'reason 2',
];
$scope.selectResponse = function(response) {
$scope.form.experience = response;
};
$scope.thankYouFunction = function() {
$scope.responses.$add({
customerRsponse: $scope.form
});
$scope.form.$setPristine();
};
});

How to make template without ng-repeat and pass data to $scope with angular-drag-and-drop-lists?

I want to use angular-drag-and-drop-lists with my own grid template to WYSIWYG editor. How to build my own HTML template without ng-repeat so it will be able to drop items in any predefined column and store information in $scope in which column item has been dropped?
I want to store dropped items in columns array:
.controller('DragDropGrid', ['$scope',
function($scope) {
$scope.layouts = {
selected: null,
templates: [
{name: "Plugin", type: "item", id: 2},
],
columns: [],
oldaproachcolumns: [
"A": [
],
"B": [
]
}
]
};
}
]);
This is currently not a working template. On drop it throws the error "undefined is not an object (evaluating 'targetArray.splice')":
<div ng-include="'grid.html'"></div>
<script type="text/ng-template" id="grid.html">
<div class="col-md-12 dropzone box box-yellow">
<div class="row template-grid" dnd-list="list">
<div class="col-xs-12 col-md-8" ng-repeat="item in list" dnd-draggable="item" ng-include="item.type + '.html'">Header</div>
<div class="col-xs-6 col-md-4">News</div>
</div>
</div>
</script>
<script type="text/ng-template" id="item.html">
<div class="item">Plugin {{item.id}}</div>
</script>
This is the standard working aproach:
<div class="row">
<div ng-repeat="(zone, list) in layouts.oldaproachcolumns" class="col-md-3">
<div class="dropzone box box-yellow">
<h3>{{zone}}</h3>
<div ng-include="'list.html'"></div>
</div>
</div>
</div>
<script type="text/ng-template" id="list.html">
<ul dnd-list="list">
<li ng-repeat="item in list" dnd-draggable="item" dnd-effect-allowed="move" dnd-moved="list.splice($index, 1)" dnd-selected="layouts.selected = item" ng-class="{selected: layouts.selected === item}" ng-include="item.type + '.html'">
</li>
</ul>
</script>
Based on this example: demo
How to build my own HTML template without ng-repeat
Use $templateCache and a for loop as an alternative:
var app = angular.module('foo', []);
function bop(model, data)
{
return data ? model : 'foo';
}
function baz()
{
return bop;
}
function foo($templateCache)
{
var i = 0, len = 5, bar = "";
for (i; i < len; i++)
{
bar = bar.concat("<li>",i,"<p ng-include=\u0022'foo'\u0022></p></li>");
}
$templateCache.put('listContent', bar);
}
angular.module('foo').filter('baz', baz);
app.run(foo);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="foo">
<script type="text/ng-template" id="foo">
<span>hi</span>
</script>
<input ng-model="dude">
<ul ng-include="'listContent' | baz:dude"></ul>
</div>
References
AngularJS: API: $templateCache
AngularJS: Is there a better way to achieve this than the one specified?

Categories