AngularJS ng-include on ng-click - javascript

I would like to find a way to insert HTML (which is optimalized for the controller) into alert div. However I couldn't find a way to do it...
<script type="text/ng-include" id="login.html">
<form data-select="exeption" class="loginBox shadowed" onclick="event.stopPropagation();" novalidate name="login">
<h2>Login alert</h2>
<!--inputs and such, they need to be controlled by the controller-->
</form>
</script>
<script type="text/ng-include" id="bug.html">
<form data-select="exeption" class="bugBox shadowed" onclick="event.stopPropagation();" novalidate name="report">
<h2>Bug report</h2>
<!--inputs and such, they need to be controlled by the controller-->
</form>
</script>
This two templates should be evoked by the JS itself or by user. Those templates should get into this div, but I can't use innerHTML since in templates are some ng-models and such things...
<div id="alert" data-ng-click="empty()" data-ng-controller="alert" role="navigation"></div>

Usually what I do is use ng-if / ng-show .
I'm not sure I understood your request correctly, so I'll write a little example; let's say you have a simple login form:
<form>
<label>
username:
<input name="username" type="text" ng-model="username"/>
</label>
<label>
password:
<input name="password" type="password" ng-model="password"/>
</label>
<button type="submit" ng-click="login()">login</button>
<div class="message" ng-if="message">
</div>
</form>
Inside the controller:
$scope.username = '';
$scope.password = '';
$scope.message = '';
$scope.login = function() {
// login example function with ajax request and success/error promises
myLogin($scope.username, $scope.password)
.success(function() {
$scope.message = 'Logged in!';
})
.error(function(errorMessage) {
$scope.message = errorMessage;
})
}
This way your div is empty when $scope.message is empty and you can show it automatically just giving $scope.message a value.
If you need to have an ng-include, simplest thing you could do is to use it inside a div that you show when you need it:
<div ng-if="showMessage">
<div ng-include="template.html"/>
</div>
UPDATE: following my last example, if you wanted to include a different type of message for every situation, you could use multiple ngIf, including different template; example:
<div ng-if="showMessage">
<div ng-if="message.type == 'alert'" ng-include="'alert.html'"/>
<div ng-if="message.type == 'info'" ng-include="'info.html'"/>
<div ng-if="message.type == 'warning'" ng-include="'warning.html'"/>
<div ng-if="message.type == 'error'" ng-include="'error.html'"/>
</div>
This way you can also do an ngInclude for a login form, or another kind of popup.
UPDATE 2: same last example, but with another solution:
<div ng-if="showMessage">
<div ng-include="templatePath"/>
</div>
then you can give in the controller the whole path to the partial:
$scope.templatePath = 'alert.html';

Related

How to clear a form within an angular app that appears on click?

I have seen several tutorials on how to clear angular (version 1.4.0) forms, however.. none of them seem to work in my case. I am puzzled. The following form is display: none; to begin with, but comes into existence when the 'Add' button is clicked.
<div id="..." class="displayNone ...">
<form class="..." name="addFooForm">
<div class="...">
<div class="row">
<div class="col-md-offset-3 col-md-6">
<br>
<div class="form-group">
<label>Foos</label>
<input type="text" class="..." id="..." ng-model="foo.value">
</div>
</div>
</div>
</div>
<div class="...">
...
<input type="button" value="Cancel" class="..." ng-click="resetAddFooForm()">
</div>
</form>
</div>
And in my controller, I have the following.
$scope.resetAddFooForm = function () {
// XXX:
console.log('about to reset the form');
$scope.foo = {};
// $scope.addFooForm.$setValidity();
// $scope.addFooForm.$setPristine();
// $scope.addFooForm.$setUntouched();
};
But, although the console.log message is being displayed. The form field is not being cleared. I have have even tried doing it directly as follows.
$scope.resetAddFooForm = function () {
// XXX:
console.log('about to reset the form');
$scope.fooVal = '';
// $scope.addFooForm.$setValidity();
// $scope.addFooForm.$setPristine();
// $scope.addFooForm.$setUntouched();
};
.. with the above html modified as follows.
<div class="form-group">
<label>Foos</label>
<input type="text" class="..." id="foo" ng-model="fooVal">
</div>
But nothing seems to be working. Is it perhaps because the $scope is different due to the form being dynamically inserted? But then how do I tackle that?
I just want to be able to clear the fields (and also clear the angular properties like dirty/pristine, etc) of this dynamically generated form.
Update:
I was able to send this from the html back to the controller, and then use it do what I wanted. So it appears that the problem may actually be to do with differing scopes.
<div class="...">
...
<input type="button" value="Cancel" class="..." ng-click="resetAddFooForm(this)">
</div>
And then have this retrieved the controller.
$scope.resetAddFooForm = function (elem) {
elem.foo = {};
elem.$setValidity();
elem.$setPristine();
elem.$setUntouched();
};
Any hints? Why do I need to send this, when I should really be able to simply use $scope. Why doesn't that work?
Initially declare empty object on your controller
$scope.foo = {}
then try empty it on reset
You can manually reset fields value.

Get Array from Page 1 and use it on Page 2 using on-Click (AngularJS)

hope you guys are kicking and jumping. Thanks for your usual understanding.
Frameworks: AngularJS, NodeJS
I am designing a login page. But the data to be compared with is an array of items in testData.html. I want to call the data on the login.html and compare it with user's input.
The login form works properly but the data is not read. I tried compiling the dataobject.html file separately, and it did not run.
I do not want to store this data in a .json file.
Later I will learn how to use the MongoDB to read data and compare
Please check the codes below.
[LOGIN.HTML]
<div ng-app="myApp" ng-controller="loginCtrls" style="height:auto;">
<form name="lForm">
<div class="container">
<label><b>Username</b></label>
<input class="w3-round" type="text" name="username" placeholder="Username" ng-model="username" required>
<div align="right" style="width:550px;">
<span style="color:red" ng-show="lForm.username.$dirty && lForm.username.$invalid">
<span ng-show = "lForm.username.$error.required">Username is required.</span>
</span>
</div>
<label><b>Password</b></label>
<input class="w3-round" type="password" name="password" ng-model="password" placeholder="Password" required>
<div align="right" style="width:550px;">
<span style="color:red" ng-show="lForm.password.$dirty && lForm.password.$invalid">
<span ng-show = "lForm.password.$error.required">Password is required.</span>
</span>
</div>
<div align="center">
<button class="w3-btn w3-teal w3-round" style="height:45px; width:100%; font-size:16px;" ng-disabled = "lForm.username.$dirty && lForm.username.$invalid || lForm.password.$dirty && lForm.password.$invalid" ng-click="chkData()">Click to Login</button>
</div>
<input type="checkbox" checked="checked"> Remember me
</div>
<div class="container" style="background-color:#f1f1f1; margin-top:0;">
<span>Forgot password?</span>
</div>
</form>
<h4>{{result}} login attempt</h4>
</div>
<script src="js/loginCtrl.js"></script>
[LOGINCTRL.JS]
// JavaScript Document
var app = angular.module('myApp', []);
app.controller('loginCtrls', function($scope, $http) {
//get the file from the dataobject.html file
$http.get("dataobject.html").then(function (response) {
//parse the array object to $scope.users
$scope.users = response.data.records;
});
//this function checks the user's input and
//compares it with the any match in object array
//the object array data has been passed into $scope.users
$scope.chkData = function(){
$scope.users = $scope.data.records;
angular.forEach($scope.users, function(value, key){
if(angular.equals(value.Username, $scope.username) && (value.Password, $scope.password)){
$scope.result = "Successful ";//msg to be displayed
}else {
$scope.result = "Unsuccessful ";//msg to be displayed
}
});
}
});
[DATA OBJECT.HTML]
<script src = "js/angular.min.js" type="text/javascript"></script>
<div ng-app="myApp" ng-controller="mdata">
</div>
<script>
var app = angular.module('myApp', []);
app.controller('mdata', function($scope) {
$scope.data =
{ "records":[ {"Username":"Alfreds","Password":"alfred","Session ID":"1"}, {"Username":"Ana","Password":"ana","Session ID":"2"}, {"Username":"Moreno","Password":"moreno","Session ID":"3"}] };
});
});
</script>
I would recommend to do it using a service. Angular services are singletons. So, from one controller, you put the data in a service, switch pages, get the data from the service.
NOTE: if user refreshes the page, the data in the service will be lost, as services (or angular for that matter) does not persist state.
ofc, everyone will have their own solution. I see you are a beginner, so the answer is meant to help you get a grasp of angular.
You can store your data either on the $rootScope or by creating localStorage Services and u can access data anywhere in application but the best practices are creating some localStorage services.

AngularJS: Target a form with Controller As syntax in an object

Note: I did look around here on SO for solutions, yet no one had the additional issue of the function being in an object.
I have a form in my Angular JS app:
<div ng-app="plunker">
<div ng-controller="PMTController as pmt">
<form name="myForm">
<div class="form-group">
<input type="text" class="form-control" />
</div>
<button class="btn btn-primary" ng-click="pmt.search.resetSearchForm()">Reset</button>
</form>
</div>
</div>
Further, I have a controller with an object:
app.controller('PMTController', function($log) {
var _this = this;
_this.search = {
resetSearchForm: function () {
$log.debug('test');
// how to target the form?
}
};
})
My ng-click works, as the log.debug works. But no amount of tweaking to target the form so that I can reset the entire thing (empty all the fields) works.
I can do $window.myForm.reset(); but how could I do this from angular?
Note please my main issue/question is how to correctly target the form from inside that resetSearchForm function in the search object.
Note I tried changing the form name to pmt.myForm or pmt.search.myForm to no avail.
I tried $setPristine and $setUntouched() but they don't seem to clear the fields.
I know I can assign a model and assign it to all the form controls, but this is for a prototype so I'd rather do a simple reset.
I made a pen: https://codepen.io/smlombardi/pen/YWOPPq?editors=1011#0
Here is my take on your codepen that will hopefully resolve the issue:
https://codepen.io/watsoncn/pen/YWOXqZ?editors=1011
Explanation:
Angular's documentation provides an example of a "Form Reset" button, but you can apply the same logic towards resetting after submission:
Documentation:https://docs.angularjs.org/guide/forms
with a plunker:
Live Example:https://plnkr.co/edit/?p=preview
The example shows the use of Angular's copy method that creates a deep copy of whatever you pass it as a parameter and assigns it to the ng-model that is put on a particular input field. In this case they simply pass it an empty master object.
You need to make sure to add an ng-model attribute to your inputs, then create a reset function that can run after submission. Another common option would be to simply set each input's ng-model to empty strings in the submission function, such as $scope.inputModel = ""
Is this what you were hoping for? I might have misunderstood the question. I will happily take another crack at it if there is still confusion.
To get the form in your controller you just need to name your form this way:
<form name="pmt.myForm">
Here's a complete demo:
(function() {
"use strict";
angular
.module('plunker', [])
.controller('PMTController', PMTController);
PMTController.$inject = ['$log'];
function PMTController($log) {
var _this = this;
_this.model = {};
_this.search = {
resetSearchForm: function() {
console.log(_this.myForm); // -> Form reference
_this.model = {};
}
};
}
})();
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body ng-controller="PMTController as pmt">
<div class="col-md-12">
<form name="pmt.myForm">
<div class="form-group">
<input type="text" ng-model="pmt.model.example" class="form-control" />
<input type="text" ng-model="pmt.model.example2" class="form-control" />
<input type="text" ng-model="pmt.model.example3" class="form-control" />
</div>
<button class="btn btn-primary" ng-click="pmt.search.resetSearchForm()">Reset</button>
</form>
<hr> All fields:
<pre ng-bind="pmt.model | json"></pre>
</div>
</body>
</html>

ng-show with form condition not working on a directive template in AngularJS

In the directive I was wondering why the CSS is not reacting accordingly to the attributes. My ng-show is a simple boolean condition that depends if the required error of a certain input is true or not. In short what I want is while the required validation is true the take exam must be hidden until the user inputs something on the textbox
Here is the code:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://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">
Required condition -- {{ loginForm.student_code.$error.required }}
<!-- dasdas -- {{loginForm.student_code.$error.codeValidity }} -->
<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="loginForm.student_code.$error.codeValidity">{{ errors }}</span>-->
</div>
</form>
<login-button form="loginForm"></login-button>
<button class="btn btn-primary">Register</button>
<!-- <br /> <strong>A message must be seen after the colon if codeValidity is true: </strong> -->
</div>
</div>
</body>
<script>
var app = angular.module("myApp", []);
app.directive('loginButton', loginButton);
loginButton.$inject = ["$http", "$window"];
function loginButton($http, $window){
return {
scope: {
form: '='
},
template: '<button type="button" class="btn btn-primary" ng-show="{{ !form.student_code.$error.required }}" ng-click="click()">Take Exam</button>',
controller: function($scope){
$scope.click = function(){
form = $scope.form;
form.student_code.$setValidity('codeValidity', false);
$scope.errors = "Code is Invalid";
};
}
}
}
</script>
</html>
Here is the plunker: https://plnkr.co/edit/plpKSGBtWqQnzhL60OfJ?p=preview
You are incorrectly trying to interpolate the variable inside the ng-show, but ng-show takes an expression. Interpolated values aren't evaluated in time for their value to be reflected by the ng-show directive. Instead, you should allow ng-show to evaluate the expression and interpolate it if necessary.
i.e. instead of: ng-show="{{ !form.student_code.$error.required }}",
do: ng-show="!form.student_code.$error.required".
Updated Plunker
It works now...Check the updated plunkr.
ng-show=" !form.student_code.$error.required "
You were making mistake in binding.

Incorporate directive's functionality into Angular form validation

I have two questions that are related:
First: I have the following directive, who's purpose is to validate whether an input[type=file] is valid or not, however I have no idea how it does it least of all, what the actual code means, here it is:
angular.module('sccateringApp')
.directive('fileModel', ['$parse', function($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
Like I said, I have no idea what the above code actually does, the explanation I got from the forum where I copied that was that it validated an input type file. Is this correct? (So far I haven't been able to verify if it works or not since it doesn't work with the code I'm using at the moment to validate my forms).
Second: Having the form below, using angular form validation it doesn't allow the submit button to be clicked until the actual inputs inside the form match the validation rules (enter a name for the category, and the description should have a max length of 144 characters). I included the directive into the file input, however the actual ng-model for the form ignores the required in the input type file and just verifies the rules are met for the first two inputs.
Here is my form:
<form method="post" role="form" name="newCategoryForm" ng-submit="submitForm()" enctype="multipart/form-data" novalidate>
<div class="row">
<div class="row">
<div class="col s12">
<div input-field>
<input type="text" name="cat-name" id="cat-name" ng-class="{ 'ng-invalid' : newCategoryForm.catname.$invalid && !newCategoryForm.catname.$pristine }"
ng-model="catname" required>
<label>Nombre</label>
</div>
</div>
</div>
<div class="row">
<div class="col s12">
<div input-field>
<textarea class="materialize-textarea" name="cat-description" id="cat-description" length="144"
ng-model="catdescription" ng-maxlength="144" required></textarea>
<label>Descripción</label>
</div>
</div>
</div>
<div class="row">
<div class="col s12">
<h6>Imagen de Fondo</h6>
<div class="file-field input-field">
<div class="btn pink darken-2 waves-effect waves-light">
<span>Archivo</span>
<input type="file" name="cat-bgimg" id="cat-bgimg"
file-model="variable" required>
</div>
<div class="file-path-wrapper">
<input class="file-path" type="text">
</div>
</div>
</div>
</div>
</div>
<button type="submit" class="btn btn-large pink darken-2 waves-effect waves-light center-button" ng-disabled="newCategoryForm.$invalid">Crear Categoría</button>
</form>
The first two inputs get validated correctly, the third one (file input) doesn't and I don't really know why since the directive got included on the input (I know natively, ngModel doesn't validate file inputs).
Any ideas or suggestions of how can I fix this? I'm really new to Angular, and all the tutorials are pretty much useless. I come from 5 years of experience working on jQuery, and the transition to Angular hasn't been easy at all.
The directive posted above is used to make the submit get the data found in the <input type="file"></input>.
Also, a variable should be initialized in the controller so that the values found inside the form are copied to said variable, then this variable needs to be sent as a parameter inside the ng-submit="submitForm().
Example:
angular.module('sccateringApp')
.controller('newSubcategoryController', function (httpcalls, $scope) {
...
$scope.subcategory = [];
...
$scope.submitForm = function(subcategory){
...
$scope.request.insertSubcategory(subcategory);
}
});
Each ng-model inside the form would be:
<input type="text" ng-model="category.name">
So that the category variable found in the controller acquires that value.

Categories