0

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="[email protected]" 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>

2 Answers 2

1

There are two basic problems need to be solved in your form container:

  • Dynamic template for your form

  • Handle summit should be run outside of your component.

I solve two problems by

  • Read template via attrs property

  • Pass handler function as a binding property

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.