Unexpected binding behaviour - angularjs

I have select list i set default option to be chosen. what happen is for few second it works then it disappear and the blank option in the list is chosen as default.
<div class="form-group">
<select class="form-control" ng-model="item.action" ng-options="option.value as option.title for option in options">
</select>
</div>
i want to set defualt option to be chosen :
so my controller look like this:
$scope.item = {};
$scope.options = [{
title: 'On entering',
value: 'enter'
}, {
title: 'On exiting',
value: 'exit'
}];
$scope.item.action= $scope.options[0].value;
$scope.profile = me.getUser();
$scope.profile.then(
function(user) {
$scope.owner = user;
$scope.item = {};
$scope.item.data = '';
$scope.item.published = true;
$scope.item.action= $scope.action;
$scope.item.owner = $scope.owner.displayName;
},
function(response) {
console.log(response);
}
);
me is a service that fecth the user data.
the reason why am defining $scope.item = {}; again is because i can't apend the displayName to the $scope.item out of the scope.
I commented this part of the code and it works well:
$scope.profile = me.getUser();
$scope.profile.then(
function(user) {
$scope.owner = user;
$scope.item = {};
$scope.item.data = '';
$scope.item.published = true;
$scope.item.action= $scope.action;
$scope.item.owner = $scope.owner.displayName;
},
function(response) {
console.log(response);
}
);
But now i can't figure out how to build my item object to send it in HTTP request

Related

Angular 1:Build dropdown box dynamically

I am new to Angular 1,so I am stuck with building a dropdown box dynamically using angular.
Below is my code
var app = angular.module('myApp', []);
app.controller('TestCtrl', function($scope, $http) {
I have created an onchange function getTypeName() and have passed the parameters using get method and retrieved the result as json .
$scope.getTypeName = function (type) {
$http.get('get-type-name',
{ params:
{
type: type
}
}).then(
function(response){
var data = response.data;
for(i = 0; i < data.length; i++) {
//code to build dropdown
}
},
);
}
});
Below is my response,
[
{"id":"001","name":"ABC"},
{"id":"002","name":"DEF"},
{"id":"003","name":"GHI"}
]
I want to build a dropdown box using this response within the get method function success using for loop.Please provide a solution to solve this out.
you do like this
in app.js
$scope.getTypeName = function (type) {
$http.get('get-type-name',
{ params:
{
type: type
}
}).then(
function(response){
$scope.data = response.data;
},
);
}
});
in your html
<select id="ddl" model="ddldata" typeof="text"required>
<option data-ng-repeat="ProjectName in data" value="{{ProjectName.id}}" ng-bind={{ProjectName.name}}">
</select>
You can try this,
$scope.yourOptions = [];
$scope.getTypeName = function (type) {$http.get('get-type-name',
{ params:
{
type: type
}
}).then(
function(response){
var data = response.data;
$scope.yourOptions = data;
},
);
}
});
in html,
<select class="form-control" ng-model="whatever" >
<option ng-repeat="x in yourOptions " value="{{x.id}}">{{x.name}}</option>
</select>
Here is an example of dynamically populating select options from an http get https://plnkr.co/edit/7PS7LBBNZA2cNzMorrB9?p=preview
<select ng-model="selectedItem">
<option ng-repeat="o in options">{{o.name}}</option>
</select>
$scope.getTypeName = function() {
$http.get('https://jsonplaceholder.typicode.com/users').then(
function(result) {
$scope.options = result.data;
},
function(error) {
console.log(error);
}
);
};

No popup window with AngularJS and typeahead

I have a problem with the typeahead directive. I try to get datas from my datas from my service via $http.get.
In the console output I can see that my datas are coming from the service but I don't get the popup window of the results.
Here is my code:
Html Template:
<input type="text" class="form-control" placeholder="Kundensuche" ng-model="selectedCompany" typeahead="c for c in companies($viewValue)" typeahead-no-results="noResults" typeahead-min-length="3">
Service:
var _search = function (route, id) {
return $http.get(serviceBase + 'api/' + route + '/search/' + id);
};
serviceHelperFactory.search = _search;
Controller:
$scope.companies = function (val) {
var output = [];
var promise = serviceHelper.search('companies', val);
promise.then(function (result) {
result.data.forEach(function (company) {
output.push(company.companyName);
//output.push(company);
});
console.log(output);
}, function (error) {
adminInvoiceService.serviceErrorMessage(error);
});
return output;
}
Thanks!
Ok, I fixed it!
For all with the same problem here is my solution!
$scope.companies = function (val) {
return $http.get('http://localhost:5569/api/companies/search/'+val).then(function (res) {
var companies = [];
console.log(companies);
res.data.forEach(function (item) {
companies.push(item);
});
console.log(companies);
return companies;
});
};

ng-select with lazy population

It's an edit form with parent record first populated then dependent select list is populated, and then it's expected the value from parent record pre-select the combo box.
html
<select ng-model="data.trackId" >
<option ng-repeat="track in tracks" value="{{track.id}}">{{track.name}}</option>
initial result once parent record is pulled.
if(data) {
this.$scope.data.id = data.id;
this.$scope.data.name = data.name;
this.$scope.data.room = data.room;
this.$scope.data.start = data.start;
this.$scope.data.end = data.end;
this.$scope.data.dayId = data.day_id;
this.$scope.data.trackId = data.track_id;
this.$scope.data.color = data.color;
this.$scope.data.description = data.description;
this.$scope.$apply();
this.$element[0].removeAttribute("style");
}
//later track results were pulled
trackResult: function(data, status, headers, config) {
for(var i=0; i<data.length; i++) {
this.$scope.tracks.push(data[i]);
}
this.$scope.$apply();
},
Problem:
List gets populated from the second call trackResult but default value from the $scope.trackId never sets the combo box to a value.
Edit: Controller Body
controller: function($scope, $element) {
var self = this;
this.$scope = $scope;
this.$element = $element;
this.$scope.data = {};
this.$scope.days = [];
this.$scope.tracks = [];
this.$scope.submit = function() {self.submit()};
this.$scope.cancel = function() {self.cancel()};
},
Edit : Updated with setting the data from outside the scope (OP request)
Use ng-options & ng-model
this is how i think it should be done in angularjs.
use the built in databinding capabilities to simplify your code and make it less complicated
for binding a list into a <select> and controlling the selected item, this snippet below should do the trick.
http://jsfiddle.net/72em40j4/
js
var myapp = angular.module('myapp', []);
myapp.controller('Ctrl', function ($scope) {
$scope.options = [];
$scope.selectedOption = null;
});
html
<script>
function clickFromOutside() {
var controllerElement = document.getElementById('container');
var controllerScope = angular.element(controllerElement).scope();
var firstTrack = {
id: 1,
first: 'First',
last: 'Track'
};
var secondTrack = {
id: 2,
first: 'Second',
last: 'Track'
};
controllerScope.options.push(firstTrack);
controllerScope.options.push(secondTrack);
controllerScope.selectedOption = secondTrack;
controllerScope.$apply();
}
</script>
<button onclick="clickFromOutside();">outside</button>
<div ng-app="myapp">
<fieldset id="container" ng-controller="Ctrl">
<select ng-options="p.first + ' ' + p.last for p in options" ng-model="selectedOption"></select> <pre>{{ selectedOption }}</pre>
</fieldset>
</div>

How to manually add a datasource to Angularjs-select2 when select2 is set up as <input/> to load remote data?

I am using the Select2 as a typeahead control. The code below works very well when the user types in the search term.
However, when loading data into the page, I need to be able to manually set the value of the search box.
Ideally something like: $scope.selectedProducerId = {id:1, text:"Existing producer}
However, since no data has been retrieved the Select2 data source is empty.
So what I really need to be able to do is to add a new array of data to the datasource and then set the $scope.selectedProducerId, something like: $scope.producersLookupsSelectOptions.addNewData({id:1, text:"Existing producer}) and then
$scope.selectedProducerId = 1;
Researching this I have seen various suggestions to use initSelection(), but I can't see how to get this to work.
I have also tried to set createSearchChoice(term), but the term is not appearing in the input box.
I would be most grateful for any assistance.
Thanks
This is the html
<div class="col-sm-4">
<input type="text" ui-select2="producersLookupsSelectOptions" ng- model="selectedProducerId" class="form-control" placeholder="[Produtor]" ng-change="selectedProducerIdChanged()"/>
</div>
This is the controller
angular.module("home").controller("TestLookupsCtrl", [
"$scope", "$routeParams", "AddressBookService",
function($scope, $routeParams, AddressBookService) {
$scope.producersLookupsSelectOptions = AddressBookService.producersLookupsSelectOptions();
}
]);
This is the service:
angular.module("addressBook").service("AddressBookService", [
"$http", "$q", function($http, $q) {
var routePrefix = "/api/apiAddressBook/";
//var fetchProducers = function(queryParams) {
// return $http.get(routePrefix + "GetClientsLookup/" + queryParams.data.query).then(queryParams.success);
//};
var _getSelectLookupOptions = function(url, minimumInputLength, idField, textField) {
var _dataSource = [];
var _queryParams;
return {
allowClear: true,
minimumInputLength: minimumInputLength || 3,
ajax: {
data: function(term, page) {
return {
query: term
};
},
quietMillis: 500,
transport: function(queryParams) {
_queryParams = queryParams;
return $http.get(url + queryParams.data.query).success(queryParams.success);
},
results: function(data, page) {
var firstItem = data[0];
if (firstItem) {
if (!firstItem[idField]) {
throw "[id] " + idField + " does not exist in datasource";
}
if (!firstItem[textField]) {
throw "[text] " + textField + " field does not exist in datasource";
}
}
var arr = [];
_.each(data, function(returnedData) {
arr.push({
id: returnedData[idField],
text: returnedData[textField],
data: returnedData
});
});
_dataSource = arr;
return { results: arr };
}
},
dataSource: function() {
return _dataSource;
},
getText: function (id) {
if (_dataSource.length === 0) {
throw ("AddressBookService.getText(): Since the control was not automatically loaded the dataSource has no content");
}
return _.find(_dataSource, { id: id }).text;
}
//initSelection: function(element, callback) {
// callback($(element).data('$ngModelController').$modelValue);
//},
//createSearchChoice:function(term) {
// return term;
//},
addNewData:function(data) {
this.ajax.results(data,1);
};
};
return {
producersLookupsSelectOptions: function() {
var url = routePrefix + "GetClientsLookup/";
return _getSelectLookupOptions(url, 2, "Id", "Name");
},
}
}
]);

Re-binding a tree (Wijmo tree) with AngularJS

I am fairly new to AngularJS, and really struggling to re-bind a Wijmo tree (or even a tree implemented using UL and LI elements wth ng-repeat) with new data on changing of value of a Wijmo combobox (or, even a regular dropdown of HTML select elem).
Below is the code I have written, which is working fine in initial page load. But on changing the dropwdown, the tree is not being reloaded with new data fetched by loadDomainTree method; it is still showing old data. Can somebody help me figure out what's wrong with this code?
HTML:
<div ng-controller="DomainCtrl">
<select id="domain" ng-model="currentDomain" ng-options="item.Name for item in domainList"></select>
<div>
<ul id="wijtree">
<li ng-repeat="item in domainEntityList" id={{item.Id}}>
<a>{{item.Name}}</a>
</li>
</ul>
</div>
</div>
JS:
$(document).ready(function ()
{
$("#domain").wijcombobox({
isEditable: false
});
$("#wijtree").wijtree();
});
function DomainDropdownModel(data) {
this.Id = data.Id.toString();
this.Name = data.Name;
};
function DomainTreeModel(data) {
this.Id = data.Id;
this.Name = data.Name;
};
function DomainCtrl($scope, $locale) {
$scope.domainList = [];
$.ajax({
url: dropDownUrl,
async: false,
success: function (data) {
$(data).each(function (i, val) {
var domain = data[i];
var domainId = domain.Id.toString();
var domainName = domain.Name;
$scope.domainList.push(new DomainDropdownModel({ Id: domainId, Name: domainName }));
});
}
});
$scope.currentDomain = $scope.domainList[0];
$scope.loadDomainTree = function (domainId) {
domainEntitiesUrl = DOMAIN_API_URL + DOMAIN_ID_PARAM + domainId;
//alert(domainEntitiesUrl);
$scope.domainEntityList = [];
$.ajax({
url: domainEntitiesUrl,
async: false,
success: function (data) {
$(data).each(function (i, entity) {
var domainEntity = data[i];
var domainEntityId = domainEntity.Id.toString();
var domainEntityName = domainEntity.Name;
$scope.domainEntityList.push(new DomainTreeModel({ Id: domainEntityId, Name: domainEntityName }));
});
}
});
};
//Will be called on setting combobox dfault selection and on changing the combobox
$scope.$watch('currentDomain', function () {
$scope.loadDomainTree($scope.currentDomain.Id);
});
}
You may $watch for the selectedItem of WijCombobox and then, re-load the wijtree accordingly. Here is the code:
$scope.$watch('selectedItem', function (args) {
if (args === 'Tree 1') {
$("#wijtree").wijtree("option", "nodes", $scope.nodes1);
}
else {
$("#wijtree").wijtree("option", "nodes", $scope.nodes2);
}
});
HTML Code
<wij-combobox data-source="treeList" selected-value="selectedItem">
<data>
<label bind="name"></label>
<value bind="code"></value>
</data>
</wij-combobox>

Resources