AutoComplete Typehead in AngularJS - 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 ?

Related

AngularJS Custom filter using radio button

<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

How to initialize an angularJS factory with a button click

I have a factory to load data from an API. Code looks like
.factory('iScroll', function($http) {
var iScroll = function(pre_url){
this.items = [];
this.busy = false;
this.page = 1;
this.pre_url = pre_url;
}
iScroll.prototype.nextPage = function(){
if(this.busy) return;
this.busy = true;
var url = this.pre_url + 'page='+this.page;
$http.get(url).then(function(response){
console.log(response.data);
for (var i = 0; i < response.data.length; i++){
this.items.push(response.data[i]);
console.log("loading...");
}
this.page++;
this.busy = false;
}.bind(this));
};
return iScroll;
})
I initialize it like $scope.load_users = new iScroll('/api/web/branches/users/' +$stateParams.id+'?');
My question is, how can i call the factory via a button click?
In your template, you would use the ngClick directive to trigger an action:
<button type="button" ng-click="loadUsersAction()">Load Users</button>
Then in your controller, you define that function:
$scope.loadUsersAction = function() {
$scope.load_users = new iScroll('/api/web/branches/users/' +$stateParams.id+'?');
};

TypeError on Angular form submit

I'm getting the error TypeError: Cannot set property 'songname' of null, when trying to submit an update to a row in firebase. The console error is saying that its happening with the record.songname in the edit function. I'm able to add, but not edit rows.
myApp.controller('ProductsCtrl', ['$scope', '$firebaseArray', function($scope, $firebaseArray, $http){
var myProducts = new Firebase('https://url-to-db.firebaseio.com/songs');
$scope.products = $firebaseArray(myProducts);
$scope.showForm = function(){
$scope.addFormShow = true;
$scope.editFormShow = false;
clearForm();
window.scrollTo(0, 0);
}
$scope.hideForm = function(){
$scope.addFormShow = false;
}
function clearForm(){
$scope.songname = '';
$scope.artist = '';
$scopt.tags = '';
}
$scope.addFormSubmit = function(){
$scope.products.$add({
songname:$scope.songname,
artist:$scope.artist,
tags:$scope.tags,
date:Date.now()
});
$('.messages').addClass('alert alert-success').slideDown().show().html('The song has been added').fadeOut(2000);
clearForm();
}
$scope.dateFormat = 'MM-dd-yy # HH:mm:ss';
$scope.showProduct = function(product){
$scope.editFormShow = true;
$scope.addFormShow = false;
$scope.songname = product.songname;
$scope.artist = product.artist;
$scope.tags = product.tags;
$scope.date = product.date;
}
$scope.editFormSubmit = function(){
var id = $scope.id;
var record = $scope.products.$getRecord(id);
record.songname = $scope.songname;
record.artist = $scope.artist;
record.tags = $scope.tags;
$scope.products.$save(record);
$('.messages').addClass('alert alert-info').slideDown().show().html('The job has been edited').fadeOut(2000);
clearForm();
$('.edit-form').toggle();
}
}]);
The $scope.id attribute is probably not getting set.
Try setting the id in the scope in your showProduct function or whichever function initializes the $scope variables for the item.
$scope.showProduct = function(product){
$scope.id = product.id;
..............

Angularjs State transition

I am building a hybrid mobile app using ionic framework and cordova (first time).I am having problems with state transition because by default angular renders the template before completing the transition.This makes the the app look slow (when you click a menu item and wait for it to come).This happens only for those who load data from local storage or service! My Question is: How can I make the template come empty in the moment I click the menu item , then show a loader until the template is ready.Below is some code is use in my menu controller for the state transition!
//I use ng-click="navigateTo('state name')"
$scope.navigateTo = function (stateName) {
$timeout(function () {
$mdSidenav('left').close();
if ($ionicHistory.currentStateName() != stateName) {
$ionicHistory.nextViewOptions({
disableAnimate: false,
disableBack: true
});
$state.go(stateName);
}
}, ($scope.isAndroid == true ? 1000 : 0));
};// End navigateTo.
Below is the controller code for the view that needs a solution
appControllers.controller("calendar_Ctrl", function($scope,$rootScope, $state,$stateParams, $ionicHistory, $filter, $q, $timeout, $log, MaterialCalendarData, $moment) {
$scope.isAnimated = $stateParams.isAnimated;
$scope.selectedDate = null;
$scope.weekStartsOn = 0;
$scope.dayFormat = "d";
$scope.disableFutureDates = false;
$scope.directionn = "horizontal";
$scope.setDirection = function(direction) {
$scope.directionn = direction;
$scope.dayFormat = direction === "vertical" ? "EEEE, MMMM d" : "d";
};
$scope.dayClick = function(date) {
$scope.msg = "You clicked " + $filter("date")(date, "MMM d, y h:mm:ss a Z");
};
$scope.setContentViaService = function() {
var today = new Date();
MaterialCalendarData.setDayContent(today, '<span> :oD </span>')
}
$scope.getItems = function(){
if(localStorage.getItem("eventsData")){
var eventsData = localStorage.getItem("eventsData");
return JSON.parse(eventsData);
}else{
return [];
}
}
var events = $scope.getItems();
// You would inject any HTML you wanted for
// that particular date here.
var numFmt = function(num) {
num = num.toString();
if (num.length < 2) {
num = "0" + num;
}
return num;
};
var loadContentAsync = false;
$log.info("setDayContent.async", loadContentAsync);
$scope.setDayContent = function(date) {
var key = [date.getFullYear(), numFmt(date.getMonth()+1), numFmt(date.getDate())].join("-");
var data = (events[key]||[{ type: ""}]);
if (loadContentAsync) {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve(data);
});
return deferred.promise;
}
return data;
};
$scope.isAnimated = $stateParams.isAnimated;
});
Thank You Very Much for your time and help!!
Hi Use $ionicLoading Service to solve this problem,
http://ionicframework.com/docs/api/service/$ionicLoading/

$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