Embedded Forms using AngularJS or plain JavaScript?

Hi to everyone.

I have been trying for a long time to find a way in order to create a user task form displayed within Tasklist. I want to create a shopping list form where I will be able to add and remove items like the one in the example of the following link:
Angular Application
At the moment I have been learning JavaScript as I am not a web developer but I am a bit confused with the code which I must write in my editor (I am using an Eclipse Neon 3 Package for Java EE Developers) as I have taken a look at many and different code snippets throughout the Internet.
Unfortunately, I am not a software developer in order to be able to decide which one is the most appropriate for my task.
So, I would like to ask here if I can create an application form like the above one with plain JavaScript or if I have to embed AngularJS into my Eclipse and by which way in the second case.

Any answers here would be really valuable.
Thanks a lot.

Steve

Hi @steftriant,

In think you should use embedded forms with the cam-script directive in combination with angular.
please take a look a the javascript reference
You could use the cam-script directive and hook into the lifecycle events.

You can check that example on github and combine it with your example.

Your solution could be:

<form role="form">

  <script cam-script type="text/form-script">

    // angular form works on scope object
    var products = $scope.products = [];

    $scope.addItem = function () {
        $scope.products.push($scope.addMe);
    }
    $scope.removeItem = function (x) {
        $scope.products.splice(x, 1);
    } 

    // hook into camunda SDK JS Form Lifecycle
    camForm.on('form-loaded', function() {

      // declare variable 'customerData' incuding metadata for serialization
      camForm.variableManager.createVariable({
        name: 'products',
        type: 'json',
        value: products,
      });

    });

  </script>

  <h3>Shopping List</h3>
  <div>
   <ul>
        <li ng-repeat="x in products">
            {{x}}
            <span ng-click="removeItem($index)">&times;</span>
        </li>
    </ul>
    <input ng-model="addMe">
    <button ng-click="addItem()">Add</button>
  </div>
</form>

regards,
Dominik

Hi @dominikh and @StephenOTT.
Thank you for your answers here and sorry for my delayed response.
This week, I installed and configured AngularJS in my eclipse JEE Neon 3. I followed the instructions referenced in the blog site (How to Install and configure AngularJs in eclipse – Beginner's Blog) and I checked that everything was ok by executing its last step (10.).
I studied and wrote the code snippet of @dominikh here today, I saw the relative form in my Tasklist but there are 2 main issues.
The first one is that when I click on the button (Add) in order to add items in my form list, the button is deactivated. It does nothing. I can submit only one value to the input field of my form.
The second one is that if I don’t insert a value to the input field of the form and click on “Complete” to continue my process, the form is submitted, the process continues and this is something I don’t want to happen.
I also uploaded a screenshot of my HTML File (add-categories.html) from my eclipse in order to see the relative code and another one with the relative form (My List of Categories) from my Tasklist.
I would appreciate any possible help, thank you.

regards,
Steve


Hi @steftriant

could you please post the code (not as a screenshot) of your form to check that :slight_smile:

You could hook into the events and prevent the submit from being executed if no category was added:

 camForm.on('submit', function(evt) {
      // handle submit
      // may prevent the submit from being executed:
      if (categories.length < 1){
         evt.submitPrevented = true;
     }
    });  

regards,
Dominik

Hi again @dominikh.
Yes, of course.
My code is this one:

<script cam-script type="text/form-script">
	
	var categories = $scope.categories = [];      /* Custom JavaScript creates a JavaScript Object and 
												     binds it to the angular $scope of the form
												     as a variable named "categories".*/
	$scope.addItem = function () {				  /* We make a function named "addItem" and we
		$scope.categories.push($scope.addMe);        use the value of the addMe input field to add an item to the array "categories".*/
	}
	$scope.removeItem = function (x) {			  /* We make a function named "removeItem" which
		$scope.categories.splice(x,1);				 takes the index of the item we want to remove, as a parameter.*/ 			      
	}
	camForm.on('form-loaded', function() {		  /* We hook into the lifecycle of Camunda SDK JS Form.*/
		
		camForm.variableManager.createVariable({  /* We create a process variable
		name:'categories',						     named "categories" and 
		type:'json',								 provide as type information 'json' used for serialization.*/
		value:categories
	});
});

</script>

<h2>My List of Categories</h2>
<div>
	<ul>
		<li ng-repeat="x in categories">		         <!--A list is displayed using the items of the array "categories".--> 
			{{x}}
			<span ng-click="removeItem($index)">x</span> <!--For each item we make a "span" element and--> 
		</li>											 <!--give them a "ng-click" directive--> 
	</ul>												 <!--which calls the function named "removeItem" with the current "$index".-->
	<input ng-model="addMe">
	<button ng-click="addItem()">Add</button>			 <!--A button is given a "ng-click" directive which runs the function named "addItem" when the button is clicked.-->                                           
</div>

As for the second issue I would like to ask you where can I find the relative snippet and where can I put it in my code. In a similar AngularJS App. example of w3schools (https://www.w3schools.com/angular/angular_application.asp) there is a relative reference in its 4th step (Error Handling).

Thanks,
Steve

Hi @steftriant,

your comments are the problem…

$scope.categories.push($scope.addMe); also gets disabled:

here

This Code should work:

<form role="form">
<script cam-script type="text/form-script">
	
	var categories = $scope.categories = [];      // Custom JavaScript creates a JavaScript Object and 
												  //  binds it to the angular $scope of the form
												  //  as a variable named "categories".
	$scope.addItem = function () {				  // We make a function named "addItem" and we
		$scope.categories.push($scope.addMe);     //  use the value of the addMe input field to add an item to the array "categories".
		$scope.addMe = "";	
	}
	$scope.removeItem = function (x) {			  // We make a function named "removeItem" which
		$scope.categories.splice(x,1);			  // takes the index of the item we want to remove, as a parameter.		      
	}
	camForm.on('form-loaded', function() {		  // We hook into the lifecycle of Camunda SDK JS Form.
		
		camForm.variableManager.createVariable({   // We create a process variable
		name:'categories',						   //  named "categories" and 
		type:'json',							   // provide as type information 'json' used for serialization.
		value:categories
		});
	});

 camForm.on('submit', function(evt) {
      // handle submit
      // may prevent the submit from being executed:
      if (categories.length < 1){
         evt.submitPrevented = true;
     }
    }); 

</script>

<h2>My List of Categories</h2>
<div>
	<ul>
		<li ng-repeat="x in categories track by $index">		         <!--A list is displayed using the items of the array "categories".--> 
			{{x}}
			<span ng-click="removeItem($index)">x</span> <!--For each item we make a "span" element and--> 
		</li>											 <!--give them a "ng-click" directive--> 
	</ul>												 <!--which calls the function named "removeItem" with the current "$index".-->
	<input ng-model="addMe">
	<button ng-click="addItem()">Add</button>			 <!--A button is given a "ng-click" directive which runs the function named "addItem" when the button is clicked.-->                                           
</div>
</form>

Hi again @dominikh.
Yes, you are right, the problem is now over, thanks a lot :smiley:
I would also like not to be allowed to add empty items as the app accepts null values in the input field.
If you take a look at the Step 4. Error Handling of the example (https://www.w3schools.com/angular/angular_application.asp) you may understand the way.

regards,
Steve

Hi again @dominikh, @StephenOTT and to everyone else.
I would like to ask something about my 2nd form in the Tasklist.
I want all the submitted values of the variablecategories” to be transfered in my next (my 2nd) form.
In addition, for each one of these categories I want to add a brief description, a detailed description (by uploading a file less than 5 MB for each category) and a price. So, I want to create 3 new variables in this form.
I suppose that I will have to access the already existing json variablecategoriesfirstly and after to create (exactly like in my previous form) the other 3 new json variables but I am not sure because it’s my first attempt and I am not very familiar with all these yet :confused:
The code snippet for my previous form is exactly above in this topic.
Any possible guidance would be really valuable :slightly_smiling_face:

Thanks a lot,
Steve

@steftriant where are you uploading your 5mb files to?

Hi @StephenOTT.
I want to upload for each one of the submitted categories (from my previous form here) one different file whose size will be less than 5 MB in another input field of the same form. And of course to submit in 2 other input fields the other 2 new variables (bried_description & price).
I suppose that I need to write a code snippet like the one (Implementing Custom Fields) from Docs (https://docs.camunda.org/manual/7.7/reference/embedded-forms/javascript/lifecycle/) because I want to combine (in the same code) the fetching of an existing variable and the addition of 3 new variables.
I have also checked this example on github (https://github.com/camunda/camunda-bpm-examples/tree/master/usertask/task-form-embedded-json) on how to access an existing variable in a form.
But, I am not very sure because I am an entire new user of Camunda BPM and that’s why I need a little help at the moment :slightly_smiling_face:

Thanks,
Steve