AngularJS AutoComplete Not Working In IE8 - angularjs

I have the following code for autoComplete
<div id="ng-app" ng-app ng-controller="AutoCtrls">
<input list="names" ng-model="selected">
<datalist id="names">
<option value="{{name}}" ng-repeat="name in names"></option>
</datalist>
selected = {{selected}}
</div>
and in app.js
function AutoCtrls($scope, Restangular) {
$scope.names = ["john", "bill", "charlie", "robert", "alban", "oscar",
"marie", "celine", "brad", "drew", "rebecca", "michel", "francis", "jean",
"paul", "pierre", "nicolas", "alfred", "gerard", "louis", "albert",
"edouard", "benoit", "guillaume", "nicolas", "joseph"];
alert('ok 1');
}
The problem I am facing is this doesn't work in IE8, however this does work in Chrome and Firefox.
What could be the reason and how can I fix the issue?

IE8 and 9 don't support <datalist>: http://caniuse.com/datalist

Related

Wrong array item after using orderby filter AngularJS

I have an app that works well displaying a list of students. When you click on each name, it displays more info about that particular student. However, if I change the order of names through select options or search, wrong student info is displayed.
Here is my view:
<input type="text" ng-model="expression" placeholder="Search Student" />
<div class="select">
<span>Sort By: </span>
<select ng-model="order" ng-show="students.length > 0">
<option selected value="name">Name A-Z</option>
<option value="-name">Name Z-A</option>
<option value="room">Room (first to last)</option>
<option value="-room">Room (last to first)</option>
</select>
</div>
<div ng-repeat="student in students | orderBy: order | filter:expression">
<div class="info">
<div class="img">
<img ng-src="{{student.image}}">
</div>
<h2 style="color: #007acc;"> Student Details For:</h2>
<hr>
<h2>{{student.name}}</h2>
<a ng-href="#!/students/{{$index}}"><button>View Student
Details</button></a>
</div>
</div>
Here is my Js:
var data = [
{
name: "Andrea Toe",
sex: "Female",
room: 12,
cell: "076 861 6184",
image: "images/female.jpg",
checkin: "June 2016"
},
{
name: "John Doe",
sex: "Female",
room: 3,
cell: "063 961 7190",
image: "images/lebo.jpg",
checkin: "01 Feb 2018"
},
{
name: "James Drew",
sex: "Male",
room: 1,
cell: "076 910 3069",
image: "images/male.jpeg",
checkin: "01 Feb 2018"
}
];
app.controller("studentsCtrl", function($scope){
$scope.students = data;
});
app.controller('studentInfoCtrl', ['$scope', '$routeParams',
function($scope, $routeParams) {
$scope.info = data[$routeParams.id];
}]);
What should I do to get it to display correct info even after using search filter or reordering using oderBy?
It is because, when creating the link to the "student details", you use the $index scope variable.
This $index is introduced by the ng-repeat directive and will represent the:
iterator offset of the repeated element (0..length-1)
(from the documentation linked here)
In short, the $index you use to uniquely identify a student when building the corresponding link to their details page depends entirely on its position in the page. It does not at all identify the resource itself!
What you could do is have an id property assigned to each student along with their name, sex etc., like so:
var data = [{
id: 0,
name: "Andrea Toe",
}, {
id: 1,
name: "John Doe",
}, {
id: 2,
name: "James Drew",
}];
And simply refer to that newly introduced property in the urls you create!
<a ng-href="#!/students/{{ student.id }}"><button>View Student Details</button></a>
Searching and sorting are working fine for me:
var data = [{
id: 1,
name: "Andrea Toe",
sex: "Female",
room: 12,
cell: "076 861 6184",
image: "images/female.jpg",
checkin: "June 2016"
},
{
id: 2,
name: "John Doe",
sex: "Female",
room: 3,
cell: "063 961 7190",
image: "images/lebo.jpg",
checkin: "01 Feb 2018"
},
{
id: 3,
name: "James Drew",
sex: "Male",
room: 1,
cell: "076 910 3069",
image: "images/male.jpeg",
checkin: "01 Feb 2018"
}
];
app = angular.module("myapp", []);
app.controller("studentsCtrl", function($scope) {
$scope.students = data;
});
app.controller('studentInfoCtrl', ['$scope', '$routeParams',
function($scope, $routeParams) {
$scope.info = data.filter(function(d){
return d.id == $routeParams.id;
})[0];
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script>
<div ng-app="myapp" ng-controller="studentsCtrl">
<input type="text" ng-model="expression" placeholder="Search Student" />
<div class="select">
<span>Sort By: </span>
<select ng-model="order" ng-show="students.length > 0">
<option selected value="name">Name A-Z</option>
<option value="-name">Name Z-A</option>
<option value="room">Room (first to last)</option>
<option value="-room">Room (last to first)</option>
</select>
</div>
<div ng-repeat="student in students | filter:expression | orderBy: order ">
<div class="info">
<!-- <div class="img">
<img ng-src="{{student.image}}">
</div> -->
<h2 style="color: #007acc;"> Student Details For:</h2>
<hr>
<h2>{{student.name}}</h2>
<a ng-href="#!/students/{{student.id}}"><button>View Student
Details</button></a>
</div>
</div>
</div>

Injector moduler error in angularJs

I am getting "Uncaught Error: [$injector:modulerr]". Can anyone help me to solve this. My code is as follows..
<!DOCTYPE html>
<html>
<head>
<style>
body {
max-width: 32em;
margin: 1em auto 0;
}
img { width: 30px; }
</style>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
// https://angular-ui.github.io/
// setup app and pass ui.bootstrap as dep
var myApp = angular.module("angularTypeahead", ["ui.bootstrap"]);
// define factory for data source
myApp.factory("States", function(){
var states = ["Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Dakota", "North Carolina", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"];
return states;
});
// setup controller and pass data source
myApp.controller("TypeaheadCtrl", function($scope, States) {
console.log("hello");
$scope.selected = undefined;
$scope.states = States;
});
</script>
</head>
<body>
<div ng-app="angularTypeahead">
<div class="container-fluid" ng-controller="TypeaheadCtrl">
<h2><img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/15309/angular-logo.svg" alt="Angular.js Logo"> Angular.js Typeahead</h2>
<div class="form-group">
<label for="states">Search for US States</label>
<input name="states" id="states" type="text" placeholder="enter a state" ng-model="selected" typeahead="state for state in states | filter:$viewValue | limitTo:8" class="form-control">
</div>
<button class="btn btn-success" type="submit">Submit</button>
</div>
</div>
</body>
</html>
Am I did wrong anywhere? I got this code from codepen. It is running perfectly there. But Its is not running in my local

Update <select> tag inside ng-if in angularjs

I would like to update the list of states on selection of country. I have researched a bit into this where it was recommended to use $parent as ng-if does not work on controller scope.But that too is not working for me.
Can someone please help me understand how to get the values into state select control.
Also I would also like to know what if there are multiple ng-if in my HTML. (again nested $parent.$parent.$parent... is not working)
Plunker Link : Plunker Link
"use strict";
var app = angular.module("app", []);
function CountriesController($scope) {
$scope.condition = true;
$scope.countries = [{
"name": "USA",
"id": 1
},{
"name": "Canada",
"id": 2
}];
$scope.states = [{
"name": "Alabama",
"id": 1,
"countryId": 1
}, {
"name": "Alaska",
"id": 2,
"countryId": 1
}, {
"name": "Arizona",
"id": 3,
"countryId": 1
}, {
"name": "Alberta",
"id": 4,
"countryId": 2
}, {
"name": "British columbia",
"id": 5,
"countryId": 2
}];
$scope.updateCountry = function(){
$scope.availableStates = [];
angular.forEach($scope.states, function(value){
if(value.countryId == $scope.country.id){
$scope.availableStates.push(value);
}
});
}
}
<!DOCTYPE html>
<html data-ng-app="app">
<head>
<script data-require="angular.js#1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body data-ng-controller="CountriesController">
<div ng-if="condition">
<select data-ng-model="country" data-ng-options="country.name for country in countries" data-ng-change="updateCountry()">
<option value="">Select country</option>
</select>
<br>
<select data-ng-model="state" data-ng-options="state.name for state in availableStates">
<option value="">Select state</option>
</select>
<br> Country: {{country}}
<br> State: {{state}}
</div>
</body>
</html>
Instead of making a separate list, you can use your country list by filtering
filter: {countryId: $parent.country.id}
"use strict";
var app = angular.module("app", []);
function CountriesController($scope) {
$scope.condition = true;
$scope.countries = [{
"name": "USA",
"id": 1
},{
"name": "Canada",
"id": 2
}];
$scope.states = [{
"name": "Alabama",
"id": 1,
"countryId": 1
}, {
"name": "Alaska",
"id": 2,
"countryId": 1
}, {
"name": "Arizona",
"id": 3,
"countryId": 1
}, {
"name": "Alberta",
"id": 4,
"countryId": 2
}, {
"name": "British columbia",
"id": 5,
"countryId": 2
}];
$scope.updateCountry = function(){
$scope.availableStates = [];
angular.forEach($scope.states, function(value){
if(value.countryId == $scope.country.id){
$scope.availableStates.push(value);
}
});
}
}
<!DOCTYPE html>
<html data-ng-app="app">
<head>
<script data-require="angular.js#1.1.5" data-semver="1.1.5" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body data-ng-controller="CountriesController">
<div ng-if="condition">
<select data-ng-model="country" data-ng-options="country.name for country in countries" data-ng-change="">
<option value="">Select country</option>
</select>
<br>
<select data-ng-model="state" data-ng-options="state.name for state in states | filter:{countryId: country.id}:true">
<option value="">Select state</option>
</select>
<br> Country: {{country}}
<br> State: {{state}}
</div>
</body>
</html>
Here is simplest way to init selected option:
for blank form, just init with option value that you want (don't forget the double single quotes)
<select ng-model="$ctrl.data.userlevel" ng-init="$ctrl.data.userlevel='0'">
<option value="0">User</option>
<option value="1">Admin</option>
</select>
for loaded data form, just init using that loaded model data, like below:
<select ng-model="$ctrl.data.userlevel" ng-init="$ctrl.data.userlevel=''+$ctrl.data.userlevel">
<option value="0">User</option>
<option value="1">Admin</option>
</select>
i think, init value should be string. so they need to concat with double single quotes.

How to set width for Kendo Angular input kendo-auto-complete?

I need to set width of the autocomplete input in the Angular Kendo.
How can i do it programatically please?
Thanks for any help.
Setting it with an initial value, you should use style="width: 200px;".
Example:
<input kendo-auto-complete="my_autocomplete" ng-model="country" k-data-source="countryNames" style="width: 200px" />
If then you need to modify it, you should change the width via css method for wrapper element.
Example
$scope.my_autocomplete.wrapper.css("width", "300px");
angular.module("KendoDemos", [ "kendo.directives" ])
.controller("MyCtrl", function($scope){
$scope.countryNames = [
"Albania",
"Andorra",
"Armenia",
"Austria",
"Azerbaijan",
"Belarus",
"Belgium",
"Bosnia & Herzegovina",
"Bulgaria",
"Croatia",
"Cyprus",
"Czech Republic",
"Denmark",
"Estonia",
"Finland",
"France",
"Georgia",
"Germany",
"Greece",
"Hungary",
"Iceland",
"Ireland",
"Italy",
"Kosovo",
"Latvia",
"Liechtenstein",
"Lithuania",
"Luxembourg",
"Macedonia",
"Malta",
"Moldova",
"Monaco",
"Montenegro",
"Netherlands",
"Norway",
"Poland",
"Portugal",
"Romania",
"Russia",
"San Marino",
"Serbia",
"Slovakia",
"Slovenia",
"Spain",
"Sweden",
"Switzerland",
"Turkey",
"Ukraine",
"United Kingdom",
"Vatican City"
];
setTimeout(function() {
alert("Changing width");
$scope.my_autocomplete.wrapper.css("width", "300px");
}, 4000);
});
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.common.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/2014.3.1119/styles/kendo.default.min.css" />
<script src="http://cdn.kendostatic.com/2014.3.1119/js/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1119/js/angular.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1119/js/kendo.all.min.js"></script>
<div id="example" ng-app="KendoDemos">
<div class="demo-section k-content" ng-controller="MyCtrl">
<input kendo-auto-complete="my_autocomplete" ng-model="country" k-data-source="countryNames" style="width: 200px" />
</div>
</div>

How to always show a top li in typeahead with angular ui bootstrap

I am trying to use typeahead in ui bootstrap (http://angular-ui.github.io/bootstrap/) to add a drop down for existing options. I want the user to always have the option of selecting a li that says "+ add new" (see example code).
Do you know how I could add a li that is always on the top of the li list?
What I am trying to display in the dropdown:
<input value="">
<ul>
<li>+ Add New</li>
<li>Boots</li>
<li>Shoes</li>
<li>Hats</li>
</ul>
the angular html and directive
<div class="row form-group" ng-app="filterSelect">
<div class="col-xs-4">
<label for="">State:</label>
<div class="btn-group s-search-filter">
<span class="s-search-input" ng-controller="TypeaheadCtrl">
<input type="text" ng-model="selected" placeholder="Search" typeahead="state for state in states | filter:$viewValue | limitTo:8" class="form-control">
</span>
</div>
</div>
</div>
</div>
<script charset="utf-8">
angular.module('filterSelect', ['ui.bootstrap']);
function TypeaheadCtrl($scope, $http) {
$scope.selected = undefined;
$scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'];
}
</script>
You can do this by implementing a custom filter in angularjs.
autocompleteApp.filter('statesFilter', function() {
return function(states, searchText) {
var filtered = ['+ Add New'];
searchText = searchText.toLowerCase();
angular.forEach(states, function(state) {
if (state.toLowerCase().indexOf(searchText) != -1)
filtered.push(state);
});
return filtered;
};
});
here's the html
<input type="text"
ng-model="selected"
placeholder="Search"
typeahead="state for state in states | statesFilter:$viewValue | limitTo:8"
class="form-control">
Actually as far as i know you can not do it.
Once a had the similar problem: i had to show my input text before all results. So, i wrote my own directive over typeahead directive. Unfortinally, i didn't finish that one, but you can try to modify that one.
The main idea is that before showing results you process you Array jf results and unshift() your own value. You could modify that one and insert some special value for add new value.
Also, these directive works only with Arrays of Objects.
Here is the link: http://plnkr.co/edit/DKi5ONvNFtXPonwOHqtX?p=info
Hope, it will be usefull for you.

Resources