ngForm not work in web application, but does in jsFiddle - angularjs

I am trying to use the $invalid properties of ngForm to disable a submit button in my app. For some reason, the FormController instance that I should have access to after the <form> is created is not available. However, I moved the code over to jsFiddle and for some reason it works now.
Here is the jsFiddle
In my real application, there are no errors in the console and I am including angular.min.js correctly because everything else works fine. I am lost on what to try next since the code is basically the same in both.

Without seeing what is in your controller this is just a guess, but when I have problems with things not working for obscure reasons I generally am able to solve the problem by creating an object in scope and hanging everything off of it (much like you have already done.)
function Controller($scope) {
$scope.form = {
email:'',
employees:'',
migDate:''
};
}
The trick here is that you need to name your form similarly:
<form name="form.newMigForm" novalidate ng-controller="myControllerName">
and then when you check $invalid in your button, you use the same convention:
<input id="qaStartForm" ng-disabled="form.newMigForm.$invalid" ng-click="submitNewMigration()" type="button" class="btnOrangeLarge" value="Start" />
This problem generally arises when you use the UI Modal and they tell you to access it like this in the docs. I have used it successfully in other areas and solved the mystery that was plaguing me.

Related

Angular-Material "md-datepicker" directive - "md-open-on-focus" issue

As exampled in this fiddle, there's seems to be an inconsistency issue with opening the md-datepicker multiple times when using md-open-on-focus.
The problem occurs after opening and closing it for the first time (which works ok) - after that, it'll randomly open on click and become unstable.
<md-datepicker ng-model="timeModel" md-hide-icons="all" md-open-on-focus></md-datepicker>
Has anyone experienced the same behavior and found a solution? Thanks.
Currently, the problem with md-hide-icons="all" and md-open-on-focus used together is, when you click outside, the focus remains on the input. But, since there are no icons to click for and focus is already on the input, there is no way we can open the datepicker.
If you click outside, and click outside again, focus from the input is gone, and it will work normally from there on which should arguably be the expected behavior.
But if you don't want such behavior, we can do something to change it!
Now, having a look at the datePicker code, in the closeCalendarPane function, they have
self.calendarPaneOpenedFrom.focus();
which is responsible for keeping focus on input. If we remove it, it would lose focus while clicking outside (or selecting a date from the picker) which is exactly what we want. They have some code handling input when openOnFocus is true but not sure how that helps!
Forked jsfiddle (changed line is at #31449)
Also, changing the library code isn't what we would normally want to do. So, for now, you could have a workaround like having a callback on md-is-open and removing the focus from the input element inside callback using your favourite way (jQuery/angular.element or pure JS) [As mentioned by #quirimmo]
Hope that helps!
Unfortunately this functionality it's not implemented yet in angular material.
If you take a look to the official examples, you will see the same behavior in the one using md-open-on-focus.
https://material.angularjs.org/1.1.0/demo/datepicker
You need a little workaround in order to make it works. Just changed your example code:
HTML:
<md-datepicker ng-model="timeModel" md-hide-icons="all" md-is-open="isOpen" md-open-on-focus></md-datepicker>
JS:
angular.module('sandbox', ['ngMaterial'])
.controller('Ctrl', function($scope, $timeout) {
$scope.timeModel = new Date();
$scope.$watch('isOpen', function(newValue, oldValue) {
if (!newValue && oldValue) {
document.querySelector('.md-datepicker-input').blur();
}
});
});
https://jsfiddle.net/ecs9ao89/
You can achieve also the same behavior defining a new directive and requiring the base datepicker of angular material, and open it on click.
But this solution is smaller effort.

ng-change not working after first upload

http://embed.plnkr.co/keaGc3Y4Pmgfs04HJgnC/
Here is the link of my code.I am trying to validate my upload by disabling the load data button when the file is empty.
It is working for the first time,but when the next time I upload the file,ng-change is not working and the button is still showing disabled although I have uploaded the next file.
I am a beginner in AngularJS,so i might be doing some basic mistake.please help.
Since you are trying to upload the same file again, the onChange event will not fire, because it is the same file. To resolve this issue, you need to unset the input field after you uploaded the file. Unfortunately, you have to use jQuery (or get the element wit vanilla js) for this. So, in your onFileLoad function you could do something like this:
angular.element("input[type='file']").val(null); // Unset Input
$scope.filename = undefined; // Unset $scope property
Note that this is not the "angular" way of doing this. It would be better to move this into a directive, cause you should not manipulate the DOM within a Controller.
Update:
As said before, you need to include jQuery for this to work. Angular's jqLite does not support selecting DOM elements by its type. So, either you include jQuery (needs to be loaded before angular!) or you modify the code so you can use vanilla JS or jqlite.
Please change, initially
vm.foo = 'Monthly'
<input type="radio" name="{{item.deviceId}}" ng-model="renew.foo" ng-value="'Monthly'" ng-click="renew.updatePref(item, 'Monthly')">Monthly
<input type="radio" name="{{item.deviceId}}" ng-model="renew.bar" ng-value="'Yearly'" ng-click="renew.updatePref(item, 'Yearly')">Yearly
you have use ng-change, change event never happen as value for these input remains always same. use,
var vm = this;
you are also using ng-value="Monthly", Monthly is variable (undefiend) for ng-value. either use value="Monthly" or ng-value="'Monthly'".

Access an angular page from a form

I would like to access an angular page from an html form. But when I submit the form via method get and with parameter I get some problem with the url.
Here is a simple form to reproduce the problem :
<form action="http://ncel28182/pl/Angular/#/FFCO">
<input type="text" name="test">
<button>toto</button>
</form>
When I click on the submit button, it open a page where the url is
http://ncel28182/pl/Angular/?test=#/FFCO
It seems that the parameters are placed before the #.
Is there a way to fix it ?
I believe you should use $location to change location, and a service to share data, as in the following :
HTML :
<form name="myForm" ng-submit="submit()">
<input type="text" name="test">
<button>toto</button>
</form>
Javascript :
function submit($scope, $location, MyService) {
MyService.data = $scope.myForm.test;
$location.url("/pl/Angular/#/FFCO");
}
In the other's page controller, define the service as a dependency and you will be able to access the up-to-date data.
Please note that I'm not a professional angularjs user or even a webdevelopper, you should probably wait for other users to react to my answer or add their own.
Since you can't edit the form sending data, you can't use ngRoute to directly route to the desired "FFCO" view because ngRoute matches against $location.path, whereas the form sends the "FFCO" part as the $location.hash. Since you have no $location.path provided, the form will target your application root.
What you will want to do is add some js code in this page to handle the location change :
if ($location.hash() === "/FFCO") { $location.path("/FFCO"); }
This should do the trick, translating the url requested by the form to a format understandable by your angularjs application. I don't think this will change the hash, if an extra #/FFCO by the end of your URL is a problem you should remove it with $location.hash('').
I believe the best place to do so would be in an extra controller added somewhere after your app bootstrap code.
This is obviously still sub-optimal, I wish I had a better solution.

Trying to create a keyboard shortcut for a button using Angular

I want to be able to set a keyboard shortcuts for buttons in an application I'm building. I'd like to be able to pass in the keyboard button code as a parameter to make it configurable. Here's what I have so far using the documentation before I got stuck. HTML:
<div ng-controller="BtnCtrl">
<button class="primary-btn" type="submit" ng-keypress="press($event, '12')">Button</button>
</div>
JavaScript:
angular.module('App')
.controller('BtnCtrl', function ($scope) {
$scope.press = function($event, hotKeyRef) {
if ($event.keyCode==hotKeyRef) {
//need some code here to trigger the button press
}
}
});
So using my approach, I'm unsure of a) how to trigger the button press from inside the function and b) whether this is the correct way of passing in the keyCode data.
I might also be taking completely the wrong approach, so any other guidance would be appreciated.
Thanks
For the question a).
The main uses of a < button > html element is to fire an event on a click.
So if you want to use a keypress, why use this element ? I don't really see what you want to achieve. that seems controversal.
for b) :
By default, ng-keypress is intended to be used in an input element.
Otherwise, it seems that some posts, where I inquired, manage to make it work out.
You can see what it can look like, for example on this post (Is it possible to listen for arrow keyspress using ng-keypress?)
in which the person trying to setup the konami code.
Moreover, it seems that you can have trouble depending on which browser (Chrome, Firefox, Safari, IE) you uses. Be careful.
I hope this could help you.
hi there is an excellent plugin for your scenario u can check the below link
https://github.com/chieffancypants/angular-hotkeys/
u can also check the below stackoverflow link
What is AngularJS way to create global keyboard shortcuts?

Form validation with AngularJS and dynamic fields

I'm stuck with strange problem regarding AngularJS form validation. If a dynamically added control (a textbox, for instance) requires validation and is removed from the form, the form will remain invalid if the removed control was invalid.
That last sentence is a bit confusing. See it in action with this plnkr preview (or see the plnkr editor).
I've checked the FormController API. Based on the documentation, there's no method to provoke any kind of form validation status refresh, although the AngularJS source code defines methods like $removeControl() and $setValidity() in the FormController.
Is there a standard way to circumvent the validation issue?
I came across this before, see this answer for more detail: https://stackoverflow.com/a/15192773/317180
Apparently this is an active bug.
A workaround is to provide a hidden counter that is incremented when elements are changed, this forces the form to revalidate:
In template:
<input type="hidden" ng-bind="abc" />
In controller:
$scope.remove = function(position) {
$scope.items.splice(position, 1);
$scope.abc += 1;
}

Resources