I am using Angular JS 1.5.6 and I would like to use only component and not directive.
I have more than 5 views using a form in my application. The style of the form is exactly the same in all the views, it is only the content of the form that changes. I have made components (input, button, etc..) and I would like to create a component for the form, it would be like a container component, in which I can put different components. In view A, the form will contain 1 button and 1 input, in view B the form will contain 2 button and 2 inputs, etc... But I don't know if it is possible to do it and how to dow it. I have plnkered this. I would like to create a component for the form.
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<link data-require="bootstrap-css@3.3.6" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.6/angular.min.js"></script>
<script src="script.js"></script>
<script src="myInput.js"></script>
<script src="myButton.js"></script>
</head>
<body ng-controller="MyCtrl">
<div class="container">
<h2>My form</h2>
<form role="form">
<my-input label="Firstname"></my-input>
<my-input label="Lastname"></my-input>
<my-button label="Submit"></my-button>
</form>
</div>
</body>
</html>
There are two basic problems need to be solved in your form container:
I solve two problems by
Code for form component:
angular.module('MyApp').component('myForm', {
templateUrl: function($element, $attrs) {
return $attrs.template; // read template file from component attribute
},
controller: MyFormController,
bindings: {
label: '@',
summitHandler: '&' // call to function outside of component via this property
}
});
In MyFormController, we need handle summit event by calling to summitHandler function passed via binding property:
function MyFormController($scope, $element, $attrs) {
var ctrl = this;
ctrl.summitForm = function(data) {
// call handler with data summited
var handler = ctrl.summitHandler();
handler(data);
}
}
That all for our form container component.
Now you can add my-form with:
<my-form label="Personal Info" template="myForm.html" summit-handler="ctrl.myFormHandler"></my-form>
Property ctrl.myFormHandler will be a function handling event in myCtl with:
ctrl.myFormHandler = function(data){
console.log('receive test summit:' + data);
ctrl.dataReceived = data;
}
See it run here in Plunk.
Typing in the age field, you can see it will be passed to outside of form. Extend it with more features as you want.
Look at this project:
http://kelp404.github.io/angular-form-builder/
If you want to implement this yourself you will need to create a template dynamically and compile it before it's injected into the DOM.
This project can be useful:
https://github.com/incuna/angular-bind-html-compile
It's directive but it will inject and compile your form elements (components or directives) for you:
<div bind-html-compile="formElements.input1"></div>