AngularJS using ngRequired without using ngModel - angularjs

I'm currently maintaining an AngularJS application and need to have html inputs use the ngRequired directive. However these inputs do not use ngModel-- just straight up value to display the value dynamically and ngClick to popup a modal window that will eventually set the value in an object that is not bounded to a model. Seems like ngRequired only works when paired with ngModel in order for the submit button to reflect changes appropriately (like enable/disable).
I tried to work around not using ngRequired by manipulating the ngInvalid CSS which works great for showing the required fields-- however it does not bubble up to the submit button (disabling it if one or more required fields have no input). Is there a way to emulate ngRequired without using it explicitly in AngularJS?

Related

Why Angular 1 form validation not works without ng-model

I am trying to implement the basic angular form validation. I have implemented the same. But I am curious to know, why it does not works if I am not using ng-model.
Link for plunker to show the same behaviour
ngModel directive holds an instance of NgModelController containing the services for data-binding, validation, CSS updates, and value formatting and parsing. If ngModel itself is not there, validation will not work.
For form validation to work you need both form instance which can be published to scope using name attribute and the form input control (ngModel). The below description from Angular documentation explains that:
A form is an instance of FormController. The form instance can
optionally be published into the scope using the name attribute.
Similarly, an input control that has the ngModel directive holds an
instance of NgModelController. Such a control instance can be
published as a property of the form instance using the name attribute
on the input control. The name attribute specifies the name of the
property on the form instance.
This implies that the internal state of both the form and the control
is available for binding in the view using the standard binding
primitives.
This allows us to extend the above example with these features:
Custom error message displayed after the user interacted with a
control (i.e. when $touched is set) Custom error message displayed
upon submitting the form ($submitted is set), even if the user didn't
interact with a control
Because without the ng-model, the input elements aren't bound to anything within your application's scope.
Angular has own context model. (scope or something else) If you treat form outside Angular world, form can't get any information in Angular point of view.
If you doesn't want to use ng-model, use plain javascript validation method.
ng-model="value" defines that the value of that particular element is from angular's context. It checks for the value in the scope where the element is declared. For example, we have onclick="call()" and ng-click="call()" methods. The onclick event search for the function that is outside of angular context, ng-click event search for the function in the scope.
<div ng-app="app" ng-controller="Ctr" onclick="call()" ng-click="call()"></div>
<script>
function call(){
console.log('out of angular');
}
angualr.app('app', function($scope){
$scope.call = function(){console.log('insode angular')}
})
</script>
In the above code if you remove onclick, then ng-click prints 'inside angular', if you remove ng-click, then onclick prints out of angular. If both will be there, both will be called and prints.
In the same way, if you remove ng-model, you will loose the control over the value of input in angular context and $error, $invalid doesn't know what to validate.

angularui bootstrap typeahead- prepopulate dropdown list onfocus

I am using angularui bootstrap typeahead module for my project.
I am unable to pre-populate the drop-down with predefined value.
Whenever user click on input text of typeahead, it should automatically show the typeahead suggestion dropdown(from a static JSON).
Whenever user starts typing, then the behaviour should be normal.
I tried this solution but unfortunately it stopped working when I upgraded my angularjs to version 1.3
So I essentially accomplished this by making a custom directive and making a minor modification to the ui bootstrap typeahead code. You have to trick the typeahead into thinking someone has typed something in it. I placed a little pulldown arrow to the right of the field so essentially it looked like a pulldown and clicking on that arrow would show ALL choices. You should be able to do it using onfocus.
Basically find the code in the bootstrap typeahead that binds to the key events and I changed it to check for a keydown event of 40
if(scope.matches.length === 0 && evt.which === 40) { // Added
// COMMENT OUT modelCtrl.$setViewValue(modelCtrl.$viewValue);
modelCtrl.$setViewValue(''); // Added
}
You'll also need to make sure the typeaheadMinLength is set to 0. Note in the code above it checks for the case of the user NOT having typed anything AND the special keydown event that I trigger. You should be able to change this to trigger on onfocus. I copied the bootstrap typeahead to mytypeahead.js and then modified it as above, along with a few other minor mods that you may or may not need depending on if the field is "required" or not.

Directive that binds to form input blur event

I would like to have a directive for my validation messages that takes the name of the form input being validated and then displays itself if the named form input is invalid. For the sake of good UI, I want this to only happen after the input is blurred. Here's a Plunkr: http://plnkr.co/edit/qLSsCHpAPLdZsCPG8iaf
Obviously, ctrl[attr.tgValidates] isn't giving me an object I can bind to (although it is referencing the correct field), but I'm not sure how to properly select the element I do want. jqLite doesn't have great support for selectors, so it's a tricky to do what I want without pulling in all of jQuery. I guess I could also pull in $document and select off that, but I'm wondering if there's a better, more Angular way to approach this?

is ng-model allowed inside <td> element of a table?

Is ng-model allowed inside element of a table? Will angular automatically update the model if I change a particular column(i.e. view)?
If you are making the table cells directly editable using the HTML contenteditable attribute, ng-model won't work automatically as by default it's only for form elements.
It is possible to make it work with contenteditable though. There is an working example of how to do it on the angular website at http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController
ng-model is allowed wherever typical form elements exist that can use the directive (input, select and textarea)
One thing I will say about ng-model that can make it a bit tricky is that you will want to bind ng-model to a property of an object rather than just a simple scope variable. I have run into several instances where I bind $scope.foo to ng-model and use it in an input control. Then, if you clear the input field, the binding is lost and it stops updating the variable. Use something like $scope.fooObj.modelProp where fooObj is an object and it will work fine.

AngularJS -- How to disable a form when it's being submitted?

How does one disable the complete form (all input elements within it), while it's being submitted via AJAX? I've tried setting a $scope.form_state variable in the controller and binding it to the submit button's ng-disabled attribute, but it seems like a workaround. There should be an easier + straight-forward way of doing this.
You can put all form elements into fieldset and use ng-disabled to disable the whole fieldset.

Resources