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
Related
I could not get text field value present inside the modal pop up using Angular.js. I am providing my code below.
view.html:
<modal title="Driver Information" visible="showModal">
<div class="col-md-12">
<div class="form-group">
<label>Comment</label>
<textarea class="form-control" id="comment" rows="3" ng-model="comment"></textarea>
</div>
</div>
<button class="btn btn-success" id="singlebutton" ng-click="save();">Save</button>
<div style="clear:both;"></div>
</modal>
My controller page is given below.
viewcontroller.js:
var dashboard=angular.module('easyride');
dashboard.controller('viewcontroller',function($scope){
$scope.save=function(){
console.log('comment',$scope.comment);
}
})
dashboard.directive('modal', function () {
return {
template: '<div class="modal fade">' +
'<div class="modal-dialog modal-lg">' +
'<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;
});
});
}
};
});
In the console message I am getting the blank value even I am entering some value in comment field and click on save button. Here I need to get the user typed the comment value after click on save button and once the value will be printed via console message the pop up should close.
i made some simple changes in your code, check it and it works
visible="showModal"
ng-click="save(comment);"
$scope.save=function(comment){
console.log('comment',comment);
$scope.comment = comment;
$scope.showModal = false;
}
here is jsfiddle
https://jsfiddle.net/0m8mpx43/2/
you can pass it from the ng-click itself
<modal title="Driver Information" visible="showModal">
<div class="col-md-12">
<div class="form-group">
<label>Comment</label>
<textarea class="form-control" id="comment" rows="3" ng-model="comment"></textarea>
</div>
</div>
<button class="btn btn-success" id="singlebutton" ng-click="save(comment);">Save</button>
<div style="clear:both;"></div>
</modal>
then in controller
var dashboard=angular.module('easyride');
dashboard.controller('viewcontroller',function($scope){
$scope.save=function(comment){
console.log('comment',comment);
}
})
As I have mentioned in my comment - you are creating a new scope by inheriting parent scope, so $scope.comment in your controller will not be the same as $scope.comment in your directive. You have to use a "dot in your model" to make it work. If you want to close a modal after - you can implement this method inside the directive and then call it by passing as an argument. Here is a working example, that illustrates the mentioned changes to your code:
angular.module('easyride', [])
.controller('viewcontroller',function($scope){
$scope.modelForModal = {
showModal: true,
comment: '',
save: function (closeModal){
console.log('comment',$scope.modelForModal.comment);
if (angular.isFunction(closeModal)) { closeModal(); }
}
};
})
.directive('modal', function () {
return {
template: '<div class="modal fade">' +
'<div class="modal-dialog modal-lg">' +
'<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');
});
scope.$parent.closeModal = scope.closeModal = function() {
$(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;
});
});
}
};
});
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/css/bootstrap.min.css">
<body ng-app="easyride">
<div ng-controller="viewcontroller">
<modal title="Driver Information" visible="modelForModal.showModal">
<div class="col-md-12">
<div class="form-group">
<label>Comment</label>
<textarea class="form-control" id="comment" rows="3" ng-model="modelForModal.comment"></textarea>
</div>
</div>
<button class="btn btn-success" id="singlebutton" ng-click="modelForModal.save(closeModal);">Save</button>
<div style="clear:both;"></div>
</modal>
</div>
</body>
<script type="text/javascript" src="//code.jquery.com/jquery-3.1.1.slim.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.3/js/bootstrap.min.js"></script>
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 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.
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
i am using datepicker and want to bind its value i wrote custom directive for it but know why its not binding value .
HtmlTagsdatepicker
<div class="col-md-6">
<label for="datepicker" class="col-lg-5 form-label">Date Of Birth:</label>
<div class="col-lg-7">
<input type="text" class="form-control dateBirth" ng-model="user.dob" id="datepicker" name="datepicker" datepicker="" value="" placeholder="Date Of Birth" required/>
<div class="error" ng-show="newUser_form.datepicker.$dirty && newUser_form.datepicker.$invalid">
<small class="error errorFields" ng-show="newUser_form.datepicker.$error.required">
Date is required.
</small>
</div>
</div>
</div
>
datepickerDirective.js
app.directive('datepicker', function() {
var linker = function(scope, element, attrs, ngModelCtrl) {
element.datepicker().on('changeDate', function(value){
var dateStrToSend = value.date.getFullYear() + '/' + (value.date.getMonth() + 1) + '/' + value.date.getDate();
ngModelCtrl.$setViewValue(dateStrToSend);
$(".datepicker").hide();
});
}
return {
require: 'ngModel',
restrict: 'A',
link: linker
}
});
I think you aren't in a digest cycle. Try $apply
element.datepicker().on('changeDate', function(value){
var dateStrToSend = value.date.getFullYear() + '/' + (value.date.getMonth() + 1) + '/' + value.date.getDate();
scope.$apply(function () {
ngModelCtrl.$setViewValue(dateStrToSend);
});
$(".datepicker").hide();
});