Using sweetalert 2 with custom html and AngularJS - angularjs

I am using SweetAlert2 with AngularJS, using this port to AngularJS 1.x : https://github.com/socialbase/angular-sweetalert-2.
I am trying to add some custom html in my swal, so when I do this:
angular.module('app').controller('TestController', function($scope, SweetAlert) {
$scope.test = "My test";
SweetAlert.swal({
type: 'warning',
html: '<input type="text" ng-model="test">'
}).then(function() {
});
});
It binds the html correctly, but it isn't binding ng-model using my variable test. Apparently it is putting the swal modal code outside my ng-controller in my html code.
How can I make my variable test work with AngularJS and SweetAlert?

Look at the code for this lib:
https://github.com/socialbase/angular-sweetalert-2/blob/master/lib/angular-sweetalert2.js
As you can see there is very little angular-related "porting", it's just a wrapper to the plain-JS library.
Therefore, it's simply not possible to put in your angular-specific code as a html and expect it to work.
However, looking at this lib's code examples, you could read html input's values after the dialog is closed.
angular.module('app').controller('TestController', function($scope, SweetAlert) {
$scope.test = "My test";
SweetAlert.swal({
type: 'warning',
html: '<input id="swal-input" type="text" ng-model="test">',
preConfirm: function() {
return document.getElementById('swal-input').value;
}
})
.then(function(value) {
$scope.test = value;
});
});

Related

Custom directive is not working/rendering the html on the browser

I have created a custom directive but when I try to render it on browser it is not working.Please see my code and guide me if you can see where I went wrong.
Below is my code
JS
var app = angular.module('main',[]);
app.controller('servicecntr', function ($scope) {
$scope.name='jagdish';
$scope.changeclick= function(){
$scope.name= $scope.name.split('').reverse().join('');
}
})
app.directive('myDirectives', function(){
return{
restrict:'EA',
scope:false,
template: "<div> this is the print out of name {{name}}" + "onclick the modelPannel is <input type='text' ng-model='name'",
}
})
change the scope:true,you are inherited the scope from the parent controller, you are trying to access the name from parent controller,and how you use this directive in html,i don't find that code.

Controller method not found when button inside template is pressed

I'm creating a project using NodeJS, Express and AngularJS that will have a search form (added via custom directive) and a search results that must be loaded only after the search button is pressed.
The problem is that the method I have created inside the controller can't be found from the search form.
Here is a sample of my code:
app.js
(function() {
var app = angular.module('app', ['app-directives']);
app.controller('AppController', function() {
this.buttonClick = function() {
alert('Test');
};
});
})();
directives.js
(function(){
var app = angular.module('app-directives', []);
app.directive('searchForm', function() {
return {
retrict: 'E',
templateUrl: '/partials/search-form.html'
};
});
app.directive('searchResults', function() {
return {
retrict: 'E',
templateUrl: '/partials/search-results.html'
};
});
})();
search-form.html
<input type="text" id="query" />
<button onclick="buttonClick">Search</button>
page-content.html
<section id="mainContent">
<search-form></search-form>
<search-results></search-results>
</section>
UPDATE
The second question will be posted in another thread.
About your first question:
You are using onclick attribute instead angular's 'ng-click' in the button search. This could be the problem. And do not forget to also add the 'ng-app' and 'ng-controller' tags. If not, your method will never be visible.
I also would recommend you to use $scope service instead of 'this' for attaching models and functions you later will use in your views.
Regards

Unable to locate FormController instance from parent scope

Problem
I'm trying to access an AngularJS FormController instance (created by setting a name property on a form directive) from it's parent controller scope. The output is undefined.
Confusion
But I can see the controller object as a property on the $scope when I log it to the console. I can also access the object from the template itself using the interpolation directive.
Example
The markup looks like:
<body ng-controller="FooCtrl">
<form name="FooForm" novalidate>
<input name="bar" required>
</form>
</body>
The JavaScript looks something like:
myAngularApp.controller('FooCtrl', function ($scope) {
console.log($scope.FooForm); // undefined
console.dir($scope); // has FooForm peek-a-booing in there
});
Demo
Here is the full plunk: http://plnkr.co/edit/EE7pdBF32B5XRbjZuy8R?p=preview
What am I doing wrong? I'm trying to follow these docs: https://docs.angularjs.org/api/ng/directive/form
The problem here is that your controller is initialized before your template, so at the time you are trying to use it, it's still undefined. Try this:
myApp.controller('MainCtrl', function ($scope) {
$scope.$watch('NewForm', function () {
var outputArea = document.getElementById('output-area');
outputArea.innerHTML = "The FormController instance is: " + $scope.NewForm;
});
});
Also note that using:
outputArea.innerHTML = "The FormController instance is: " + console.dir(newVal);
Doesn't make much sense, you're trying to concat the return value of console.dir to a string, which also always returns undefined ;) Changed it to:
outputArea.innerHTML = "The FormController instance is: " + $scope.NewForm;
Here's a working Plunker: http://plnkr.co/edit/yfVP8hD6saWV2tIok2ER?p=preview
Edit after comment:
If you want to be notified as soon as the form is available on your scope and you don't want to use $watch, you could do that by adding an custom directive to your form element which fires an event:
<form name="NewForm" novalidate formready>
The custom 'formready' directive:
.directive('formready', function(){
return {
restrict: 'A',
compile: function () {
return {
post: function(scope) {
scope.$emit('formready');
}
}
}
};
});
Now in your controller you can do:
$scope.$on('formready', function (event) {
console.log($scope.NewForm); // Available now
});
Here's a working example on Plunker: http://plnkr.co/edit/KG7LEB6EEkBkdONkL9LA?p=preview

Perform task after model's DOM is displayed in view

I have a code snippet in my content which is a model fetched from http. I am using syntax highlighter to prettify the code. So I need to call a javascript function as soon as the DOM is updated for that particular model.
Here is a sample code to make it clear. I am using alert to demonstrate it. In my project I would use a third party plugin which will find matching dom elements and remodel them.
Here,
I want the alert to occur after the list is displayed
jsfiddle :
http://jsfiddle.net/7xZde/2/
My controller has something like this.
$scope.items = Model.notes();
alert('test');
alert comes even before the items list is shown, I want it after the list is displayed.
Any hint to help me achieve this.
We need to use $timeout ,
$scope.items = Model.notes();
$timeout(function () {
alert('test');
})
Yeah it was silly , $timeout seemed to be a misnomer to me. I am 2 days old to angularjs . Sorry for wasting your time.
Lucky for you, I wanted to do the exact same thing. Mutation observers are the path forward, but if you need backwards compatibility with older browsers, you'll need a bit more code than this.
Working plunker for Firefox, Chrome, and Safari.
Javascript:
var app = angular.module('plunker', [])
.controller('MainCtrl', function($scope) {
$scope.name = 'World';
})
.directive('watchChanges', function ($parse, $timeout) {
return function (scope, element, attrs) {
var setter = $parse(attrs.watchChanges).assign;
// create an observer instance
var observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
$timeout(function () {
var text = angular.element('<div></div>').text(element.html()).text();
setter(scope, text);
});
});
});
// configuration of the observer:
var config = {
attributes: true,
childList: true,
characterData: true,
subtree: true
};
// pass in the target node, as well as the observer options
observer.observe(element[0], config);
};
});
HTML:
<body ng-controller="MainCtrl">
<div watch-changes="text">
<p>Hello {{ name }}</p>
<label>Name</label>
<input type="text" ng-model="name" />
</div>
<pre>{{text}}</pre>
</body>

How to validate dynamic form fields in angular directive?

I would like to create form with fields created in directive. Data binding of data working correctly but validation doesn't work.
this is html:
<body ng-controller="MainCtrl">
<h1>form</h1>
<form name="form">
<div ng-repeat="conf in config">
<div field data="data" conf="conf"></div>
</div>
</form>
<pre>{{data|json}}</pre>
</body>
controller and field directive:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.data = {name: '', age: ''}
$scope.config = [
{field: 'name', required:true},
{field: 'age'}
];
});
app.directive('field', function ($compile) {
return {
scope: {
data: '=',
conf: '='
},
link: function linkFn(scope, element, attrs) {
// field container
var row = angular.element('<div></div>');
// label
row.append(scope.conf.field + ': ');
// field input
var field = angular.element('<input type="text" />');
field.attr('name', scope.conf.field);
field.attr('ng-model', 'data.' + scope.conf.field);
if (scope.conf.required) {
field.attr('required', 'required');
}
row.append(field);
// validation
if (scope.conf.required) {
var required = angular.element('<span>required</span>');
required.attr('ng-show',
'form.' + scope.conf.field + '.$error.required');
row.append(required);
}
$compile(row)(scope);
element.append(row);
}
}
});
problem is that validation for field name doesn't work and validation text required is never shown. May be form in ng-show is unknown in directive. But I don't know how to pass form into field directive. Can you help me how to fix it? Thanks.
here is live code: http://plnkr.co/edit/j0xc7iV1Sqid2VK6rMDF?p=preview
Todo:
before:
$compile(row)(scope);
element.append(row);
after:
element.append(row);
$compile(row)(scope);
p/s in 'planker' for facilities add css:
.ng-invalid {
border: 1px solid red;
}
You'll need to use ng-form directive and push the dynamic field directly into form object.
This thread can help you out:
https://github.com/angular/angular.js/issues/1404
Here is a plunker forked from yours to fix you're issue:
http://plnkr.co/edit/qoMOPRoSnyIdMiZnbnDF?p=preview
To summarize, I added a watch that will toggle the error message instead of using the ng-show directive. Things can get hairy when you attempt to dynamically add a directive within a directive link. For a simple use case as this, it is quicker to add your own watch.
You may also look at this directive which is preconfigured to handle many use cases for validation as well as allow you to create custom validations easily https://github.com/nelsonomuto/angular-ui-form-validation
var toggleRequiredErrorMessage = function (invalid) {
if(invalid === true) {
addRequiredErrorMessage();
} else {
removeRequiredErrorMessage();
}
};
scope.$watch( watchIfRequired, toggleRequiredErrorMessage );

Resources