Selection on selectbox in IE when modifying the options with angular - angularjs

I'm developping an application that use Angular and we want to synchronize two selectbox (HTML). It means when I click a value in the first selectbox , I want value in the second selectbox updated, and clickable too.
I did the following plunker to explain our problem:
http://plnkr.co/edit/KkBVcu29CZ6Elr741ZPe?p=preview
<html ng-app="myApp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js" type="text/javascript"></script>
<script>
'use strict';
angular.module("myApp", []).run(function($rootScope) {}).config(function () {});
angular.module('myApp').controller('myCtrl', function(
$scope) {
//$scope.obj2Selected = null;
$scope.list1 = [];
$scope.list1.push({
id : "1",
name : "1",
selected : false
});
$scope.list1.push({
id : "2",
name : "2",
selected : false
});
$scope.list1.push({
id : "3",
name : "3",
selected : false
});
$scope.list2 = [];
$scope.list2 .push({
id : "1",
name : "1"
});
$scope.list2.push({
id : "2",
name : "2"
});
$scope.list2.push({
id : "3",
name : "3"
});
$scope.selectionObjDone = function(){
$scope.obj2Selected = null;
$scope.list2.length = 0;
$scope.list2.push({
id : Math.random().toString(),
name : Math.random().toString()
});
$scope.list2.push({
id : Math.random().toString(),
name : Math.random().toString()
});
};
});
</script>
<div ng-controller="myCtrl">
<select size="10" id="listNodes" style="width:200px;"
ng-options="obj as obj.name for obj in list1 track by obj.id" ng-model="objSelected"
ng-change="selectionObjDone()">
</select>
<select size="10" style="width:200px;" id="select2"
ng-options="obj as obj.name for obj in list2 track by obj.id"
ng-model="obj2Selected" >
</select>
</div>
</html>
In this plunker everything looks fine. But if you copy/paste the exact same code in a test.html for example, opening it in IE (V11), you'll see the problem:
Start by clicking on the first selectbox to choose an option or another.
Try to select then an option in the second selectbox, you'll see that the selection is no more possible.
It works well in FF or Chrome, and also it works better on Plunker, even if sometimes it stops to work in Plunker (I did not find the exact use case).
It has a real link to the fact that I empty the array that is used to fill the 2nd selectbox. If I comment this line, everything work fine:
$scope.list2.length = 0;
I tried different ways to empty this array:
How do I empty an array in JavaScript?
Does anybody have an idea on what happens here and how to fix this?
Thanks

Finally, even with an expert of Angular we did not find the answer, but waiting a few, the new version of Angular (1.5.7) resolved by magic the problem!

Related

Difference with use of using Select as in ng-options

Select box in IE is causing a problem in the opening for the first time when used with
identity as identity.identityName for identity in identityProofList track by identity.identityId or ng-repeat
but when used without identity as, it is working fine and can not see any difference in the functionality of select box also.
<select name="identityProof" ng-model="identityProof" ng-change="changeProofOfIdentity(identityProof)" ng-options="identity.identityName for identity in identityProofList track by identity.identityId" id="identityProofList" >
Where identityProofList is array of objects having properties identityName and identityId.
What is difference b/w the both?
Why ng-repeat is causing problem with IE11.
What is difference b/w the both?
Do you mean the difference between ng-repeat and ng-options?
The difference between using them to create DropdownList is that:
Dropdowns made with ng-options allows the selected value to be an object, while dropdowns made from ng-repeat has to be a string.
More details, check the AngularJS Select Boxes.
Why ng-repeat is causing problem with IE11 is also with using .
According to your codes, I create a sample using the following code, it works well on my IE browser (11.17134.1.0), you could refer to it.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<p>Select a identity:</p>
<select ng-model="selectedidentity">
<option ng-repeat="x in identityProofList " value="{{x.identityId}}">{{x.identityName}}</option>
</select>
<h1>You selected: {{selectedidentity}}</h1><br />
<select name="identityProof" ng-model="identityProof" ng-change="changeProofOfIdentity(identityProof)"
ng-options="identity as identity.identityName for identity in identityProofList track by identity.identityId"
id="identityProofList"></select>
<h1>You selected: {{selectedvalue}}</h1>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.identityProofList = [
{ identityId: "1001", identityName: "Admin" },
{ identityId: "1002", identityName: "User" },
{ identityId: "1003", identityName: "Customer" }
];
$scope.selectedvalue = "";
$scope.changeProofOfIdentity = function (identity) {
$scope.selectedvalue = identity.identityName;
}
});
</script>
The result like this.

Retain the dropdown value after the page is refresh or move to another page in angularjs

let me explain my scenario. I am having the dropdownlist in my master page. if changed dropdownlist the data are changed depend upon the dropdownlist value.
If i refreshed my page or moved to another page the dropdownlist will clear automatically.
I want to retain the dropdownlist value after refresh the page or moved to another page.
I tried like this but this is not help ful.
HTML
<select id="Facility_ID" required typeof="text" name="Facility Name" ng-options="Role.FacilityName for Role in Roles"
form="DistanceMatrixFormId" class="form-control" ng-model="Role._id" ng-selected="getFacilityID(Role._id.FacilityName)">
</select>
Controller.js
$scope.getFacilityID = function (data) {
localStorage.setItem("FacilityName", data);
var getfacility = localStorage.getItem("FacilityName");
}
i refered this link but it is not help ful
I don't know how to retain the value. can any one fixed me.
You cannot put an object into the local storage, you must store strings inside local storage.
If you want, you can have an implementation I did here : How to add local storage in angular?
For your current code, you don't need to use ng-selected. ng-model is enough.
<select id="Facility_ID" required typeof="text"
name="Facility Name"
ng-options="Role.FacilityName for Role in Roles"
form="DistanceMatrixFormId"
class="form-control"
ng-model="Role._id"
ng-change="updateLocalStorage()">
</select>
And inside your angular controller, what you can do is the following :
myApp.controller('controllerName', ['$scope', 'LocalStorageService',
function($scope, LocalStorageService){
// After initialization of your "Role" object
$scope.Role._id = LocalStorageService.retrieve('mySelectValue');
$scope.updateLocalStorage = function(){
LocalStorageService.store('mySelectValue', $scope.Role._id);
}
}])
Here is an example that uses a service to store the selected value. Unfortunately the embedded demo does not work because of the sandboxing, but works when served as an application.
angular.module(
"App", []
).factory("MyStorage", function() {
const key = "selected";
return {
getValue: function() {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : null;
},
setValue: function(value) {
localStorage.setItem(key, JSON.stringify(value));
}
};
}).controller("MyCtrl", function($scope, MyStorage) {
$scope.options = ["A", "B", "C"];
$scope.selected = MyStorage.getValue();
$scope.$watch("selected", newValue => {
MyStorage.setValue(newValue);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<div ng-app="App" ng-controller="MyCtrl">
<select ng-model="selected" ng-options="x for x in options">
</select>
</div>

ng-init does not initialize my selected model

I have a select option where I get a list of titles i.e. Mr, Mrs, Dr etc. from an API, the code looks like this in the front end:
<select class="form-control" name="titleSelect" id="titleSelect" ng-options="option.value for option in titleData.availableOptions track by option.key" ng-model="adult[$index].selectedTitle" ng-init="adult[$index].selectedTitle = titleData.availableOptions[0]"></select>
And this in the controller:
var getPassengerTitle = PassengerDetailsAndCardDetailsService.getPassengerTitle();
PassengerDetailsAndCardDetailsService is service, where I get the API data i.e. the title data. Furthermore this service returns a promise.
This is where I set the title Data:
getPassengerTitle.then(function(result){
$scope.availableTitles = angular.fromJson(result.titleList);
$scope.tempListOfTitles = [];
for(var key in $scope.availableTitles){
$scope.tempListOfTitles.push({key : key, value : $scope.availableTitles[key]});
};
$scope.titleData = {
availableOptions: $scope.tempListOfTitles,
};
});
When I try to ng-init to the first option (that is Mr.) it does not work as in a blank option is shown. However when I tried statically defining the titleData in an object it works, could you please help me?
UPDATE:
I failed to mention that the title data is inside an ng-repeat to support input for multiple people/passengers in this case. Therefore I'm using adult[$index] where it creates an ng-model for each person/passenger.
I am not sure if this is the required behavior you want, but if you want to initialise the title on selecting an option you can either use the value from ng-model or use the event handler ng-change. Here is an example jsbin which handles the change and assigns the new value to ng-model. Let me know if this is what you were looking for
try like this.
var myapp = angular.module('app', []);
myapp.controller('Main', function ($scope) {
var vm = this;
vm.adult = {
'selectedTitle':'1'
};
vm.titleData = [
{'key':'0','value':'Mr'},
{'key':'1','value':'Ms'},
{'key':'2','value':'Dr'}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app = "app">
<div ng-controller="Main as ctrl">
<div class="select-style">
<select ng-options="option.key as option.value for option in ctrl.titleData" ng-model="ctrl.adult.selectedTitle"></select>
</div>
</div>
</div>

angularjs dynamic model in directive from json object

I have a json file of objects that store the properties to be used in a directive.
I want to use the json obj model value in the directive, but nothing I am trying is working.
Anyone have any ideas what I am doing wrong / missing? I find this very confusing.
Hope someone can help been trying this for days now!
Edit::
I have a $http service that gets and returns the Json object and I can access the properties fine.
I am specifically trying to use the value of the json obj model property -- "model" : "ticketData.contactname" as the dynamic value of the ng-model.
If I just use the ticketData.contactname obj then it works fine and I can edit the model value, but if I try and use the string from the Json obj then it just prints the string into the input box.
I do not know what to do. I am sure it is something basic I am missing.
Thanks in advance
Json sample:
[
{
"inputsContact" : [
{
"labelName" : "Contact Name",
"placeholder" : "Enter your name",
"model" : "ticketData.contactname",
"type" : "text"
}
}
]
Html sample:
<text-input-comp inputdata="contactName" ng-model="contactModel"> </text-input-comp>
Directive text-input-comp:
.directive('textInputComp', [ '$compile', function($compile){
return {
restrict: 'E',
scope: {
inputData: '=inputdata',
modelData: '=ngModel'
},
templateUrl: '/app/views/partials/components/textInputComp.html'
}
}]);
Directive template sample:
<label> {{ inputData.labelName }} </label>
<input type="text" ng-model="modelData" ng-model-options="{ getterSetter: true }" placeholder="{{ inputData.placeholder }}" />
<div ></div>
Controller sample:
$scope.contactName = $scope.inputData[0].inputsContact[0];
$scope.contactModel = $scope.inputData[0].inputsContact[0].model;
i think u need to get the json file first then do all the manupilation
have a look at this code
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<ul>
<li ng-repeat="x in myData">
{{ x.Name + ', ' + x.Country }}
</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("customers.json").then(function (response) {
$scope.myData = response.data.records;
});
});
</script>
</body>
</html>
What u were missing is this
Just replace the customer.json file with your json and u are good to go
and
1.$http is service responsible for communicating with other file. $http says get file from ‘js/data.json’ and if the operation is a ‘success’ then execute a function holding the ‘data’ which it got automatically from data.json file
to make u understand.
2.A one more line above: [‘$scope’, ‘$http’, function($scope, $http){ … }] is little bit tricky: it takes an array holding two objects one is $scope and other is a service i.e $http. The reason we have this in array is angularJS automatically minifies code which means it removes extra spaces and shorten variable names for faster performance but sometimes this minification causes trouble so we just told controller NOT to minify $scope, $http services and function inside array.

Angular.JS data binding

I have started learning angular.js but I am kind of having trouble understanding the data binding and scopes.
Here is my Html file :
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"> </script>
<title>Egghead</title>
</head>
<body data-ng-app="myApp">
1. <div>
NAME : <input type = "text" name = "name" data-ng-model="data.name"/>
Typed Name : <b>{{data.name}}</b>
<br><br>
EMAIL: <input type = "email" name = "email" data-ng-model="data.email"/>
Typed Email : <b>{{data.email}}</b>
</div>
2. <div data-ng-controller="firstController">
NAME : <input type = "text" name = "name" data-ng-model="data.name"/>
Typed Name : <b>{{data.name}}</b>
<br><br>
EMAIL: <input type = "email" name = "email" data-ng-model="data.email"/>
Typed Email : <b>{{data.email}}</b>
</div>
3. <div data-ng-controller="secondController">
NAME : <input type = "text" name = "name" data-ng-model="data.name"/>
Typed Name : <b>{{data.name}}</b>
<br><br>
EMAIL: <input type = "email" name = "email" data-ng-model="data.email"/>
Typed Email : <b>{{data.email}}</b>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
Now when I have this module for my current html :
(function(){
var myApp = angular.module('myApp', []);
myApp.controller('firstController', function($scope, $rootScope) {
/*$rootScope.data = {name : "root", email : "root#gmail.com"};
$scope.data = {name : "Ishan", email : "soni.ishan.nitj#gmail.com"};*/
});
myApp.controller('secondController', function($scope) {
/*$scope.data = {name : "Divyan", email : "soni.divyan#gmail.com"};*/
});
})();
any changes that I make in any of the textbox for say the "name" input reflects and is bound everywhere. Example I make a change in the input text with name = "name" inside the second controller, the value in the text box for first also changes, but when I remove the comments from my javascript file, any change I make in the second controller's input box are not reflected in the first's input box. Why?
$rootScope is parent of all scopes, so if you assign property to it, it will be available everywhere in views. Every controller has $scope, you have two sibling controllers, so they have different scopes, if you want to share data between controllers, you shall use service. Like this:
myApp.factory('dataSrvc', function () {
return {
getData: function () {
return {
name : "Divyan",
email : "soni.divyan#gmail.com"
};
}
};
});
Then inject it into controllers:
myApp.controller('firstController', function($scope, dataSrvc) {
scope.data = dataSrvc.getData();
});
myApp.controller('secondController', function($scope, dataSrvc) {
scope.data = dataSrvc.getData();
});
In this case changes in first controller will not reflect on second and vice versa, because getData returns new instance of object every time (with same data).

Resources