I am trying to do a Pop-up in Angular.js with a table, where there is an option to click in a particular cell in a row which gives a pop-up. Below is the code snip.
Html code
<table class="table table-bordered">
<tr><th>Number</th><th>Comment</th></tr><tr ng-repeat="col in Data|filter:search1"><td>{{col.cd}}</td><td><div ng-controller="igCtrl">
Comment
<ig-comment></ig-comment>
</div></td></tr></table>
Controller
function igCtrl($scope) {
$scope.addComment = function (col) {
$scope.cdn="";
$scope.cdn = col;
console.log("testing"+$scope.cdn);
$scope.check = true;
if ($scope.check) {
$("#comment").modal('show');
};
};}
Directive
app.directive('igComment', function () {
return {
restrict: 'E',
replace: true,
template:'<div class="row">
<div class="modal fade" id="comment" aria-hidden = "true" >
<div class = "modal-dialog" style="width:300px;height:600px;">
<form class="form-horizontal" name="form" ng-submit = "submit()" novalidate="novalidate">
<div class = "modal-content" >
<div class = "modal-header">
Data is :{{cdn}}
<input ng-disabled="form.$invalid" type="submit" class="btn btn-primary" id="submit" ng-click="submit()" value="Submit"></input >
<input type="button" class="btn btn-primary" data-dismiss="modal" value="Cancel" ng-click="cancel()"></input>
</div>
</div >
</form>
</div >
</div>
</div>'
};
});
Data for this table is coming from the database. The variable cdn in the controller is getting updated and the console.log statement in the controller gives correct output.
But cdn in the directive is not getting updated and hence not showing rite results in the pop-up.
How to rectify this?
Thanks
I'd use an isolated scope for this.
e.g.:
<ig-comment cdn="cdn"></ig-comment>
* this takes the "cdn" value from the controller's scope
and in the directive:
return {
restrict: 'E',
replace: true,
scope: { cdn: '=' } // this assigns the "cdn" from the directive attribute above
// to the directive isolated scope (under the same name)
...
The rest seems fine (ignoring the unfortunate jquery mix) and should work.
Related
I have 2 directives that are on the same level as follows:
function signUpForm(djangoAuth, Validate){
return{
restrict:'A',
controller:["$rootScope","$scope",function($rootScope, $scope){
$scope.submitFunction = function(formData){
//do stuff
}
}]
}}
function signInForm(djangoAuth, Validate){
return{
restrict:'A',
controller:["$rootScope","$scope",function($rootScope, $scope){
$scope.submitFunction = function(formData){
//do stuff
}
}]
}}
My HTML is as follows:
<div>
<div class="email_log_container">
<form name="signup_form" class="signup_form" sign-up-form
novalidate ng-submit="submitFunction(signup_form)">
<input type="submit" name="submit" value="Submit" >
</form>
</div>
<div class="email_log_container">
<form name="signin_form" class="signin_form" sign-in-form
novalidate ng-submit="submitFunction(signin_form)">
<input type="submit" name="submit" value="Submit" >
</form>
</div>
</div>
The problem is that when I click the submit button on the second form, it actually submits the first form which results in errors. So I went on to add isolate scopes to the directives, now what happens is that the functions and attributes attached to $scope in the controller are not being picked up now. For example ng-submit does not know about the submitFunction within the controller.
Can anyone help me with ideas on how to stop these two directives from interfering with each other?
While you are using a controller but no template for your directive this will not work. Try it like in this runnable demo fiddle and add the form as a template into your directive. In that way you will be able to handle all the $scope goodness in your directive controller itself. The template itself will be compiled and uses the directive controller.
View
<div ng-controller="MyCtrl">
<div class="email_log_container">
<sign-in-form></sign-in-form>
</div>
</div>
AngularJS application
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
});
myApp.directive('signInForm', function signInForm(){
return{
restrict:'E',
replace: true,
template: '<form name="signin_form" class="signin_form" sign-in-form novalidate ng-submit="submitFunction(signin_form)"><input type="submit" name="submit" value="Submit" ></form>',
controller:["$rootScope","$scope",function($rootScope, $scope){
$scope.submitFunction = function(formData){
//do stuff
console.log('sdfsdfd');
}
}]
}});
I am having form in ng-repeat with different form names.
i want to pass the form when some button clicked inside form.
When am calling like below
checkSaveDisable(updateProductSale_{{productIndex}}) it throwing some angular js error.
It might be am passing the angular expressions inside the function call. How can i pass the form which contains dynamic name in function.
HTML:
<div ng-repeat="productSale in productSales" class="existingProductSales" ng-init="productIndex=$index">
<form name="updateProductSale_{{productIndex}}" novalidate>
---------------//
<button class="btn btn-default save-btn save-sale" ng-disabled="checkSaveDisable(updateProductSale_{{productIndex}})" >Save</button>
</form>
</div>
updateProductSale_{{productIndex}} is a string value, right? If so, to pass the string value as an argument, try to use
ng-disabled="checkSaveDisable('updateProductSale_{{productIndex}}')"
UPDATE: Okay, what if you use the following?
ng-disabled="checkSaveDisable('updateProductSale_' + {{productIndex}})"
angular.module('MyApp', []).controller('AppCtrl', function($scope) {
$scope.productSales = ['Form1', 'Form2'];
$scope.click = function(val) {
alert(val);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<div ng-controller="AppCtrl" ng-cloak="" ng-app="MyApp">
<div ng-repeat="productSale in productSales">
<form name="updateProductSale_{{$index}}" novalidate>
<button class="btn btn-default save-btn save-sale" ng-click="click('updateProductSale_' + $index)" >Save</button>
</form>
</div>
</div>
I am not very familiar with the directives in the AngularJS as I'm used on relying on controllers. Is it possible to set validity on other inputs via directive? Here is the case, I have a button and when it is clicked.. It should set a validity on a certain input text. But I just can not seem to get the code that will set the validity.
Here is the HTML code:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body>
<div class="container">
<div id="login-container">
<div class="form-group">
<span class="glyphicon glyphicon-user"></span>
</div>
<form name="loginForm" novalidate>
<div class="form-group">
dasdas -- {{ loginForm.student_code.$error.codeValidity }}
<input type="text" class="form-control text-center" name="student_code" ng-model="studentCode" placeholder="Enter Exam Code" required />
<span class="errors" id="error-student-code" ng-if="loginForm.student_code.$error.codeValidity">{{ errors }}</span>
</div>
</form>
<login-button form="loginForm"></login-button>
<button class="btn btn-primary">Register</button>
</div>
</div>
</body>
</html>
Here is the JS Code:
var app = angular.module("myApp", []);
app.directive('loginButton', loginButton);
loginButton.$inject = ["$http", "$window"];
function loginButton($http, $window){
return {
template: '<button type="button" class="btn btn-primary">Take Exam</button>',
link: function(scope, element, attrs, ctrl){
element.on('click', function(){
form = attrs.form;
form.student_code.$setValidity('codeValidity', true);
scope.errors = "Code is Invalid";
});
}
}
}
Here is a sample on plunker: http://plnkr.co/edit/kcdDgZpStQixTpGWqxOp?p=preview
PS.
I know this can be easily achieved using controllers but I would like to achieve this using directives as my practice to get used to it.
Yes, it is possible and you almost got it right. What you wanna do is pass form to isolated scope and then use in directive controller.
There is no need to add event manually, as you can use ng-click.
Otherwise you would need to use $scope.$apply.
In directives you can use linking function, but you don't have to.
In general it is good practice to keep light logic in controller and DOM manipulation in linking function.
var app = angular.module("myApp", []);
app.directive('loginButton', loginButton);
loginButton.$inject = ["$http", "$window"];
function loginButton($http, $window){
return {
template: '<button type="button" class="btn btn-primary" ng-click="click()">Take Exam</button>',
scope: {
form: '='
},
controller: function($scope){
$scope.click = function(){
form = $scope.form;
form.student_code.$setValidity('codeValidity', false);
};
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<div ng-app="myApp">
<div class="container">
<div id="login-container">
<div class="form-group">
<span class="glyphicon glyphicon-user"></span>
</div>
<form name="loginForm" novalidate>
<div class="form-group">
dasdas -- {{ loginForm.student_code.$error }}<br>
<input type="text" class="form-control text-center" name="student_code" ng-model="studentCode" placeholder="Enter Exam Code" required />
<span class="errors" id="error-student-code" ng-if="errors">{{ errors }}</span>
</div>
</form>
<login-button form="loginForm"></login-button>
<button class="btn btn-primary">Register</button>
</div>
</div>
</div>
Consider the form:
<form class="form" name="myForm" ng-submit="submit()">
<div class="form-group" ng-class="{'has-error': myForm.title.$invalid}">
<label for="title">Title: </label>
<input id="title" name="title" class="form-control" ng-model="title"
required>
<div ng-messages="myForm.title.$dirty && myForm.title.$error" role="alert">
<div ng-message="required" class="alert small with-error-font">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
Title is required!
</div>
</div>
</div>
</form>
I want to achieve the following behaviour:
Validation error message should appear if user started typing and left the field empty (it's not pristine anymore). Otherwise, it shouldn't be visible till user clicks submit.
So I thought it could be done by using sort of 'aspect'/'interceptor' which simply checks if form is valid. If it is, then it should invoke ng-submit function. If not, then it should invoke $setDirty on each field (so that validation errors appear) and simply return.
I want to achieve it by creating ma own directive, like the following:
let validateAndSubmit = function (onValidationSuccessCallback) {
return function () {
// this is where validation logic should happen
onValidationSuccessCallback();
};
};
let ValidatingFormDirective = function () {
return {
restrict: 'E',
transclude: true,
replace: true,
scope: {
name: '#',
postValidationCallback: '&'
},
link: function (scope) {
scope.validateAndSubmit = validateAndSubmit(scope.postValidationCallback);
},
templateUrl: 'app/events/common/forms/validating-form.template.html'
}
};
export default ValidatingFormDirective;
and here's my directive template:
<form name="{{name}}" novalidate ng-submit="validateAndSubmit()" ng-transclude></form>
Problem:
Now if I change form to validation-form in my html, it seems like myForm is not recognized at all, because neither ngMessages block nor ng-class appears.
How can I fix it? Or maybe should I try completely different approach?
Inside showdetailsOfInside() function value of ng-model variable namein and agein that is inside bind-unsafe-html coming undefined however i have filled text contents into it.I can get value through jquery but is there any way to do it through angular js.
<body ng-controller="AppController" class="container">
Name <input type="text" name="name" ng-model="name" /><br>
Age <input type="text" name="age" ng-model="age"/><br>
<button type="button" class="btn btn-primary" ng-click="showdetailsOfInside()">showdetailsOfInside</button><br>
<div bind-unsafe-html="primaryData"></div>
<body>
Content of bind-unsafe-html="primaryData"
<button type="button" class="btn btn-primary" ng-click="shownName()">inside Basic</button><br>
<button type="button" class="btn btn-primary" ng-click="showAge()">inside Primary</button><br>
Name inside <input type="text" name="namein" ng-model="namein" id="nameinside"/><br>
Age indise :: <input type="text" name="agein" ng-model="agein" id="ageinside"/><br>
Code of bind-unsafe-html directive
dynamicContentApp.directive('bindUnsafeHtml', ['$compile', function ($compile) {
return function(scope, element, attrs) {
scope.$watch(
function(scope) {
// watch the 'bindUnsafeHtml' expression for changes
return scope.$eval(attrs.bindUnsafeHtml);
},
function(value) {
// when the 'bindUnsafeHtml' expression changes
// assign it into the current DOM
element.html(value);
// compile the new DOM and link it to the current
// scope.
// NOTE: we only compile .childNodes so that
// we don't get into infinite loop compiling ourselves
$compile(element.contents())(scope);
}
);
};
}]);
If i'm right, that's ng-bind-unsafe-html="primaryData"
dynamicContentApp.directive('bindUnsafeHtml', ['$compile', function ($compile) {
return {
link: function (scope, element, attrs) {
//code goes here
};
}
}]);