Angular Js orderBy with numeric field is not working - javascript

In controller I have written code that convert rank into Float
details.rank = '';
$scope.order = function (predicate) {
$scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false;
if (predicate == 'rank') {
for (var i = 0; i < data.countries[$scope.index].cities.length; i++) {
details.rank = parseFloat(data.countries[$scope.index].cities[i].rank);
}
$scope.predicate = predicate;
} else $scope.predicate = predicate;
};
but here I am getting error that ReferenceError: details is not defined
I have json like this:
{
"countries": [{
"country": "India",
"cities": [{
"name": "Bangalore",
"rank": "40"
}, {
"name": "Kolkata",
"rank": "54"
}, {
"name": "Mumbai",
"rank": "32"
}, {
"name": "Chennai",
"rank": "42"
}]
}, {
"country": "China",
"cities": [{
"name": "Guangzhou",
"rank": "111"
}, {
"name": "Beijing",
"rank": "90"
}, {
"name": "Fuzhou",
"rank": "21"
}, {
"name": "Baotou",
"rank": "23"
}]
}]
}
In html if I click header of table then it will sort the table both ascending and descending order but I am unable to do this.
<th>
RANK
<span ng-show="predicate === 'rank'" ng-class="{reverse:reverse}"> </span>
</th>
<ul ng-repeat="city in countryType">
<li ng-repeat="details in city.data.cities | orderBy:predicate:reverse">
<div class="text" id="t1"> {{details.name}} </div>
<div class="text" id="t2"> {{details.rank}}</div>
<div class="text" id="t3"> {{details.population}} </div>
<div class="text" id="t4"> {{details.language}}</div>
</li>
</ul>

You can make a dynamic sorting by clicking on the header divs doing like that :
<ul ng-repeat="city in countryType">
<li>
<div class="text" ng-click="orderListBy('name')"> Name </div>
<div class="text" ng-click="orderListBy('rank')"> Rank</div>
<div class="text" ng-click="orderListBy('population')"> Population </div>
<div class="text" ng-click="orderListBy('language')"> Language</div>
</li>
<li ng-repeat="details in city.data.cities | orderBy:predicate:reverse">
<div class="text" id="t1-{{$index}}"> {{details.name}} </div>
<div class="text" id="t2-{{$index}}"> {{details.rank}}</div>
<div class="text" id="t3-{{$index}}"> {{details.population}} </div>
<div class="text" id="t4-{{$index}}"> {{details.language}}</div>
</li>
</ul>
And in your controller
//initialize values
$scope.predicate = 'rank';
$scope.reverse = false;
$scope.orderListBy = function(attr){
$scope.predicate = attr;
$scope.reverse = !$scope.reverse;
};
Doing so it will revert the sort when re-clicking on the header of a column.
PS : don't forget to dynamically name your IDs in the ng-repeat directive to avoid errors and have a valid HTML code.

Related

Sorting Data from External JS File Numerically by Price

I am creating a ecommerce website and the data is being pulled from what will be an external JS file containing an array of all of the products.
I currently have a "sort" button and want to sort the books by their price which is a numerical value. Depending on the category that is selected, the books on the page should sort from high to low and low to high when the button is clicked.
I have done this in using SQL but never this way, any help is appreciated!
<div class="grid-x grid-padding-0">
<div class="medium-3 cell">
<div class="SubjectContainer">
<div class="float-left">
<div class="filterTitle" style="padding-left: 5px">Choose a subject</div>
<div class="filterctn">
<div class="optionctn">
<input type="checkbox" name="subject" value="accounting" id="accounting">
<label class="filterlabel" for="accounting">Accounting</label>
</div>
<div class="optionctn">
<input type="checkbox" name="subject" value="agriculture" id="agriculture">
<label class="filterlabel" for="business">Agriculture</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="filterTitle">Sort by Price<br>
<small style="padding-top: 10px">(highest to lowest)</small> </div>
<button class="sortBtn" onclick="sorted()">Sort</button>
</div>
Data
<script>
AllSubjects([{
"journalfilter": "accounting",
"journalorder": "1",
"journaltitle": "Accounting I",
"journalprice": "22",
},
{
"journalfilter": "accounting",
"journalorder": "2",
"journaltitle": "Accounting II",
"journalprice": "12",
},
{
"journalfilter": "agriculture",
"journalorder": "3",
"journaltitle": "Agriculture I",
"journalprice": "40",
},
{
"journalfilter": "agriculture",
"journalorder": "4",
"journaltitle": "Agriculture II",
"journalprice": "25",
},
{
"journalfilter": "agriculture",
"journalorder": "5",
"journaltitle": "Agriculture III",
"journalprice": "16",
},
]);
</script>
What about
/* Ascending */
yourArray.sort((a, b) => {
return parseInt(a.journalprice) - parseInt(b.journalprice);
});
/* Descending */
yourArray.sort((a, b) => {
return parseInt(b.journalprice) - parseInt(a.journalprice);
});
I would recommend, that you store the prices as numbers, more specifically integers (so store 1$ as 100), but not as string.

How to filter array with arraylist using ng-repeat

I'm trying to filter an array with a simple array list but I can't seem to figure out how, I tried using a custom filter but I can't make it work.
Edit: I've added more code. Text box Search works fine but when I add the myFilterby on the ng-repeat it no longer filters. I simply want to filter out an array list.
<div class="input-group">
<input type="text" class="form-control" placeholder="Search .." ng-model="searchText">
<span class="input-group-btn">
<button class="btn btn-default" type="button">
<span class="glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</div>
<td ng-repeat="a in product| filter:searchText | filter:myFilterBy">
<img class="avatar" src="img/{{a.image}}" alt="">
<div class="middleT">
<p>{{a.brand}} {{a.model}} </p>
<p>${{a.price}} </p>
</div>
Angular:
var HandleModule = angular.module("HandleModule",['rzModule','ui.bootstrap','angular.filter']);
HandleModule.controller('HandleCtrl',function($scope,$http){
// get data from the server in JSON format
$scope.chk0 = ['apple', 'orange', 'banana'];
$http.get('./loader.php').then(successCallback, errorCallback);
function successCallback(response){
//success code
$scope.product = response.data;
}
function errorCallback(error){
//error code
$scope.product="error";
}
$scope.myFilterBy = function(e) {
return $scope.chk0.indexOf(e) !== -1;
}
PHP:
<?php
$con = mysqli_connect("localhost","root","","product");
$query = "SELECT id, model, brand, price, description, image, FROM fruits ORDER BY id";
$result = mysqli_query($con, $query);
$fruits= array();
while($row = mysqli_fetch_assoc($result))
{
$fruits[] = $row;
}
echo json_encode($fruits);
?>
Used NG-repeat to print out the data separately. I used ng-repeat to display on html
<p ng-repeat="a in products ">
{{a}}
{"id":"1","model":"test1","brand":"orange","price":"4",
"description":"orange sweet and sour","image":"orange.jpg"}
{"id":"2","model":"test2","brand":"banana","price":"3",
"description":"yellow sweet","image":"banana.jpg"}
{"id":"3","model":"test3","brand":"apple","price":"5",
"description":" red sweet crunchy","image":"apple.jpg"}
From what I can decipher from your question and subsequent comments, you are simply trying to filter your product array by search text that is input by the user and a static array.
Your issue is that you are trying to compare an object to an array of strings. To fix your problem you should compare an object property, in this case brand, against the array of strings.
You can see it working below. For simplicity I have removed any code that wasn't essential to this issue.
var HandleModule = angular.module("HandleModule", []);
HandleModule.controller('HandleCtrl', function($scope) {
$scope.chk0 = ['apple', 'orange', 'banana'];
$scope.product = [{
"id": "1",
"model": "test1",
"brand": "orange",
"price": "4",
"description": "orange sweet and sour",
"image": "orange.jpg"
}, {
"id": "2",
"model": "test2",
"brand": "banana",
"price": "3",
"description": "yellow sweet",
"image": "banana.jpg"
}, {
"id": "3",
"model": "test3",
"brand": "apple",
"price": "5",
"description": "red sweet crunchy",
"image": "apple.jpg"
}, {
"id": "4",
"model": "test4",
"brand": "pear",
"price": "6",
"description": "red sweet crunchy",
"image": "pear.jpg"
}];
$scope.myFilterBy = function(e) {
return $scope.chk0.indexOf(e.brand) >= 0;
};
});
<html ng-app="HandleModule">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body ng-controller="HandleCtrl">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search .." ng-model="searchText" />
</div>
<table>
<tbody>
<tr>
<td ng-repeat="a in product| filter:searchText | filter:myFilterBy">
<div>
<p>{{a.brand}} {{a.model}} </p>
<p>${{a.price}} </p>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>

ng-option set default value in Angularjs

I'm having trouble binding my default value to a ng-option. I already searched for the answer to my question but can't seem to find one.
My problem is that I have 3 cascading selects with one model.
default values
vm.roomData.branch = 'Lucena';
vm.roomData.building = 'mhq';
vm.roomData.roomFloor = '3rd Floor';
html
<div class="col-md-4">
<label for="branch">
<strong>Branch</strong>
</label>
<select ng-options="loc as loc.branch for loc in vm.locations" class="form-control" ng-model="vm.roomData.branch">
</select>
<small id="emailHelp" class="form-text text-muted">Select branch.</small>
</div>
<div class="col-md-4">
<label for="building">
<strong>Building</strong>
</label>
<select ng-options="loc as loc.name for loc in vm.roomData.branch.building" ng-model="vm.roomData.building" class="form-control">
</select>
</div>
<div class="col-md-4">
<label for="roomFloor">
<strong>Room Floor</strong>
</label>
<select ng-options="loc.floors as loc for loc in vm.roomData.building.floors" ng-model="vm.roomData.roomFloor" class="form-control">
</select>
</div>
vm.locations data
[
{
"_id": "5a681380b7c41e7df2076819",
"branch": "Lucena",
"__v": 0,
"building": [
{
"name": "MHQ",
"floors": [
"Ground Floor",
"2nd Floor",
"3rd Floor"
]
}
],
"dateCreated": "2018-01-24T05:02:56.465Z"
},
{
"_id": "5a681aecb7c41e7df207681d",
"branch": "Lucban",
"__v": 0,
"building": [
{
"name": "MHQ1",
"floors": [
"ground floor",
"2nd floor"
]
}
],
"dateCreated": "2018-01-24T05:34:36.775Z"
}]
try initializing the default values like this,
$scope.roomData.branch = $scope.locations.find((loc) => loc.branch === 'Lucena');
$scope.roomData.building = $scope.roomData.branch.building.find((br) => br.name.toLowerCase() == 'mhq');
$scope.roomData.roomFloor = '3rd Floor' ;
like
var app = angular.module('testApp', []);
app.controller('testCtrl', function($scope) {
var vm = this;
vm.roomData = {};
vm.locations = [{
"_id": "5a681380b7c41e7df2076819",
"branch": "Lucena",
"__v": 0,
"building": [{
"name": "MHQ",
"floors": [
"Ground Floor",
"2nd Floor",
"3rd Floor"
]
}],
"dateCreated": "2018-01-24T05:02:56.465Z"
},
{
"_id": "5a681aecb7c41e7df207681d",
"branch": "Lucban",
"__v": 0,
"building": [{
"name": "MHQ1",
"floors": [
"ground floor",
"2nd floor"
]
}],
"dateCreated": "2018-01-24T05:34:36.775Z"
}
];
vm.roomData.branch = vm.locations.find((loc) => loc.branch === 'Lucena'); debugger
vm.roomData.building = vm.roomData.branch.building.find((br) => br.name.toLowerCase() == 'mhq');
vm.roomData.roomFloor = '3rd Floor' ;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="testApp" ng-controller="testCtrl as vm">
<div class="col-md-4">
<label for="branch">
<strong>Branch</strong>
</label>
<select ng-options="loc as loc.branch for loc in vm.locations" class="form-control" ng-model="vm.roomData.branch">
</select>
<small id="emailHelp" class="form-text text-muted">Select branch.</small>
</div>
<div class="col-md-4">
<label for="building">
<strong>Building</strong>
</label>
<select ng-options="loc as loc.name for loc in vm.roomData.branch.building" ng-model="vm.roomData.building" class="form-control">
</select>
</div>
<div class="col-md-4">
<label for="roomFloor">
<strong>Room Floor</strong>
</label>
<select ng-options="o as o for o in vm.roomData.building.floors" ng-model="vm.roomData.roomFloor" class="form-control">
</select>
</div>
</body>

Align radio buttons vertically in Angular JS

I'm building a form of radio question types.
Here is code for view:
<div class="form-group" ng-class="{ 'has-error': form.$submitted && form[field.id].$invalid }" ng-if="field.type === 'radio'">
<label for="{{field.id}}">{{field.title}}</label>
<br>
<label ng-repeat="value in field.values">
<input type="radio" id="{{field.id}}" name="field.id" ng-model="formData[field.id]" value="{{value.title}}"> {{value.title}}</label>
<p class="form-group-note" ng-if="field.info" ng-bind="field.info"></p>
<div ng-show="form.$submitted" ng-cloack>
<span class="help-block" ng-show="form['{{field.id}}'].$error.required" ng-if="field.validations.required">Please enter a value, this field is required</span>
</div>
Selected Value is : {{formData[field.id]}}
</div>
JSON data I'm feeding is
{
"groups": [
{
"id": "4_2",
"title": "Passport",
"sections": [
{
"id": "4_2_section",
"fields": [
{
"id": "select_id",
"title": "Select type of question",
"type": "select",
"info": "Always select \"Yes\"",
"size": {
"width": 100,
"height": 1
},
"validations": {
"required": true
},
"values": [
{
"id": 0,
"title": "Not Selected"
},
{
"id": 1,
"title": "Yes"
},
{
"id": 2,
"title": "No"
}
]
}
]
The result I get for the radio questions is like following:
As you can see, all radio buttons are aligned horizontally.
How do I align them vertically?? I mean one radio button on one row.
Add a style to your HTML
.display-block {
display: block;
}
<label class="display-block" ng-repeat="value in field.values">
<input type="radio" id="{{field.id}}" name="field.id" ng-model="formData[field.id]" value="{{value.title}}"> {{value.title}}
</label>
Watch what you want to repeat.
<ul>
<li ng-repeat="value in field.values">
<label for="{{field.id}}"> {{value.title}}</label>
<input type="radio" id="{{field.id}}" name="field.id" ng-model="formData[field.id]" value="{{value.title}}">
</li>
</ul>
Wrap your inputs in ul, li. Below code will help for sure :
HTML:
<form name="myForm" ng-controller="MyCtrl">
<p>Favorite Beatle</p>
<ul>
<li ng-repeat="person in people">
<label>{{person.name}}
<input type="radio" ng-model="$parent.name" name="name" value="{{person.name}}" required />
</label>
</li>
</ul>
<p><tt>myForm.$invalid: {{myForm.$invalid}}</tt></p>
<button ng-disabled="myForm.$invalid">Submit</button>
</form>
JavaScript :
function MyCtrl($scope) {
$scope.people = [{
name: "John"
}, {
name: "Paul"
}, {
name: "George"
}, {
name: "Ringo"
}];
}
JsFiddle : https://jsfiddle.net/nikdtu/zp2131zw/

AngularJS retrieve data and display with ng-change

I have a function to add records to database.
What I need to do is when I select an option all necessary fields must be filled with data.
I'm just new with angularjs and want to learn how to do this.
below is my code.
template
<div class="col-md-10">
<div class="col-md-12">
<div class="form-group">
<label>Select Employee </label>
<select class="form-control" ng-change='getData()' id='empId' ng-model="empId" ng-options="opt.id as opt.value for opt in employees">
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Department <i class="required">*</i></label>
<select class="form-control" ng-change ="getPos()" ng-model="data.Employee.departmentId" ng-options="opt.id as opt.value for opt in deparments" data-validation-engine="validate[required]">
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Position <i class="required">*</i></label>
<select class="form-control" ng-model="data.Employee.positionId" data-validation-engine="validate[required]">
</select>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Rate <i class="required">*</i></label>
<input type="text" class="form-control" ng-model="data.Employee.rate" data-validation-engine="validate[required]">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Loan Amount <i class="required">*</i></label>
<input type="text" class="form-control" ng-model="data.Loan.amount" data-validation-engine="validate[required]">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Period (months) <i class="required">*</i></label>
<input type='text' class="form-control" ng-model="data.Loan.amount" data-validation-engine="validate[required]">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label>Date Start<i class="required">*</i></label>
<input type="text" class="form-control text-left" id="dateStart" ng-model="data.Employee.contractFrom" data-validation-engine="validate[required]" id="contractFrom">
</div>
</div>
</div>
controller
app.controller('LoanAddController', function($scope, Loan,Select) {
$('#form').validationEngine('attach');
$scope.load = function() {
Loan.get({ id: $scope.employeeId }, function(e) {
$scope.data = e.data;
});
Select.get({ code: 'departments' }, function(e) {
$scope.departments = e.data;
});
// employees selection
Select.get({ code: 'employees' }, function(e) {
$scope.employees = e.data;
});
Select.get({ code: 'positions' }, function(e) {
$scope.positions = e.data;
});
}
$('#dateStart').datepicker({
format: 'mm/dd/yyyy',
autoclose: true
});
$scope.load();
// save loan data
$scope.save = function() {
valid = $("#form").validationEngine('validate');
if (valid) {
Loan.save($scope.data, function(e) {
if (e.ok) {
$.gritter.add({
title: 'Successful!',
text: e.msg,
});
window.location = '#/loans';
} else {
$.gritter.add({
title: 'Warning!',
text: e.msg,
});
}
});
}
}
});
some JSON data
{
"ok": true,
"data": [
{
"Loan": {
"id": "1",
"employeeId": "9",
"dateApplied": "2015-10-15",
"amount": "5000",
"period": "6",
"startdate": "2015-11-01",
"status": "pending",
"visible": true,
"created": "0000-00-00 00:00:00",
"modified": "0000-00-00 00:00:00"
},
"Employee": {
"id": "9",
"employeeNumber": "24681012",
"lastName": "Cortez",
"firstName": "Kim Carlo",
"middleName": "Mira",
"departmentId": "1",
"positionId": "4",
"rate": "600",
"typeId": "8",
"dateHired": "2015-10-22",
"contractFrom": "2015-10-31",
"contractTo": "2016-10-31",
"image": "9.PNG",
"visible": true,
"created": "2015-10-07 08:25:56",
"modified": "2015-10-07 08:25:56"
},
"Department": {
"id": null,
"code": null,
"name": null,
"description": null,
"visible": null,
"created": null,
"modified": null
},
"Position": {
"id": "9",
"name": "Bell boy",
"departmentId": "6",
"description": "bellboy, ice cream vendor",
"visible": true,
"created": "2015-10-06 13:52:43",
"modified": "2015-10-06 13:52:43"
}
}
],
"paginator": {
"page": 1,
"current": 1,
"count": 1,
"prevPage": false,
"nextPage": false,
"pageCount": 1,
"order": {
"Loan.id": "ASC"
},
"limit": 25,
"options": [
],
"paramType": "named"
}
}
I have to populate the fields for employee details.
Any help would be appreciated.
Thank guys,

Categories