So, I have the same question asked on this question, sadly, no one has answered, so, here it goes again
I'm trying to create a select directive, where I can send the ng-options as a parameter.
This is my directive
app.directive('dropDown', function () {
return {
restrict: 'E',
template: function (element, attrs) {
return '<div class="col-sm-{{labelCol}} control-label">' +
'<label>{{label}}:</label>' +
'<div>' +
'<div clas="col-sm-{{controlCol}}">' +
'<label style="cursor:pointer" ng-show="!edit && forEdit" ng-disabled="disabled" ng-click="edit = true;">{{ngModel}}</label>' +
'<i ng-show="!edit && forEdit && !disabled" class="fa fa-pencil-square-o" style="cursor:pointer" aria-hidden="true" ng-click="edit = true;"></i>' +
'<select name="{{name}}" ng-change="ngChange" ng-blur="edit = false" ng-show="edit || !forEdit" class="form-control" ng-model="ngModel" ng-required="required" ng-options={{options}}/>' +
'</div>'
},
replace: true,
scope: {
ngModel: '=',
ngChange: '&',
label: '#',
labelCol: '#',
controlCol: '#',
type: '#',
name: '#',
disabled: '=',
required: '=',
forEdit: "=",
options: "#"
},
link: function (scope, element, attrs) { },
compile: function (element, attrs) {
if (!attrs.labelCol) attrs.labelCol = '4';
if (!attrs.controlCol) attrs.controlCol = '8';
if (!attrs.required) attrs.required = false;
if (!attrs.disabled) attrs.disabled = false;
if (!attrs.forEdit) attrs.forEdit = false;
attrs.edit = !attrs.forEdit;
}
}
})
And this is a implementation of the directive
<div class="row">
<drop-down ng-model="site" for-edit="true" label="Site Test" options="x.SITE_CODE as x.SITE_NAME for x in sites"></drop-down>
</div>
<div class="row">
<drop-down ng-model="site1" for-edit="true" label="Site Test" options="x for x in sites1"></drop-down>
</div>
And I'm getting the same response
Error: [$parse:syntax] Syntax Error: Token 'in' is an unexpected token
at column 3 of the expression [x in sites1] starting at [in sites1].
Error: [$parse:syntax] Syntax Error: Token 'as' is an unexpected token
at column 13 of the expression [x.SITE_CODE as x.SITE_NAME for x in
sites] starting at [as x.SITE_NAME for x in sites].
Any idea how to achieve my desired result?
Edit1:
If it help, here's the arrays that should be filling the selects
$scope.sites = JSON.parse("[{\"SITE_CODE\":\"1\",\"SITE_NAME\":\"SITE1\",},{\"SITE_CODE\":\"2\",\"SITE_NAME\":\"SITE2\"},{\"SITE_CODE\":\"3\",\"SITE_NAME\":\"SITE3\"},{\"SITE_CODE\":\"4\",\"SITE_NAME\":\"SITE4\"}]");
$scope.sites1 = ["SITE1", "SITE2", "SITE3", "SITE4"];
Edit 2:
Added the error for the more complex ng-options sentence
Edit 3:
So, I just realized that, I'm setting the ngOptions as a 2 way databinding field on the scope, as, it's not necesary, so I changed it from = to # and now, I'm getting another error message
Error: [$compile:ctreq] Controller 'select', required by directive 'ngOptions', can't be found!
Which, it's unreasonable, as I'm indeed setting the ngOptions, and I can verify it on the compile
Edit 4:
So, after some testing, I'm finally getting my controls rendered, but sadly, withouth values
The selects are clearly on the controller div
<div class="content" ng-controller="testController">
<div class="row">
<drop-down ng-model="site" for-edit="true" label="Site Test" options="x for x in sites"></drop-down>
</div>
<div class="row">
<drop-down ng-model="site" label="Site Test" options="x for x in sites"></drop-down>
</div>
<div class="row">
<drop-down ng-model="site1" for-edit="true" label="Site Test" options="x for x in sites1"></drop-down>
</div>
</div>
The controller indeed has this collections
app.controller('testController', ['$scope', function ($scope) {
$scope.sites = JSON.parse("[{\"SITE_CODE\":\"1\",\"SITE_NAME\":\"SITE1\",},{\"SITE_CODE\":\"2\",\"SITE_NAME\":\"SITE2\"},{\"SITE_CODE\":\"3\",\"SITE_NAME\":\"SITE3\"},{\"SITE_CODE\":\"4\",\"SITE_NAME\":\"SITE4\"}]");
$scope.sites1 = ["SITE1", "SITE2", "SITE3", "SITE4"];
}]);
But my rendered controls comes without any values
This is the rendered html for one of the controls
<div ng-model="site" label="Site Test" options="x for x in sites" class="ng-isolate-scope ng-valid">
<div class="col-sm-4 control-label"><label class="ng-binding">Site Test:</label></div>
<div class="col-sm-8">
<label style="cursor:pointer" ng-show="!edit && forEdit" ng-disabled="disabled" ng-click="edit = true;" class="ng-binding ng-hide"></label>
<i ng-show="!edit && forEdit && !disabled" class="fa fa-pencil-square-o ng-hide" style="cursor:pointer" aria-hidden="true" ng-click="edit = true;"></i>
<select name="" ng-change="ngChange" ng-blur="edit = false" ng-show="edit || !forEdit" class="form-control ng-pristine ng-valid ng-valid-required ng-touched" ng-model="ngModel" ng-required="required" ng-options="x for x in sites">
<option value="?" selected="selected"></option>
</select>
</div>
</div>
At least now I'm getting my controls rendered, now, on to show some values on them
The syntax ng-options="x in sites1" is incorrect.
In it's most simplest form it should be label for value in array:
ng-options="x for x in sites1"
Also check out the angular docs for ngOptions to see all of the permitted argument forms.
Well, after much testing, I finally am able to achieve my desired result.
I'll leave the directive here to whoever might want to use it, as it allows to
Set a desired options string
Set a property to show in case we store the complete object in the model
Disabled status, that will only show the model value
Inline edit of the value
var app = angular.module("app", []);
app.controller('testController', ['$scope', function($scope) {
$scope.sites = JSON.parse("[{\"SITE_CODE\":\"1\",\"SITE_NAME\":\"TEST 1\"},{\"SITE_CODE\":\"2\",\"SITE_NAME\":\"TEST 2\"},{\"SITE_CODE\":\"3\",\"SITE_NAME\":\"TEST 3\"},{\"SITE_CODE\":\"4\",\"SITE_NAME\":\"TEST 4\"}]");
$scope.sites1 = ["TEST 1", "TEST 2", "TEST 3"];
}]);
app.directive('dropDown', function() {
return {
restrict: 'E',
require: 'ngOptions',
template: function(element, attrs) {
return '<div>' +
'<div class="col-sm-{{labelCol}} control-label">' +
'<label>{{label}}:</label>' +
'</div>' +
'<div class="col-sm-{{controlCol}}">' +
'<label ng-show="!edit && forEdit">{{ngModel[textValue] !== undefined ? ngModel[textValue] : ngModel}}</label> ' +
'<span ng-show="!edit && forEdit && !disabled" class="fa fa-pencil-square-o" style="cursor:pointer" aria-hidden="true" ng-click="edit = true;">click here for edit</span>' +
'<select name="{{name}}" ng-change="ngChange" ng-blur="edit = false" ng-show="edit || !forEdit" class="form-control" ng-model="ngModel" ng-required="required" ng-options="{{options}}"/>' +
'</div>' +
'</div>';
},
replace: true,
scope: {
ngModel: '=',
ngChange: '&',
label: '#',
labelCol: '#',
controlCol: '#',
type: '#',
name: '#',
disabled: '=',
required: '=',
forEdit: "=",
options: "#",
items: "=",
textValue: "#"
},
compile: function(element, attrs) {
if (!attrs.labelCol) attrs.labelCol = '4';
if (!attrs.controlCol) attrs.controlCol = '8';
if (!attrs.required) attrs.required = false;
if (!attrs.disabled) attrs.disabled = false;
if (!attrs.forEdit) attrs.forEdit = false;
if (attrs.disabled)
attrs.forEdit = "true";
attrs.edit = !attrs.forEdit;
},
link: function(scope, element, attrs) {
},
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div class="" ng-controller="testController">
<div class="row">
<drop-down ng-model="site" for-edit="true" label="Site Test Inline" text-value="SITE_NAME" options="x.SITE_NAME for x in items" items="sites"></drop-down>
<drop-down ng-model="site1" for-edit="false" label="Site Test Select" options="x for x in items" items="sites1"></drop-down>
<drop-down ng-model="site1" disabled="true" label="Site Test Disabled" options="x for x in items" items="sites1"></drop-down>
</div>
</div>
</div>
I have a array with form questions which has label(_text), type(QuestionData._fieldType). on basis of fieldtype I want to creata directive.
Here I am stuck how to pass parameters to directives and use inside directive.
html
<div ng-controller="autoQuoteCtrl">
<form class="form-horizontal text-center" role="form" name="DTOstep1" ng-submit="onSubmit()">
current page:{{$state.current.name}}
<div ng-repeat="que in questions[$state.current.name]">
<div ng-if="que.QuestionData._fieldType === 'text'" >
text - <code>{{que.QuestionData._attributeName}}</code>
<text-control-dir data="que"></text-control-dir>
<!-- <question-dir>print from directive</question-dir> -->
</div>
<div ng-if="que.QuestionData._fieldType === 'select'" >
select - <code>{{que.QuestionData._attributeName}}</code>
<select-control-dir data="que"></select-control-dir>
</div>
<div ng-if="que.QuestionData._fieldType === 'radio'" >
select - <code>{{que.QuestionData._attributeName}}</code>
<radio-control-dir data="que"></radio-control-dir>
<!-- <question-dir>print from directive</question-dir> -->
</div>
<div ng-if="que.QuestionData._fieldType === 'hidden' && que.QuestionData._attributeName != 'CBQ'" >
hidden - <code>{{que.QuestionData._attributeName}}</code>
<hidden-control-dir data="que"></hidden-control-dir>
<!-- <question-dir>print from directive</question-dir> -->
</div>
</div>
<input type='hidden' id="save_quote_email" name="save_quote_email" ng-model="AutoQuote.postAutoQuoteObj.ApplicationInfo.GeneralPartyInfo.ContactInfo.Emails[0].EmailAddress" value="praveend06#gmail.com" />
{{AutoQuote.postAutoQuoteObj.ApplicationInfo.GeneralPartyInfo.ContactInfo.Emails[0].EmailAddress}}
<input type="submit" value="Save" />
{{AutoQuote.postAutoQuoteObj.SessionInfo.StateCode}}
</form>
</div>
controlDirective.js
(function () {
"use strict";
angular
.module("autoQuote")
.directive('textControlDir', [textControlDir])
.directive('selectControlDir', [selectControlDir])
.directive('radioControlDir', [radioControlDir])
.directive('hiddenControlDir', [hiddenControlDir]);
function textControlDir(data)
{
console.log('here in text directive');
console.log(data);
return {
transclude: true, // append html
restrict: 'E',
template: "<div ng-transclude></div>\n\
\n\
<label>{{data._text}} </label><input type='text' name='' id='' value='' >"
};
}
function selectControlDir()
{
console.log('here in select directive');
return {
transclude: true,
template: "<h1>Made by a select directive!</h1>"
};
}
function radioControlDir()
{
console.log('here in radio directive');
return {
transclude: true,
template: "<h1>Made by a radio directive!</h1>"
};
}
function hiddenControlDir()
{
console.log('here in hidden directive');
return {
transclude: true,
template: "<h1>Made by a hidden directive!</h1>"
};
}
}());
please check my plunker link for complete code. http://plnkr.co/edit/Op1QDwUBECAosPUC7r3N?p=preview
when you want to define the template of your directive, instead of template itself you can use a function of the form:
angular.module("autoQuote")
.directive('question', function() {
return {
template: function(elem, attrs) {
if (angular.isDefined(attrs["type"])) {
switch attrs["type"]:
case "text":
return "<input type='text' name='' id='' value='' >"
case "radio":
// return radio template
}
}
....
}
});
and you can write a general directive like question and use it like this: <question type="{{que.QuestionData._fieldType}}"></question>.
Also you can check this answer for more information.
Hope it helps
I need one help.i need to open one pop up window whose code is present inside the my deal.php page.I need to open by declaring the directive inside my controller function.Let me to explain my code below.
deal.php:
<li ui-sref-active="active"><a ui-sref="productdata">Add Product Stock</a></li>
<div class="container">
<!-- Chats, File upload and Recent Comments -->
<!--1st Chat window -->
<div class="row" ui-view>
</div>
<!-- End 1st chat window -->
</div>
<modal title="Specification" visible="showSpecification">
<textarea id="spec" class="form-control" ng-model="specification_modal" rows="7" style="width:100%;"></textarea>
</modal>
When user clicked on Add Product Stock it will move to the below path.
.state('productdata',{
url:'/data',
templateUrl:'productview/productData.html',
controller:'productDataController'
})
productData.html:
<div class="input-group bmargindiv1 col-md-12">
<span class="input-group-addon ndrftextwidth text-right" style="width:180px">Product Name :</span>
<select class="form-control" id="product_name" ng-model="product_name" ng-options="cat.name for cat in listOfProduct track by cat.value " ng-change="removeBorder('product_name');">
</select>
</div>
Here i need when i wiil select the product name from the list the modal pop up window should open.
productDataController.js:
var productData=angular.module('medilink');
productData.controller('productDataController',function($scope,$http,$state,$window,$filter,Upload,productInpuFieldFocus){
$scope.removeBorder=function(id){
}
})
productData.directive('modal', function () {
return {
template: '<div class="modal fade">' +
'<div class="modal-dialog">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>' +
'<h4 class="modal-title">{{ title }}</h4>' +
'</div>' +
'<div class="modal-body" ng-transclude></div>' +
'</div>' +
'</div>' +
'</div>',
restrict: 'E',
transclude: true,
replace:true,
scope:true,
link: function postLink(scope, element, attrs) {
scope.title = attrs.title;
scope.$watch(attrs.visible, function(value){
if(value == true)
$(element).modal('show');
else
$(element).modal('hide');
});
$(element).on('shown.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = true;
});
});
$(element).on('hidden.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = false;
});
});
}
};
});
Here my requirement is when user will select the value from drop down the pop up window will open and the value should display in text area of the pop up window.Please help me.
This is my directive to show an input field:
JS:
.directive('isField', function () {
return {
restrict: 'EA',
template: '<div class="form-group">' +
'<label class="col-sm-2 control-label">{{prop}}</label>' +
'<div class="col-sm-10">' +
'<label ng-if="obj.prop" class="control-label" style="font-weight:normal;">Yes</label>' +
'<label ng-if="!obj.prop" class="control-label" style="font-weight:normal;">No</label>' +
'</div>' +
'</div>',
scope: {
obj: "#obj",
prop: "#prop",
},
controller: function(){
},
link: function(scope,elem,attr,ctrl){
}
};
})
HTML:
<is-field obj="pano" prop="isOutRoom" class="ng-isolate-scope">
<div class="form-group">
<label class="col-sm-2 control-label ng-binding">isOutRoom</label>
<div class="col-sm-10">
<!-- ngIf: obj.prop -->
<!-- ngIf: !obj.prop -->
<label ng-if="!obj.prop" class="control-label ng-scope" style="font-weight:normal;">No</label>
<!-- end ngIf: !obj.prop -->
</div>
</div>
</is-field>
But obj.prop is not being evaluated, the directive shows No even when obj.prop is true.
Sample JSON:
pano:
{
"objectId": "566f915b00b0814d65fa12e0",
"isVirtualRoom": true,
}
Am I doing something wrong with the scope: part of the directive?
I think the error is in your template and precisely in ng-if, you template should be like
.directive('isField', function () {
return {
restrict: 'EA',
template: '<div class="form-group">' +
'<label class="col-sm-2 control-label">{{prop}}</label>' +
'<div class="col-sm-10">' +
'<label ng-if="prop" class="control-label" style="font-weight:normal;">Yes</label>' +
'<label ng-if="!prop" class="control-label" style="font-weight:normal;">No</label>' +
'</div>' +
'</div>',
scope: {
obj: "#obj",
prop: "#prop",
},
controller: function($scope){
},
link: function(scope,elem,attr,ctrl){
}
};
})
this is a worked demo
i am having trouble with populating modal window form. For example, I click on grid row for editing user and I call ajax which returns me specific data of user.
Current code:
<modal title="Uredi uporabnika" visible="showModal">
<form role="form">
<div class="form-group">
<label for="user_name">Ime</label>
<input type="text" class="form-control" id="user_name" />
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</modal>
Controller:
$scope.openUserEditor = function(selected_user_id){
$http({
method:'POST',
url:ajax,
dataType: 'json',
headers: {
'Content-type': 'application/x-www-form-urlencoded;charset=utf-8'
},
data:{
action:'loadUserData',
id:selected_user_id
}
}).success(function(data,status){
$scope.userInfo = data.user_info;
$scope.showModal = !$scope.showModal;
});
}
Modal window code:
app.directive('modal', function(){
return {
template: '<div class="modal fade">' +
'<div class="modal-dialog">' +
'<div class="modal-content">' +
'<div class="modal-header">' +
'<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>' +
'<h4 class="modal-title">{{ title}}</h4>' +
'</div>' +
'<div class="modal-body" ng-transclude></div>' +
'</div>' +
'</div>' +
'</div>',
restrict: 'E',
transclude: true,
replace:true,
scope:true,
link: function postLink(scope, element, attrs) {
scope.title = attrs.title;
scope.$watch(attrs.visible, function(value){
if(value == true)
$(element).modal('show');
else
$(element).modal('hide');
});
$(element).on('shown.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = true;
});
});
$(element).on('hidden.bs.modal', function(){
scope.$apply(function(){
scope.$parent[attrs.visible] = false;
});
});
}
};
});
I would apreciate any help, even if I am doing in on right way becouse I am new at Angular.
Use the input ID to populate the values:
$("#user_name").val(data.user_info);
Ok I found solution after millions of different trys and I've just put hands over my head.
<input type="text" class="form-control" id="user_name" value="{{userInfo.u_name}}" />
So I had to add userInfo object and call that parameter u_name.
tnx Shivi for help anyway :D