Resetting a Formly form within an ng-repeat - angularjs

I have an Angular Formly form inside an ng-repeat. I've got everything working as I would expect except for the reset button. For some reason clicking any reset button always resets the last form, not the one it's supposed to. Submitting and updateInitialValue() seem to work fine.
<div ng-repeat="model in vm.models">
Here is the form declaration inside the repeat:
<formly-form model="model" fields="vm.fields" options="vm.options[$index]" form="vm.form[$index]">
And here is the reset button.
<button type="button" class="btn btn-default" ng-click="vm.options[$index].resetModel()">Reset</button>
Here is the whole thing in a fiddle.
http://jsbin.com/feguvulumo/edit?html,js,output
Thanks in advance for any help you can give!

I figured this out with some help from #kentcdodds on the Formly gitter chat (https://gitter.im/formly-js/angular-formly)
He suggested that the issue was that the repeating forms are sharing the same field configuration.
To fix it, I implemented a function that was called by an ng-init inside the ng-repeat. It builds up an array of fields objects as it loops.
function addFields() {
vm.fields.push(new getFields());
}
I then changed the fields property on the <formly-form> like so
<formly-form model="model" fields="vm.fields[$index]" options="vm.options[$index]" form="vm.form[$index]">
Full solution
http://jsbin.com/yanopeyija/1/edit?html,js,output

I am also new to angular, but generally this could be achieved if we change the button type as reset :
<button type="reset" >

Related

How to manage an Accordion of Directives in Angular

I'm building a large input form in angular. To make the application user friendly I have broken the form down into many different sections. I need each section to reside within a different group of an accordion. Each section needs to have validation and a user cannot progress until the required field validation has been satisfied.
In the main page of the app I have added the markup for the accordion. Each section within the accordion is a custom directive. The directive contains the markup for each group (The input form and validation) and it also contains the code to connect to the relevant services to persist state within a db.
Sample code
<uib-accordion close-others="true">
<uib-accordion-group heading="Person Details" is-open="heading1.isOpen">
<div person-details></div>
<button class="btn btn-default btn-sm pull-right" ng-click="heading2.isOpen = !heading2.isOpen">Next <i class="glyphicon glyphicon-chevron-right"></i></button>
</uib-accordion-group>
<uib-accordion-group heading="Address Details" is-open="heading2.isOpen">
<div address-details></div>
<button class="btn btn-default btn-sm pull-right">Next <i class="glyphicon glyphicon-chevron-right"></i></button>
</uib-accordion-group>
</uib-accordion>
The difficulty is how to manage what accordion group is open at any time. In the example code above I have a next button to open the next accordion group. However this button needs to reside with the directives themselves in order to manage validation. The problem with this is that the directives then need to know how to control the accordion in order to change the active accordion group - bubble up somehow.
Does anybody have any thoughts on this please? If you think I am going about this is the wrong way please let me know.
Thanks
You need to use a scope variable in your directive(s) that has a two way binding to heading1.isOpen for example. That way the directive will be able to modify the is-open state of its parent directive.
Just search angular docs for directives and isolated scope variables.

Angularjs ui-bootstrap btn-checkbox conditional styling

Would like to use btn-checkbox in place of all my checkboxes on a form. I am looking for the syntax to make a generic reference to the value of the bound property from within the attributes, in this case ng-class.
<button type="button"
ng-class="{true: 'btn btn-success',
false:'btn btn-checkbox-off'}
[vm.csrMain.doubleAggregate]"
ng-model="vm.csrMain.doubleAggregate"
btn-checkbox btn-checkbox-true="true" btn-checkbox-false="false">
DOUBLE AGGREGATE
</button>
( using ctrl as vm syntax ) The code above works, but I want to make a generic reference to the value of the ng-model in the brackets where I am hard coding the bound property [vm.csrMain.doubleAggregate] something like [ng-model.$value]
Tried to do a plunker here. Not sure why I can't get the btn-checkbox behavior I get successfully in the code above. If someone could guide me on that as well I'd appreciate it as this my first shot at a plunk from scratch plunker

Reset file selection blueimp fileupload - angularJS

I am looking for a way to reset the file selection, in case the user choose an invalid file for instance.
From this issue on gitHub, it appears that you need to unbind the event in order to reset the file selection, now, how do I do such a thing in AngularJS?
Markup:
<form name="applyForm" data-file-upload="model.uploadOptionsResume" action="{{model.application_url}}" method="{{model.method}}" enctype="multipart/form-data">
<fieldset>
<input type="file" data-ng-model='model.formData.resume' name="resume" data-ng-disabled="" data-valid-file data-my-validate data-value-required="true">
<submit data-ng-disabled="applyForm.$invalid || innerLoader" class="btn btn-primary" style="width:99%;" data-ng-click="submit(); model.submitFormApplicant()">
Apply
<!-- submitFormApplicant() check if a file is selected and if not does regular submit -->
</submit>
</fieldset>
</form>
I think that unbinding the event is required because of the closed over variables that are captured with the .on('click', ... anonymous function. I am pretty sure your code can be structured to not rely on the closure, thus removing the need to unbind from ng-click. However, without seeing your code, I cannot be sure that closures are your problem nor can I really recommend how restructure your code if they are.

Angular ng-click won't fire if angular {{model}} is included as parameter

I would think this is fairly straight forward, but if I try to include a bound {{data}} model as a parameter in ng-click, nothing happens (an no error is fired in Console).
For example, I have the following:
<p ng-repeat='item in array'>
<a ng-click='function({{item}})'></a>
</p>
Here is a plunker that is more fleshed out: plunker
If I click on the link, nothing happens. Ideas?
Found my own answer:
within ng-click, there is no need for the {{notation}}. It knows that "item" is an angular data model. Again, not super clear in the Angular documentation.
Here is the updated plunker that shows it working and not working.

AngularJS required radio buttons needs two click events to be valid

I have a very simple form where a radio button is required to be selected in order for a form to be valid. The radio buttons are generated by ngRepeat.
As you can see from this fiddle, while the desired behavior is that when the radio button is clicked for the first time, that should validate the form (being the only element), however notice that it takes an additional click (on the same radio button or any other) to validate the form:
http://jsfiddle.net/Xsk5X/3/
What am I missing?
All the other solutions are work-arounds: All you have to do is remove the name attribute, when you use the ng-model attribute you don't need it and they conflict.
Specifying the name causes Angular to get confused because it changes the value once for the angular model and another time for the form element name.
I had this problem because a colleague had copied the radio buttons in the same page and hidden them for temporary reference, so duplicate radio inputs with the same name
Try adding the ng-click attribute to your radio button input.
Credit to Manny D for noting this first. Yes, this is a little hackish, but it works. E.g.,
<input type="radio"
name="groupName"
ng-model="editObject.Property"
ng-value="someValue"
ng-click />
The reason why this is breaking - is because you're setting all radio boxes to be required. As a result, depending on how you write it - angularjs is saying it's invalid because not all have been selected at some point.
The way around this is to do something like the following:
Using checkboxes and required with AngularJS
(check the 1st and 2nd answers). This will resolve your problem.
Seems like an AngularJS 1.0.3 $scope.$apply update problem.
Tested your exact Fiddle in 1.0.2 (check it out yourself) and it works the way you expect it too.
It doesn't seem like there's anything wrong with your code, just that $scope.$apply(or $digest) isn't working as expected on the first select.
A very simple fix is to force the $scope to also update on every select, try changing the following line of code in your form:
<p>Favorite Beatle</p>
change it too:
<p>Favorite Beatle: {{name}}</p>
And you will see how myForm.$invalid is updated even after the first click.
I would try it out with the latest AngularJs version and let us know if that happens there too.
Another solution I can think of it setting the default selected radio, which will cause myForm.$invalid to be false from the beginning. you can do this by adding the following line in your controller code:
$scope.name = "John";
or any default name you want.
Some times the $digest cycle dosen't $apply(fn) because you have two o more instances.
For fix this you need $apply this trick manually, so put this in your directives:
angular.('myApp',[])
.directive('ngRadioExtend', ['$rootScope', function($rootScope){
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, iElm, iAttrs, controller) {
iElm.bind('click', function(){
$rootScope.$$phase || $rootScope.$apply()
});
}
};
}])
and use it as:
<input type="radio" name="input_name" ng-model="some" value="F" ng-required="true" ng-radio-extend>
<input type="radio" name="input_name" ng-model="some" value="M" ng-required="true" ng-radio-extend>
DONE it's the correct way!
The problem of the scope not getting updated still occurs in 1.1.5
A simple work around is to just add
<span ng-show="false"> {{name}} </span>
Fiddle: http://jsfiddle.net/jonyschak/xaQJH/
For IONIC v1,
add name="" to prevent ionic auto-generate attribute name.
Then, I can change the selected item with only one click.
<ion-radio class="label-ticket"
ng-repeat="topic in vm.listTopic track by $index"
ng-value="topic"
ng-model="vm.topicSupport"
name="">
{{ topic.title }}
</ion-radio>

Resources