AngularJS Custom filter using radio button - angularjs

<div ng-repeat="item in places">
<input type="radio" name="rdnPriority" value="{{item}}" ng-checked="exists(item,selected)" ng-click="toggle(item,selected)" >{{item}}<label>
var app = angular.module("myModule", ['ngMaterial', 'ngMessages']);
app.controller("GetTicketDetails", function ($scope, $http, $interval) {
$scope.GetOrders = function () {
var url = window.location.search;
url = url.replace("?", ''); // remove the ?
//alert(url);
debugger;
$http({
url: "../api/GetOrderDetailByDate",
method: "GET"
}).then(function (response) {
console.log(response.data);
$scope.ListTicketDetails = response.data;
$scope.TotalTickets = response.data.length;
$scope.selected = [];
$scope.places = [];
// when user clicks on checkbox, change selected list
$scope.toggle = function (item, list) {
var idx = list.indexOf(item);
if (idx > -1) list.splice(idx, 1);
else list.push(item);
};
// is item exists in list
$scope.exists = function (item, list) {
debugger;
debugger;
if (scope.checked == item) {
scope.checked = false;
}
return list.indexOf(item) > -1;
};
// process user data and prepare whole places
angular.forEach($scope.ListTicketDetails, function (x, key) {
if ($scope.places.indexOf(x.OrderStatus) == -1) {
//$scope.recordLimit = 5;
$scope.places.push(x.OrderStatus);
}
});
}
app.filter('SelectedTags', function () {
// filter to check array of elements
return function (users, tags) {
return users.filter(function (x) {
if (tags.indexOf(x.OrderStatus) != -1) {
return true;
} else if (tags.length == 0) {
return true;
}
return false;
});
};
})
Hello , I have written a AngularJS Custom filter that filters the orders based on status using RadioButton Check . The problem is data is filtering but Radio Button I need to double click one click for Uncheck existing checked and next check othr status . Is there a way i can achieve that with just single check on there options of radio button .
{{Item}} is filtering all orderstatus from array and rendering radio button Inputs options.
Please help

Related

Delay loading data in Angular JS

I have code like this
(function (app) {
app.controller('productListController', productListController)
productListController.$inject = ['$scope', 'apiService', 'notificationService', '$ngBootbox', '$filter'];
function productListController($scope, apiService, notificationService, $ngBootbox, $filter) {
$scope.products = [];
$scope.page = 0;
$scope.pagesCount = 0;
$scope.getProducts = getProducts;
$scope.keyword = '';
$scope.search = search;
$scope.deleteProduct = deleteProduct;
$scope.selectAll = selectAll;
$scope.deleteMultiple = deleteMultiple;
function deleteMultiple() {
var listId = [];
$.each($scope.selected, function (i, item) {
listId.push(item.ID);
});
var config = {
params: {
checkedProducts: JSON.stringify(listId)
}
}
apiService.del('/api/product/deletemulti', config, function (result) {
notificationService.displaySuccess('Deleted successfully ' + result.data + 'record(s).');
search();
}, function (error) {
notificationService.displayError('Can not delete product.');
});
}
$scope.isAll = false;
function selectAll() {
if ($scope.isAll === false) {
angular.forEach($scope.products, function (item) {
item.checked = true;
});
$scope.isAll = true;
} else {
angular.forEach($scope.products, function (item) {
item.checked = false;
});
$scope.isAll = false;
}
}
$scope.$watch("products", function (n, o) {
var checked = $filter("filter")(n, { checked: true });
if (checked.length) {
$scope.selected = checked;
$('#btnDelete').removeAttr('disabled');
} else {
$('#btnDelete').attr('disabled', 'disabled');
}
}, true);
function deleteProduct(id) {
$ngBootbox.confirm('Are you sure to detele?').then(function () {
var config = {
params: {
id: id
}
}
apiService.del('/api/product/delete', config, function () {
notificationService.displaySuccess('The product hase been deleted successfully!');
search();
}, function () {
notificationService.displayError('Can not delete product');
})
});
}
function search() {
getProducts();
}
function getProducts(page) {
page = page || 0;
var config = {
params: {
keyword: $scope.keyword,
page: page,
pageSize: 20
}
}
apiService.get('/api/product/getall', config, function (result) {
if (result.data.TotalCount == 0) {
notificationService.displayWarning('Can not find any record.');
}
$scope.products = result.data.Items;
$scope.page = result.data.Page;
$scope.pagesCount = result.data.TotalPages;
$scope.totalCount = result.data.TotalCount;
}, function () {
console.log('Load product failed.');
});
}
$scope.getProducts();
}
})(angular.module('THTCMS.products'));
So my problem is when i loading data the application take me some time to load data.
I need load data as soon as
Is the any solution for this?
Since you are loading data via api call, there will be a delay. To handle this delay, you should display a loading screen. Once the data is loaded, the loading screen gets hidden and your main screen is visible. You can achieve this using $http interceptors.
See : Showing Spinner GIF during $http request in angular
The api-call is almost certainly causing the delay. Data may be received slowly via the api-call so you could display any sort of loading text/image to notify the use that the data is being loaded.
If u want the data ready at the time when controller inits, u can add a resolve param and pass the api call as a $promise in the route configuration for this route.

AutoComplete Typehead in AngularJS

There is Typehead i have placed in input text box, which reveal the dropdown of the list. But i want when the user enter any item and which is not available in the list. By clicking Add button it should pop-up "No item"...
Refer to the
Code is here
var app = angular.module('myApp', ['ngAnimate','ui.bootstrap']);
app.controller('NameCtrl', function ($scope,$http){
$http.get("lib/data.txt").success(function(res){
$scope.selected = undefined;
$scope.states = res;
});
$scope.names = [];
$scope.addName = function() {
if($scope.ww != '' ){
$scope.names.push({
'x1':$scope.enteredName,
'qty':$scope.ww,
'p1':$scope.enteredName.p
});
$scope.enteredName = [];
$scope.ww = '';
$scope.tp = '';
}
else if ($scope.ww = '')
{
alert("hi");
} else {}
};
$scope.removeName = function(name) {
var i = $scope.names.indexOf(name);
$scope.names.splice(i, 1);
};
$scope.edit = function(name, idx){
$scope.enteredName = $scope.states.find((item) => item.p === name.p1);
$scope.sel = name.tp;
$scope.ww = name.qty;
$scope.names.splice(idx, 1);
};
$scope.isCollapsed = true;
});
You can add the attribute : typeahead-editable=false
which will make your ng-model empty if the entry is not in the list. Then you can manage an empty model to add your "No-item" entry.
here is the documentation : (Defaults: true) : Should it restrict model values to the ones selected from the popup only ?

Angular and laravel infinte-scroll not working correctly

Angular loads new pages just by moving the scroll bar. Not when it reaches the bottom. It even loads new posts when i scroll up.
app.factory('Recipes', function ($http) {
var Recipes = function () {
this.recipes = [];
this.loading = false;
this.page = 1;
};
Recipes.prototype.nextPage = function () {
var url = 'api/recipes?page=' + this.page;
if (this.loading) return;
this.loading = true;
$http.get(url)
.success(function (data) {
console.log(this.page);
for (var i = 0; i < data.data.length; i++) {
this.recipes.push(data.data[i]);
}
this.page++;
this.loading = false;
}.bind(this));
};
return Recipes;
});
app.controller('RecipesCtrl', function ($scope, $http, Recipes) {
$scope.recipes = new Recipes();
});
This is the angular part. This is the laravel part:
Route::group(['prefix' => 'api'], function () {
Route::get('recipes', [
'as' => 'recipe.all',
'uses' => 'RecipeController#recipes'
]);});
And this is the html part:
<div ng-controller="RecipesCtrl">
<div class="recipe row" infinite-scroll="recipes.nextPage()" infinite-scroll-distance="1"
infinite-scroll-disabled='recipes.loading'>
<div ng-repeat="recipe in recipes.recipes | orderBy:sortOrder:sortReverse | limitTo:myLimit">
...
</div>
</div>
</div>
First Problem: Why does infinite-scroll load more content constantly?
infinite-scroll-distance is set to 1 in your code. This means that when the element is within 1000 pixels of the browsers bottom the directive will fetch more data.
If you change this to a value closer to 0, the user will have to scroll further for the trigger to get activated.
Second Problem: How do I prevent the directive from loading more content, when there is no more content to return?
One solution to stopping the directive from continuously loading more data is by setting the recipes.loading = true; when the returned data is empty.
As such:
.success(function (data) {
console.log(this.page);
for (var i = 0; i < data.data.length; i++) {
this.recipes.push(data.data[i]);
}
this.page++;
this.loading = false;
recipes.loading = true; // This should prevent more code from being loaded.
}

Initialize select box with the retrieved id

I am new to angular js and I am trying to code an edit page which contains a select box. It has id as the value and name as the display label.
<select class="form-control" ng-model="item.user"
ng-options="user.id as user.loginName for user in Users" ng-disabled="true" >
<!-- ng-init="item.user=userId" -->
<option value="">Select User</option>
</select>
As I am adding edit page, I retrieve the values from server side and it returns the id for the select box. When I used ng-init to set the value (See the commented ng-init code), it displays only the Select User option. When I manually provide a user id like
ng-init="item.user=3"
The corresponding user is displayed correctly in the select box. I tried setting the value from controller as,
$scope.item.user = result.userid;
alert($scope.item.user);
The alert doesn't throw but when I alert result.userid above it, it works fine. What could be the problem?
EDIT 1:
Sample controller(controller.js):
function SampleController(Sample, $scope, $http,$compile, $filter, $modal, $timeout, DTOptionsBuilder, DTColumnBuilder,DTInstances) {
$scope.edit = function(id) {
//Retrieves value for dropdown
selectbox.userList(function(result) {
$scope.Users = result.content;
});
// alert("EDIT action initiated ID : " + id);
var params = {
id : id
};
$scope.sampleObj= Sample.view(params, function() {
$scope.$state.go('sampleEdit', {id:id});
});
}
}
state (config.js):
.state('admin.editSample', {
url: '/editSample/:id',
templateUrl: 'sample/editSample.html',
data: { pageTitle: 'Edit Sample'},
controller: SampleEditController
})
SampleEditController(controller.js):
var sampleEditController = function($stateParams, $scope, $http){
var params = {};
params.id = $stateParams.id;
var url = "sample/edit";
$http.get(url, {
params : params
}).success(function(result) {
alert("Users: " + $scope.Users); //Here it alerts undefined
for(var i = 0; i < $scope.Users.length && !$scope.item.user;i++){
if ($scope.Users[i].id === result.id) {
$scope.item.user = $scope.Users[i];
}
}
})
Edit 2:
SampleRepository
#Repository
public interface IUserRepository extends JpaRepository<Employee, Long>{
#Query("select new com.sample.application.model.dto.SampleInfo(c.id,e.fullName,"
+ "c.accountExpired,c.accountLocked,c.rowCreated,c.enabled,c.rowAltered, c.password, c.passwordExpired, c.loginName, c.languageFluency) "
+ " from Employee c left join c.person e order by c.id asc")
Page<IUserInfo> getList(Pageable pageable);
}
Edit 3:
services.js
.factory('sample', ['$http', function ($http) {
return {
userList : function(result){
$http.get('sample/list').success(result);
} }
I also tried this inside the controller,
userRoleEditController:
$http.get(url, {
params : params
}).success(function(res) {
selectbox.userList(function(result) {
$scope.User = result.content;
for(var i = 0; i < $scope.User.length; i++){
if ($scope.User[i].id === res.empId) {
$scope.item.user = $scope.User[i];
}
}
});
})
With this I am able to get $scope.User. I tried alerting $scope.item.user after $scope.item.user = $scope.User[i]; but it didn't work and i didn't get the value in the drop down box.
ng-init shouldn't be used to initilise as mentioned in the documentation. Instead to set the selected item set item.user in the controller.
To get the user with id as 3 you will need to loop through the users until you find the correct user. Once found set $scope.item.user to the user:
for (var i = 0; i < $scope.Users.length && !$scope.item.user; i++) {
if ($scope.Users[i].id === 3) {
$scope.item.user = $scope.Users[i];
}
}
Edit:
In your service return the promise from $http:
.factory('sample', ['$http', function ($http) {
return {
userList : function(){
return $http.get('sample/list');
}
}
}
Then in your controller where this is called you would do something like this to call this service method, handle the promise, set the users and the user on $scope:
sample.userlist().then(function (response) {
$scope.Users = response.data;
for (var i = 0; i < $scope.Users.length && !$scope.item.user; i++) {
if ($scope.Users[i].id === 3) {
$scope.item.user = $scope.Users[i];
}
}
});

$watch not updating scope variable

First I want to say that I am a complete beginner in AngularJS and just attempting to understand the basic concepts. I have a background in Java and PHP.
I am building a part of a website. Right now the angular app only consists of opening and closing 2 drop down menus registrationDropDown and loginDropDown. I want them to work so that only one can be open at a time ie. if I open one, and the other is already open, the older one is forced to close.
I have a service to manage the variables that determine whether the drop downs should be open or closed and 2 controllers, one for login and one for registration, both include $watch for the respective variables.
THE PROBLEM
I want the app to work so that only one of the drop downs can be open at one time.
JSFIDDLE: http://jsfiddle.net/F5p6m/3/
angular.module("ftApp", [])
.factory('dropDownService', function () {
var loginDropDownStatus = false;
var registrationDropDownStatus = false;
return {
getLoginDropDownStatus: function () {
return loginDropDownStatus;
},
showLoginDropDown: function () {
console.log("showing login drop down");
registrationDropDownStatus = false;
loginDropDownStatus = true;
console.log("loginDropDownStatus" + loginDropDownStatus + "registrationDropDownStatus" + registrationDropDownStatus);
},
hideLoginDropDown: function () {
console.log("hiding login drop down");
loginDropDownStatus = false;
console.log("loginDropDownStatus" + loginDropDownStatus);
},
getRegistrationDropDownStatus: function () {
return registrationDropDownStatus;
},
showRegistrationDropDown: function () {
console.log("showing registration drop down");
registrationDropDownStatus = true;
loginDropDownStatus = false;
console.log("registrationDropDownStatus" + registrationDropDownStatus);
},
hideRegistrationDropDown: function () {
console.log("hiding registration drop down");
registrationDropDownStatus = false;
console.log("registrationDropDownStatus" + registrationDropDownStatus);
}
};
}) .controller("LoginDropDownController", function ($scope, dropDownService) {
$scope.loginDropDownStatus = dropDownService.getLoginDropDownStatus();
$scope.$watchCollection('loginDropDownStatus', function(newValue, oldValue) {
console.log("watcher is working");
console.log("value is " + newValue + oldValue);
console.log("LOGIN new value is " + newValue);
$scope.loginDropDownStatus = newValue;
});
$scope.toggleDropDown = function () {
if ( $scope.loginDropDownStatus == false ) {
dropDownService.showLoginDropDown();
dropDownService.hideRegistrationDropDown();
$scope.loginDropDownStatus = true;
} else if ( $scope.loginDropDownStatus == true ) {
dropDownService.hideLoginDropDown();
$scope.loginDropDownStatus = false;
}
};
})
.controller("RegistrationDropDownController", function ($scope, dropDownService) {
$scope.registrationDropDownStatus = dropDownService.getRegistrationDropDownStatus();
$scope.$watch('registrationDropDownStatus', function(newValue, oldValue) {
console.log("watcher is working");
console.log("value is " + newValue + oldValue);
console.log("new value is " + newValue);
$scope.registrationDropDownStatus = newValue;
});
$scope.toggleDropDown = function () {
if ( $scope.registrationDropDownStatus == false ) {
dropDownService.showRegistrationDropDown();
dropDownService.hideLoginDropDown();
$scope.registrationDropDownStatus = true;
} else if ( $scope.registrationDropDownStatus == true ) {
dropDownService.hideRegistrationDropDown();
$scope.registrationDropDownStatus = false;
}
};
})
Edit:
Here is probably the shortest option:
angular.module("ftApp", [])
.controller("ctrl", function ($scope) {
$scope.toggle = function(menu){
$scope.active = $scope.active === menu ? null : menu;
}
})
FIDDLE
One controller, no service.
Previous Answer:
I think you have quite a bit of code to get something very simple done. Here is my solution:
angular.module("ftApp", [])
.service('dropDownService', function () {
this.active = null;
this.toggle = function(menu){
this.active = this.active === menu ? null : menu;
}
})
.controller("LoginDropDownController", function ($scope, dropDownService) {
$scope.status = dropDownService;
$scope.toggleDropDown = function () {
dropDownService.toggle("login");
};
})
.controller("RegistrationDropDownController", function ($scope, dropDownService) {
$scope.status = dropDownService;
$scope.toggleDropDown = function () {
dropDownService.toggle("reg");
};
})
FIDDLE
You can make it even shorter by only using one controller. You wouldn't even need the service then.
You are overcomplicating things. All you need your service to hold is a property indicating which dorpdown should be active.
Then you can change that property's value from the controller and check the value in the view to determine if a dropdown should be shown or hidden.
Something like this:
<!-- In the VIEW -->
<li ng-controller="XyzController">
<a ng-click="toggleDropdown()">Xyz</a>
<div ng-show="isActive()">Dropdown</div>
</li>
/* In the SERVICE */
.factory('DropdownService', function () {
return {
activeDropDown: null
};
})
/* In the CONTROLLER */
controller("XyzDropdownController", function ($scope, DropdownService) {
var dropdownName = 'xyz';
var dds = DropdownService;
$scope.isActive = function () {
return dropdownName === dds.activeDropdown;
};
$scope.toggleDropdown = function () {
dds.activeDropdown = (dds.activeDropdown === dropdownName) ?
null :
dropdownName;
};
})
See, also, this short demo.
Based on what exactly you are doing, there might be other approaches possible/preferrable:
E.g. you could use just on controller to control all dropdowns
or you could use two instances of the same controller to control each dropdown.
See my updated fiddle. I simplified the code and removed the service. Because you just used two variables to control visibility, you don't need a service nor $watch. You need to keep variables in the $rootScope, otherwise changes in a controller is not visible to another controller due to isolated scopes.
angular.module("ftApp", [])
.controller("LoginDropDownController", function ($scope, $rootScope) {
$rootScope.loginDropDownStatus = false;
$scope.toggleDropDown = function () {
if ($rootScope.loginDropDownStatus == false) {
$rootScope.registrationDropDownStatus = false;
$rootScope.loginDropDownStatus = true;
} else if ($rootScope.loginDropDownStatus == true) {
$rootScope.loginDropDownStatus = false;
}
};
}).controller("RegistrationDropDownController", function ($scope, $rootScope) {
$rootScope.registrationDropDownStatus = false;
$scope.toggleDropDown = function () {
if ($rootScope.registrationDropDownStatus === false) {
$rootScope.loginDropDownStatus = false;
$rootScope.registrationDropDownStatus = true;
} else if ($scope.registrationDropDownStatus === true) {
$rootScope.registrationDropDownStatus = false;
}
};
})
This code can be simplified further. I'll leave that to you.

Resources