Cofigure Height of the Angular Material inputs - angularjs

I need to modify the height of the Angular-Material inputs to the minimun.
This is because i need to insert many inputs in a small box (500px and it is positioned on bottom of the screen), but I need that the height of the inputs do not change the height of the box, then i need that one of two things DO NOT HAPPEN:
1- The box grows-down wich is causing that the send button and other inputs are offscreen.
2- If the height of the box is configured with percentage (height:80%), then appears a scroll control in the right border of the box.
Here is the code:
<!doctype html>
<html lang="en">
<head>
<title>FORM</title>
<!-- Firebase -->
<script src="https://cdn.firebase.com/js/client/2.2.4/firebase.js"></script>
<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/1.2.0/angularfire.min.js"></script>
<!-- Angular Material style sheet -->
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.css">
</head>
<body ng-app="mmadera">
<div class="box" style="position:relative; width:500px; height:500px;">
<div ng-controller="DemoCtrl" layout="column" ng-cloak="" class="md-inline-form inputdemoBasicUsage" >
<md-content md-theme="docs-dark" layout-gt-sm="row" layout-padding="">
<div>
<md-input-container flex-gt-sm="">
<label>Título</label>
<input ng-model="user.titulo">
</md-input-container>
<md-input-container flex-gt-sm="">
<label>Email</label>
<input ng-model="user.email" type="email">
</md-input-container>
</div>
</md-content>
<md-content layout-padding="">
<div>
<form name="userForm">
<div layout-gt-xs="row">
<md-input-container flex-gt-xs=""> <!-- class="md-block" disabled="" -->
<label>Empresa</label>
<input ng-model="user.empresa" >
</md-input-container>
</div>
<div layout-gt-sm="row">
<md-input-container class="md-block" flex-gt-sm="">
<label>Nombre</label>
<input ng-model="user.nombre">
</md-input-container>
<md-input-container class="md-block" flex-gt-sm="">
<label>Teléfono</label>
<input ng-model="user.nombre">
<!-- ng-model="theMax" -->
</md-input-container>
</div>
<md-input-container class="md-block">
<label>Dirección</label>
<input ng-model="user.direcdion">
</md-input-container>
<div layout-gt-sm="row">
<md-input-container class="md-block" flex-gt-sm="">
<label>País</label>
<input ng-model="user.pais">
</md-input-container>
<md-input-container class="md-block" flex-gt-sm="">
<label>Estado</label>
<input ng-model="user.estado">
</md-input-container>
</div>
<md-input-container class="md-block">
<label>Mensaje</label>
<textarea ng-model="user.mensaje" md-maxlength="150" rows="5" md-select-on-focus=""></textarea>
</md-input-container>
<div>
<md-button type="submit" >ENVIAR</md-button>
</div>
</form>
</div>
</md-content>
</div>
</div>
<!-- ............................. ANGULAR - A.MATERIAL ......................................-->
<!-- Angular Material requires Angular.js Libraries -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-aria.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-messages.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-touch.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-animate.js"></script>
<!-- Angular Material Library -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js"></script>
<!-- Your application bootstrap -->
<script type="text/javascript">
angular.module('mmadera',['ngMaterial','ngMessages'])
.controller('SwitchDemoCtrl', function($scope) {
$scope.data = {
cb1: true,
cb4: true,
cb5: false
};
$scope.message = 'false';
$scope.onChange = function(cbState) {
$scope.message = cbState;
};
})
/* __________________________ PANEL js __________________________*/
/* __________________________ FOOTER __________________________*/
.controller('footsoc', function($scope) {
$scope.abre = false;
$scope.mov = {
isOpen: false,
count: 0,
selectedDirection: 'right'
};
})
/* __________________________ FOOTER __________________________*/
/* __________________________ SIDE BAR (Proceso) __________________________*/
.controller('AppCtrl', function ($scope, $timeout, $mdSidenav, $log) {
$scope.toggleLeft = buildDelayedToggler('left');
$scope.toggleRight = buildToggler('right');
$scope.isOpenRight = function(){
return $mdSidenav('right').isOpen();
};
/**
* Supplies a function that will continue to operate until the
* time is up.
*/
function debounce(func, wait, context) {
var timer;
return function debounced() {
var context = $scope,
args = Array.prototype.slice.call(arguments);
$timeout.cancel(timer);
timer = $timeout(function() {
timer = undefined;
func.apply(context, args);
}, wait || 10);
};
}
/**
* Build handler to open/close a SideNav; when animation finishes
* report completion in console
*/
function buildDelayedToggler(navID) {
return debounce(function() {
// Component lookup should always be available since we are not using `ng-if`
$mdSidenav(navID)
.toggle()
.then(function () {
$log.debug("toggle " + navID + " is done");
});
}, 200);
}
function buildToggler(navID) {
return function() {
// Component lookup should always be available since we are not using `ng-if`
$mdSidenav(navID)
.toggle()
.then(function () {
$log.debug("toggle " + navID + " is done");
});
}
}
})
.controller('LeftCtrl', function ($scope, $timeout, $mdSidenav, $log) {
$scope.close = function () {
// Component lookup should always be available since we are not using `ng-if`
$mdSidenav('left').close()
.then(function () {
$log.debug("close LEFT is done");
});
};
})
.controller('RightCtrl', function ($scope, $timeout, $mdSidenav, $log) {
$scope.close = function () {
// Component lookup should always be available since we are not using `ng-if`
$mdSidenav('right').close()
.then(function () {
$log.debug("close RIGHT is done");
});
};
})
.controller('DemoCtrl', function() {
this.isOpen = false;
this.availableModes = ['md-fling', 'md-scale'];
this.selectedMode = 'md-fling';
this.selectedDirection = 'right';
})
.controller('DropdownCtrl', function ($scope, $log) {
$scope.items = [
'The first choice!',
'And another choice for you.',
'but wait! A third!'
];
$scope.status = {
isopen: false
};
$scope.toggled = function(open) {
$log.log('Dropdown is now: ', open);
};
$scope.toggleDropdown = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.status.isopen = !$scope.status.isopen;
};
$scope.appendToEl = angular.element(document.querySelector('#dropdown-long-content'));
})
.controller('DemoCtrl', function($scope) {
$scope.user = {
titulo: 'Quiero vender mas!',
email: 'ejemplo#koomkin.com',
nombre: '',
telefono: '',
empresa: 'Koomkin',
direccion: '1600 Amphitheatre Pkwy',
pais: 'México',
estado: 'CDMX',
mensaje: 'Escribe tu mensaje',
postalCode: '94043'
};
})
.config(function($mdThemingProvider) {
// Configure a dark theme with primary foreground yellow
$mdThemingProvider.theme('docs-dark', 'default')
.primaryPalette('yellow')
.dark();
});
</script>
</body>
</html>
THANK YOU.

If the height of the box must not change, apply the max-heightstyle to it, with the overflow property too.
the max-height will fix your box height, while the overflow property set to hidden will hide elements that are out of it, and won't give you a scrollbar.
To change the inputs height, give them a class like this :
<input ng-model="user.titulo" class="myInput">
and give them a height of your own.
FYI, the class that applies the height of an input is md-container .md-input, so you can either overwrite it or add a new class like I told you before.
Depending on how you import your css sheets, you may need to use the !importantproperty on your class like so :
.myInput {
height: 20px !important;
max-height: 20px !important;
}

Related

AngularJS code is not running and getting no error message when inspected

When I inspect it, there are no error and it's returning nothing so, apparently not running :
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles/bootstrap.min.css">
<style>
.message {
font-size: 1.3em;
font-weight: bold;
}
</style>
<script src="angular.min.js"></script>
</head>
<body ng-app='LunchChecker'>
<div class="container" ng-controller='MyLunchCheckController'>
<h1>Lunch Checker</h1>
<div class="form-group">
<input id="lunch-menu" type="text" placeholder="list comma separated dishes
you usually have for lunch" class="form-control" ng-model='MenuInput'>
</div>
<div class="form-group">
<button class="btn btn-default" ng-click="checkInput()">
Check If Too Much</button>
</div>
<div class="form-group message" {{checkInput()}}>
<!-- Your message can go here. -->
</div>
</div>
<script src="app.js"></script>
</body>
</html>
Below is the app.js script for the above view the purpose of the code is to return either msg1 if the input is less than 3 menu or msg2 if the input is more than 3 :
(function() {
'use strict';
angular.module('LunchChecker', [])
.controller('MyLunchCheckController', MyLunchCheckController);
MyLunchCheckController.$inject = ['$scope'];
function MyLunchCheckController($scope) {
$scope.MenuInput = [].slice;
$scope.values = new Array($scope.MenuInput.length);
$scope.msg1 = "Enjoy!";
$scope.msg2 = "Too much!";
//fucntion for the button to check the user input menu-list
$scope.checkInput = function() {
for (var i = 0; i < $scope.values; i++) {
if ($scope.values <= 3) {
return $scope.msg1;
} else {
return $scope.msg2;
}
}
};
}
})();
When I try to reflect your code, I am getting function slice() { [native code] } inside the text box. As you have initialised the value of MenuInput as [].slice.
So to improve and compare the code
'use strict';
angular.module('LunchChecker', [])
.controller('MyLunchCheckController', ['$scope', function($scope) {
$scope.msg1 = "Enjoy!";
$scope.msg2 = "Too much!";
$scope.checkInput = function() {
if($scope.MenuInput.split(",").length <= 3) {
$scope.values = $scope.msg1;
} else{
$scope.values = $scope.msg2;
}
};
}]);
It will print the message in the console according to the length you compare. For displaying the message you can write like:
<div class="form-group message" {{checkInput()}}>
to
<div class="form-group message"> {{values}}</div>

Angular Formly - Custom type which generates the model from the controller

I've been all the day searching for a way to accomplish this, any help would be really appreciated.
We want to create a date selector, but not using the javascript Date format but a string 'YYYY-MM-DD'. So we tried to create a custom type which has two inputs, a type="date" so that the user can introduce the date he wants to and a hidden type="text" which stores the actual model.
It looked well at the beginning:
formlyConfig.setType({
'name': 'nativeDateSelect',
template: `
<input type="text" class="form-control" style="display: none;"
ng-model="model[options.key]" />
<input type="date" class="form-control"
ng-model="dateValue"
formly-skip-ng-model-attrs-manipulator />
`,
wrapper: ['bootstrapLabel', 'bootstrapHasError'],
controller: function ($scope, moment) {
$scope.dateValue = null;
$scope.$watch('model[options.key]', function (newValue) {
if (angular.equals($scope.dateValue, moment(newValue).toDate())) return;
$scope.dateValue = moment(newValue).toDate();
});
$scope.$watch('dateValue', function (newValue) {
if (angular.equals($scope.model[$scope.options.key], moment(newValue).format('YYYY-MM-DD'))) return;
$scope.model[$scope.options.key] = moment(newValue).format('YYYY-MM-DD');
});
},
'defaultOptions': {
'extras': {
'validateOnModelChange': true
}
}
});
This is it, it actually works, changing any of the input will modify the other one.
But here's the problem, once I introduce this type in an actual form and try to work with it, lets say for example adding an onChange function, it won't trigger as I'm not doing a change on the text input.
/* global angular */
(function() {
'use strict';
var app = angular.module('formlyExample', ['formly', 'formlyBootstrap', 'angularMoment'], function config(formlyConfigProvider) {
// set templates here
formlyConfigProvider.setType([
{
'name': 'nativeDateSelect',
template:
'<input type="text" class="form-control" style="display: block;" ' +
'ng-model="model[options.key]" /> ' +
'<input type="date" class="form-control" ' +
'ng-model="dateValue" ' +
'formly-skip-ng-model-attrs-manipulator />',
wrapper: ['bootstrapLabel', 'bootstrapHasError'],
controller: function ($scope, moment) {
$scope.dateValue = null;
$scope.$watch('model[options.key]', function (newValue) {
if (angular.equals($scope.dateValue, moment(newValue).toDate())) return;
$scope.dateValue = moment(newValue).toDate();
});
$scope.$watch('dateValue', function (newValue) {
if (angular.equals($scope.model[$scope.options.key], moment(newValue).format('YYYY-MM-DD'))) return;
$scope.model[$scope.options.key] = moment(newValue).format('YYYY-MM-DD');
});
},
'defaultOptions': {
'extras': {
'validateOnModelChange': true
}
}
}
]);
});
app.controller('MainCtrl', function MainCtrl(formlyVersion) {
var vm = this;
// funcation assignment
vm.onSubmit = onSubmit;
vm.exampleTitle = 'Default Options'; // add this
vm.model = {};
vm.fields = [
{
'type': 'nativeDateSelect',
'key': 'startDate',
'expressionProperties': {
'templateOptions.label': '\'startDate\''
},
'templateOptions': {
'required': true,
'onChange': function (modelValue, field, scope) {
alert('startDate: ' + modelValue);
}
}
}
];
vm.originalFields = angular.copy(vm.fields);
// function definition
function onSubmit() {
alert(JSON.stringify(vm.model), null, 2);
}
});
})();
<!DOCTYPE html>
<html>
<head>
<!-- Twitter bootstrap -->
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
<!-- apiCheck is used by formly to validate its api -->
<script src="//npmcdn.com/api-check#latest/dist/api-check.js"></script>
<!-- This is the latest version of angular (at the time this template was created) -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<!-- This is the current state of master for formly core. -->
<script src="//npmcdn.com/angular-formly#latest/dist/formly.js"></script>
<!-- This is the current state of master for the bootstrap templates -->
<script src="//npmcdn.com/angular-formly-templates-bootstrap#latest/dist/angular-formly-templates-bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-moment/0.10.3/angular-moment.min.js"></script>
<title>Angular Formly Example</title>
</head>
<body ng-app="formlyExample" ng-controller="MainCtrl as vm">
<div>
<h1>Changing our model from the controller</h1>
<hr />
<form ng-submit="vm.onSubmit()" novalidate>
<formly-form model="vm.model" fields="vm.fields" form="vm.form">
<button type="submit" class="btn btn-primary submit-button">Submit</button>
</formly-form>
</form>
<h2>Model</h2>
<pre>{{vm.model | json}}</pre>
<h2>Fields <small>(note, functions are not shown)</small></h2>
<pre>{{vm.originalFields | json}}</pre>
<h2>Form</h2>
<pre>{{vm.form | json}}</pre>
</div>
</body>
</html>
Do anyone know how to manage a scenario like this? I need one input to actually input and the other to be the model, so this one should track changes/validation/etc. whenever it is modified.
Thanks again!

ng-click not firing in md-bottom-sheet

My apologies in advance for a lengthy post. I wanted to include as much data as possible to see if you could assist me in my problem.
I originally developed the project using Bootstrap as a prototype and proof of concept. Now that I'm planning on going into production, I wanted to use angular-material.
Everything worked perfectly in Bootstrap. However, now that I'm using material design, ng-click is not working now that I'm using md-bottom-sheet. Here is the full code snippets;
HTML
index.html
<html ng-app="teamApp">
<head>
<link href="https://ajax.googleapis.com/ajax/libs/angular_material/0.9.4/angular-material.min.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
</head>
<body layout-fill layout-margin layout-padding layout="column" ng-controller="TeamController as teamCtrl">
<md-toolbar layout="row">
<div class="md-toolbar-tools">
<md-button class="md-icon-button" hide-gt-sm ng-click="toggleSidenav('left')">
<md-icon aria-label="Menu" md-svg-icon="https://s3-us-west-2.amazonaws.com/s.cdpn.io/68133/menu.svg"></md-icon>
</md-button>
<h2>Team Builder</h2>
</div>
</md-toolbar>
<div flex layout="row">
<md-sidenav class="md-sidenav-left md-whiteframe-z2" layout="column" md-component-id="left" md-is-locked-open="$mdMedia('gt-sm')">
<md-toolbar layout="row">
....
</md-toolbar>
<md-list>
....
</md-list>
</md-sidenav>
<div flex id="content" layout="column">
<md-content class="md-padding" flex layout="column">
<!-- Custom Directive to team-form.html -->
<team-forms></team-forms>
</md-content>
</div>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-aria.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angular_material/0.10.1/angular-material.min.js"></script>
<script src="js/team.js"></script>
</body>
</html>
You will see the team-forms directive. This is a custom directive that pulls in team-form.html. team-form.html has the button that when clicked pops up the md-bottom-sheet.
team-form.html
<div class="teamForms" layout="column">
<div id="team-list" class="row" flex>
<md-list>
<md-subheader class="md-no-sticky">Teams</md-subheader>
<md-list-item ng-repeat="team in teams">
........
</md-list-item>
</md-list>
</div>
<!-- button that when click, makes md-bottom-sheet pop up -->
<md-button class="md-fab" style="position:absolute; right:0; bottom:0" aria-label="Add Team" ng-click="teamCtrl.showAddTeam($event)">
<span style="font-size:3em; line-height:1.2em">+</span>
</md-button>
</div>
The HTML template used for the md-bottom-sheet is team-add.html. This is what pops up when the button above is clicked.
team-add.html
<!-- FORM TO CREATE team -->
<md-bottom-sheet>
{{formData}}
<md-toolbar layout="row">
<div class="md-toolbar-tools">
<h2>Add Team</h2>
</div>
</md-toolbar>
<form name="add-team">
<md-content layout-padding layout-sm="column" layout="row">
<md-input-container>
<label>Team Name</label>
<input name="teamName" ng-model="formData.name" required type="text">
</md-input-container>
</md-content>
<div layout="row" ng-show="formData.name.length >= 1">
<md-input-container>
<label>Employee Name</label>
<input class="form-control" name="teamEmployee" ng-model="employee.name" type="text">
</md-input-container>
<md-button class="md-raised md-primary" ng-click="addEmployee(formData)" type="submit">Add</md-button>
</div>
<md-content layout="row">
<md-input-container>
<md-button class="md-raised md-primary" ng-click="teamCtrl.createTeam()">Add Team</md-button>
</md-input-container>
</md-content>
</form>
</md-bottom-sheet>
JS
team.js
(function() {
'use strict';
var app = angular.module("teamApp", ["ngMaterial"]);
app.controller("TeamController", ["$scope", "$http", "$mdSidenav", "$mdBottomSheet", function($scope, $http, $mdSidenav, $mdBottomSheet) {
$scope.formData = {};
$scope.formData.employees = [];
// when landing on the page, get all teams and show them
$http.get("/api/teams")
.success(function(data) {
$scope.teams = data;
})
.error(function(data) {
console.log('Error: ' + data);
});
$scope.toggleSidenav = function(menuId) {
$mdSidenav(menuId).toggle();
};
this.showAddTeam = function($event) {
$mdBottomSheet.show({
templateUrl: 'directives/team/team-add.html',
targetEvent: $event
})
};
this.resetForms = function() {
$scope.teamForm = false;
$scope.employeeForm = false;
};
this.getTeam = function(id) {
$http.get("/api/teams/" + id)
.success(function(data) {
$scope.singleTeam = data;
console.log('Success: ' + data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
// when submitting the add form, send the text to the node API
this.createTeam = function() {
$http.post("/api/teams", $scope.formData)
.success(function(data) {
$scope.formData = {}; // clear the form so our user is ready to enter another
$scope.formData.employees = [];
$scope.teams = data;
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
this.updateTeam = function(id) {
$http.put("/api/teams/" + id, $scope.singleTeam[0])
.success(function(data) {
$scope.singleTeam = {};
$scope.teams = data;
console.log('Success: ' + data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
// delete a todo after checking it
this.deleteTeam = function(id) {
$http.delete("/api/teams/" + id)
.success(function(data) {
$scope.teams = data;
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
this.getRotation = function() {
$http.post("/api/rotations")
.success(function(data) {
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
};
}]);
app.directive("teamForms", function() {
return {
restrict: "E",
templateUrl: "directives/team/team-forms.html",
controller: ["$scope", function($scope) {
$scope.employee = {};
$scope.teamForm = false;
$scope.employeeForm = false;
this.showTeamForm = function(value) {
return $scope.teamForm == value;
};
this.setTeamForm = function(value) {
$scope.teamForm = value;
};
this.showEmployeeForm = function(value) {
return $scope.employeeForm == value;
};
this.setEmployeeForm = function(value) {
$scope.employeeForm = value;
};
$scope.addEmployee = function(dataSet) {
dataSet.employees.push($scope.employee);
$scope.employee = {};
};
$scope.removeEmployee = function(dataSet, index) {
dataSet.employees.splice(index, 1);
};
}],
controllerAs: "teamFormCtrl"
};
});
app.directive("teamEditForm", function() {
return {
restrict: "E",
templateUrl: "directives/team/team-edit.html"
};
});
}());
The issue is in the team-add.html. It's the md-button that is trying to call createTeam().
The expected result is that it would post the name of the team to my API endpoint and into my mongoDB setup. This was working perfectly before in bootstrap but I feel that now I'm deeper in the UI with how md-bottom-sheet needs to be setup, that I have some scoping or controller issue in place.
I have even tried adding a fake, non-existent function to ng-click to see if some error was thrown when clicked but no error showed up. Node is not even reporting a post command being sent. It just seems that the button is doing absolutely nothing
Any help would be greatly appreciated and if more code is needed, please let me know and I'll post it up!
Thanks!
In your md-button your ng-click is something like this
<md-button class="md-fab"
ng-click="teamCtrl.showAddTeam($event)">
Your question reads "ng-click not firing", to make ng-click work give this a try
ng-click="showAddTeam($event)">
This will work since you are trying to call a function which is in some controller and your directive's html is within at controller's scope only.

How to show message for a certain time in angularjs

I'm displaying a message when the user clicks on the button.
I want to show this message for 10 seconds and then hide it.
My code is the following:
<script>
function Ctrl($scope, $window) {
$scope.greeting = 'Hello, World!';
$scope.doGreeting = function() {
$scope.msg="hi";
};
}
</script>
<div ng-controller="Ctrl">
<input type="text" ng-model="greeting" />
<button ng-click="doGreeting()">click</button>
{{msg}}
</div>
You can set a variable that determines whether to show the message or not and hide it and after 10,000 seconds. You will have to inject $timeout as shown below. Then in your view you will need to wrap {{msg}} in a span in order to use ng-show
<script>
function Ctrl($scope, $window, $timeout) {
$scope.greeting = 'Hello, World!';
$scope.showGreeting = false;
$scope.doGreeting = function() {
$scope.msg="hi";
$scope.showGreeting = true;
$timeout(function(){
$scope.showGreeting = false;
}, 10000);
};
}
</script>
<div ng-controller="Ctrl">
<input type="text" ng-model="greeting" />
<button ng-click="doGreeting()">click</button>
<span ng-show="showGreeting ">{{msg}}</span>
</div>
The way I did to show a message for a certain time in angularjs was using AngularJS-Toaster library
To use the library follow this steps:
<link href="https://cdnjs.cloudflare.com/ajax/libs/angularjs-toaster/0.4.9/toaster.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js" ></script>
<script src="https://code.angularjs.org/1.2.0/angular-animate.min.js" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angularjs-toaster/0.4.9/toaster.min.js"></script>
Add toaster container directive:
<toaster-container></toaster-container>
Prepare the call of toaster method:
// Display an info toast with no title
angular.module('main', ['toaster'])
.controller('myController', function($scope, toaster) {
$scope.pop = function(){
toaster.pop('success', "title", "text");
};
});
Call controller method on button click:
<div ng-controller="myController">
<button ng-click="pop()">Show a Toaster</button>
</div>
Here you can see a Plunker showing many kinds of toasts showing differents messages
Add the $timeout dependency to your controller. Here's a fiddle:
<div ng-app>
<div ng-controller="Ctrl">
<input type="text" ng-model="greeting" />
<button ng-click="doGreeting()">click</button>
<div class="ng-hide" ng-show="showMessage">{{msg}} {{ greeting }}</div>
</div>
</div>
function Ctrl($scope, $window, $timeout) {
var messageTimer = false,
displayDuration = 5000; // milliseconds (5000 ==> 5 seconds)
$scope.showMessage = false;
$scope.msg = "hi";
$scope.doGreeting = function () {
if (messageTimer) {
$timeout.cancel(messageTimer);
}
$scope.showMessage = true;
messageTimer = $timeout(function () {
$scope.showMessage = false;
}, displayDuration);
};
}

AngularJS check if form is valid in controller

I need to check if a form is valid in a controller.
View:
<form novalidate=""
name="createBusinessForm"
ng-submit="setBusinessInformation()"
class="css-form">
<!-- fields -->
</form>
In my controller:
.controller(
'BusinessCtrl',
function ($scope, $http, $location, Business, BusinessService,
UserService, Photo)
{
if ($scope.createBusinessForm.$valid) {
$scope.informationStatus = true;
}
...
I'm getting this error:
TypeError: Cannot read property '$valid' of undefined
Try this
in view:
<form name="formName" ng-submit="submitForm(formName)">
<!-- fields -->
</form>
in controller:
$scope.submitForm = function(form){
if(form.$valid) {
// Code here if valid
}
};
or
in view:
<form name="formName" ng-submit="submitForm(formName.$valid)">
<!-- fields -->
</form>
in controller:
$scope.submitForm = function(formValid){
if(formValid) {
// Code here if valid
}
};
I have updated the controller to:
.controller('BusinessCtrl',
function ($scope, $http, $location, Business, BusinessService, UserService, Photo) {
$scope.$watch('createBusinessForm.$valid', function(newVal) {
//$scope.valid = newVal;
$scope.informationStatus = true;
});
...
Here is another solution
Set a hidden scope variable in your html then you can use it from your controller:
<span style="display:none" >{{ formValid = myForm.$valid}}</span>
Here is the full working example:
angular.module('App', [])
.controller('myController', function($scope) {
$scope.userType = 'guest';
$scope.formValid = false;
console.info('Ctrl init, no form.');
$scope.$watch('myForm', function() {
console.info('myForm watch');
console.log($scope.formValid);
});
$scope.isFormValid = function() {
//test the new scope variable
console.log('form valid?: ', $scope.formValid);
};
});
<!doctype html>
<html ng-app="App">
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
</head>
<body>
<form name="myForm" ng-controller="myController">
userType: <input name="input" ng-model="userType" required>
<span class="error" ng-show="myForm.input.$error.required">Required!</span><br>
<tt>userType = {{userType}}</tt><br>
<tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br>
<tt>myForm.input.$error = {{myForm.input.$error}}</tt><br>
<tt>myForm.$valid = {{myForm.$valid}}</tt><br>
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
/*-- Hidden Variable formValid to use in your controller --*/
<span style="display:none" >{{ formValid = myForm.$valid}}</span>
<br/>
<button ng-click="isFormValid()">Check Valid</button>
</form>
</body>
</html>
The BusinessCtrl is initialised before the createBusinessForm's FormController.
Even if you have the ngController on the form won't work the way you wanted.
You can't help this (you can create your ngControllerDirective, and try to trick the priority.) this is how angularjs works.
See this plnkr for example:
http://plnkr.co/edit/WYyu3raWQHkJ7XQzpDtY?p=preview
I like to disable the save/submit button if the form is invalid:
<form name="ruleForm">
<md-input-container>
<label>Priority</span>
<input name="description" ng-model="vm.record.description" required>
</md-input-container>
<md-button ng-click="vm.save()" ng-disabled="ruleForm.$invalid" class="md-primary md-raised">Save</md-button>
</form>

Resources