Good day! I need to create directive with ui-select inside.
Here is directive's controller and template:
app.controller("servicesCtrl", ["$resource", '$scope', function($resource, $scope){
$scope.clinicServices = [];
console.log($scope.data);
var Services = $resource(window.baseurl + "services/getAllbyClinic", null, {
get:{responceType: "JSON", isArray: false, method: 'POST'}
});
$scope.refresh = function(service){
if(service.length < 1) return false;
Services.get({service: service},function(data){
$scope.clinicServices = data.services;
});
};
}]);
<ui-select
multiple
tagging
tagging-label="false"
ng-model="$parent.data"
theme="bootstrap"
title="Выберите услугу"
search-enabled="true"
>
<ui-select-match placeholder="Введите услугу">{{$item.name}}</ui-select-match>
<ui-select-choices repeat="clinicService in clinicServices" refresh="refresh($select.search)">
<div ng-bind-html="(clinicService.name | highlight: $select.search)"></div>
</ui-select-choices>
</ui-select>
{{data}}
And here is directive initialization.
app.directive('services', function() {
return {
restrict: 'E',
templateUrl: window.baseurl + 'views/services',
scope: {
data: "=ngModel"
},
controller: "servicesCtrl",
controllerAs: "services"
}
});
<services ng-model="meEvent.services"></services>
Can't render $scope.data into view from servicesCtrl to edit previously selected data. There are an object inside $scope.data, but empty view's field. I tried ng-model="$parent.data" and ng-model="data", but have no effect.
There where errors in my version of ui-select library
Related
I'm trying to use directives in my angularjs app, it's the first i'm trying to apply, so i'm not sure if its right.
The thing is that i want to wrap the ui-select directive into another directive and then i want to watch the selec if a new value has been selected. I'm able to populate the select but i don't know why it doesn't trigger the watch... here is the controller:
.controller('IngredientesDatosGeneralesController' ,['$scope', 'PrivateAlergenosUtilsService',
'PrivateRestauranteService', 'PrivateIngredienteService',
function($scope, PrivateAlergenosUtilsService, PrivateRestauranteService,
PrivateIngredienteService){
var _this = this;
_this.PrivateIngredienteService = PrivateIngredienteService;
_this.proveedorSeleccionado = null;
_this.proveedores = [];
PrivateRestauranteService.getProveedores().then(
function(proveedores){
_this.proveedores = proveedores;
},
function(error){
_this.proveedores = [];
}
);
$scope.$watch('cntrl.proveedorSeleccionado', function(newValue,oldValue){
if (newValue && newValue!=oldValue){
_this.PrivateIngredienteService.getIngregienteDTO().id = _this.proveedorSeleccionado.id;
}
}, true);
}]);
The following is the directive:
.directive('comboDirective', [
function(){
return {
restrict : 'E',
templateUrl: 'resources/js/private/views/utils/combo/combo.html',
scope : {
seleccionado : '=',
elementos : '=',
descripcion : '#'
}
}}]);
The combo.html:
<div class="col-xs">
<label translate>{{descripcion}}</label>
</div>
<div class="col-xs">
<div class="selectStyle">
<ui-select ng-model="seleccionado" theme="bootstrap" register-custom-form-control disable-validation-message="" required>
<ui-select-match placeholder="{{'input.seleccionar' | translate}}">{{$select.selected.descripcion}}</ui-select-match>
<ui-select-choices repeat="elemento in elementos | filter: $select.search">
<div ng-bind-html="elemento.descripcion | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
<i class="fa fa-chevron-down"></i>
</div>
</div>
And finally this is how i call the directive:
<div ng-controller="IngredientesDatosGeneralesController as cntrl">
<combo-directive
seleccionado="cntrl.proveedorSeleccionado"
descripcion="formulario.proveedor"
elementos="cntrl.proveedores">
</combo-directive>
</div>
Thanks in advance
I found what was happening... i don't know why but if i put this config in the directive and using the 'cntrl.' prefix before the "seleccionado" and "elementos" values in the HTML, it works properly.
'use strict';
angular.module("private.directives")
.directive('comboDirective', [
function(){
return {
restrict : 'E',
templateUrl: 'resources/js/private/views/utils/combo/combo.html',
scope : {
seleccionado : '=',
elementos : '=',
descripcion : '#'
},
controller : ['$scope', function ($scope) {
}],
controllerAs : 'cntrl',
bindToController: true
}
}]);
I have an angular App which has the following code in the script:
var myApp = angular.module('myApp', []);
myApp.controller('Ctrl', function($scope, FileAccessor) {
$scope.countrynames = []
});
myApp.directive('country', function() {
var directiveDefinitionObject = {
restrict: 'E',
templateUrl: 'partials/scape.html',
controllerAs: 'dm',
compile: function(scope, FileAccessor) {
FileAccessor.fetchCountryDetails('https://restcountries.eu/rest/v1/all').success(function(response) { //assigning the fetched countries to the scope object var
scope.countrynames = response;
});
}
}
return directiveDefinitionObject;
})
myApp.factory("FileAccessor", ['$http', function($http) {
return {
fetchCountryDetails: function(url) {
return $http.get(url);
}
}
}]);
Inside scape.html, the following code is placed:
<div ng-controller="Ctrl" class="container" style="height:500px" >
<select ng-model="model" ng-options="obj.name for obj in countrynames | orderBy: '-population'" placeholder="Select" autofocus>
<option value="">- Please Choose -</option>
</select>
{{model.name}}
{{model.currencies[0]}}
</div>
As we can see, I am trying to access the function which is placed inside the factory, FileAccessor from the custom directive, country.
When I run it on browser, there is this error that pops on console:
angular.min.js:86 TypeError: FileAccessor.fetchCountryDetails is not a function
Can somebody please explain what went wrong along with the fixed code?
P.S. I want the HTTP requests to be processed only through the factory(as a requirement).
Edit 1: Including the Plunkr link here: http://plnkr.co/edit/gXQKBd?p=info
Inject the service at your directive declaration, NOT in the compile function:
myApp.directive('country', function(FileAccessor) { //inject FileAccessor here
var directiveDefinitionObject = {
restrict: 'E',
templateUrl: 'partials/scape.html',
controllerAs: 'dm',
compile: function(scope) {
FileAccessor.fetchCountryDetails('https://restcountries.eu/rest/v1/all').success(function(response) { //assigning the fetched countries to the scope object var
scope.countrynames = response;
});
}
}
return directiveDefinitionObject;
})
Edit: There are quite a number of bugs inside your code, maybe you would want to read the docs?
One: Use link instead of compile, as link gives you the scope but compile doesn't:
myApp.directive('country', function(FileAccessor) {
var directiveDefinitionObject = {
restrict: 'E',
templateUrl: 'scape.html',
controllerAs: 'dm',
link: function(scope) {
scope.test="Hello";
FileAccessor.fetchCountryDetails('https://restcountries.eu/rest/v1/all').then(function(response) { //assigning the fetched countries to the scope object var
scope.countrynames = response.data;
});
}
}
return directiveDefinitionObject;
})
Two: Remove the ng-controller directive in your scape.html as this will override the of your directive:
<div class="container" style="height:500px"> //remove the ng-controller='Ctrl'
<select ng-model="model" ng-options="obj.name for obj in countrynames | orderBy: '-population'" placeholder="Select" autofocus>
<option value="">- Please Choose -</option>
</select>
{{model.name}} {{model.currencies[0]}}
</div>
Here's a working plnkr
After analysing your code and agreeing with #CozyAzure, I could see that there is this controller Ctrl which doesn't do anything in the script.
Do you really need this? Eliminate it from your script.js and index.html and do a run. This would surely fetch the data in the desired way.
I am creating a custom directive in AngularJS. This directive should open a popup to display data. The code for the popup is in another html page and the custom directive injects the code into my main page. I am able to open the popup however I cannot display the existing data anywhere in the pop up.
Normally, I am able to display the data in the main page however the data just do not want to go into the html injected by the custom directive.
Like this I do not get any error however it does not pass the data.
Note: I had to trim some of the code here to simplify it.
This is my custom directive:
function updateCandidatePopup() {
var directive = {};
directive.restrict = "E";
directive.scope = {};
directive.templateUrl = "UpdateCandidatePopup.html";
directive.controller = function ($scope) {
$scope.SingleCandidate;
}
return directive;
}
This is where I register it:
myApp.directive("updateCandidatePopup", UpdateCandidatePopup);
This is how I use the directive in the mainpage
<update-candidate-popup value="SingleCandidate" class="modal fade" ng-model="SingleCandidate"
id="myUpdateModal"
role="dialog"
popup-data="SingleCandidate">
zxc</update-candidate-popup>
This is the UpdateCandidatePopup.html:
<div> {{SingleCandidate.FirstName}} </div>
This is the to display the data in the pop up controller: (FYI it is still trimmed)
myApp.controller('CandidatesController', function ($scope, $http, EmployerService, CandidateService) { //we injected localservice
//Select single data for update
$scope.getSingleData = function (C_ID) {
alert(C_ID);
$http.get('http://localhost:49921/api/Candidates/?C_ID=' + C_ID).success(function (data) {
$scope.SingleCandidate = data;
$scope.FName = $scope.SingleCandidate.FirstName;
alert($scope.SingleCandidate.FirstName);
alert($scope.FName);
}).error(function () {
$scope.error = "An Error has occured while loading posts!";
});
};
});
Sorry wrong !, answered your question, here I leave I found a code that will serve for your problem. In the background to the template you want to take, you let a controller and in the statement of your policy, put you going to do with those values, I think in your case is just printing.
myApp.directive('editkeyvalue', function() {
return {
restrict: 'E',
replace: true,
scope: {
key: '=',
value: '=',
accept: "&"
},
template : '<div><label class="control-label">{{key}}</label>' +
'<label class="control-label">{{key}}</label>' +
'<input type="text" ng-model="value" />'+
'<button type="button" x-ng-click="cancel()">CANCEL</button>' +
'<button type="submit" x-ng-click="save()">SAVE</button></div>',
controller: function($scope, $element, $attrs, $location) {
$scope.save= function() {
console.log('from directive', $scope.key, $scope.value);
$scope.accept()
};
}
}
});
jsFiddle
Solved the problem like below. It was only to inject to $scope in the directive controller.
myApp.directive("updateCandidatePopup", function () {
return {
templateUrl : "UpdateCandidatePopup.html",
restrict: 'E',
controller: function ($scope) {
}
}
});
I'm trying to wrap a ui-select in a custom directive. (https://github.com/angular-ui/ui-select)
this.adminv2.directive('eventSelect', function() {
return {
restrict: 'E',
replace: true,
scope: {
ngModel: '=',
placeholder: '='
},
controller: function($scope, $http) {
return $scope.refreshEvents = function(searchTerm) {
return $http.get('/events/autocomplete', {
params: {
term: searchTerm
}
}).then(function(response) {
return $scope.events = response.data;
});
};
},
template: "<div>{{ngModel}}\n <ui-select ng-model=\"ngModel\"\n theme=\"bootstrap\"\n ng-disabled=\"disabled\"\n reset-search-input=\"false\">\n <ui-select-match placeholder=\"Enter an event\">{{$select.selected.name}}</ui-select-match>\n <ui-select-choices repeat=\"event in events track by $index\"\n refresh=\"refreshEvents($select.search)\"\n refresh-delay=\"0\">\n <span ng-bind-html=\"event.name | highlight: $select.search\"></span>\n <i class=\"icon-uniF111 fg type-{{raceType}} pull-right\" ng-repeat='raceType in event.racetypes'></i>\n <br>\n {{event.dates}} <i class='pull-right'>{{event.location}}</i>\n </ui-select-choices>\n </ui-select>\n</div>"
};
});
The select works properly, but the binding with ng-model doesn't work. I cannot set the model or read it.
I don't get it since it works when I use a simple template such as
<div><input ng-model="ngModel"></div>
Is there something special to do because I wrap a directive in directive ?
I managed to make the binding work by setting the ng-model in the template as
ng-model="$parent.ngModel"
I have this simple code of my directive:
app.directive('ngModal', function ($parse) {
return {
restrict: 'E',
template: document.getElementById('ng-modal').innerHTML,
replace: true,
controller : "#",
name:"controllerName",
}
})
<ng-modal controller-name="ModalCtrl"></ng-modal>
And this is my controller:
app.controller('ModalCtrl', ['$scope', function ($scope) {
$scope.model = 'default text'
}])
<div ng-controller="ModalCtrl">
<input type="text" ng-model="model">
</div>
I want, that model field inside my Directive will updated automatically. But I see "default text" always inside directive and changed inside controller. How can I bind it?
You have to add a service to keep information between controllers. Controllers are always created per "view" so your ng-modal and div have different controllers in use, this is why model data is not updated between them.
Fast example:
app.service('sharedData', function() {
var sharedData = {
field: 'default text'
};
return sharedData;
});
app.directive('ngModal', function () {
return {
restrict: 'E',
template: '',
replace: true,
controller : "#",
name:"controllerName",
}
});
app.controller('ModalCtrl', ['$scope', 'sharedData', function ($scope, sharedData) {
$scope.model = sharedData;
}]);
<ng-modal controller-name="ModalCtrl">{{model.field}}</ng-modal>
<div ng-controller="ModalCtrl">
<input type="text" ng-model="model.field">
</div>