Camunda Custom Form Field Type - camunda

We are implementing Camunda on our application and we have a problem with forms
We need to implement our own form field type. We use the Camunda Modeler and use the custom type in the Type attribute of the field but when we try to deploy the war we always see the same error
ENGINE-16004 Exception while closing command context: ENGINE-09005 Could not parse BPMN process. Errors:
* unknown type 'file' [...]
We searched in the documentation but we don't see how to implement custom form field types
Any idea how to solve this?
Thanks in advance

You didn't provide much information on your project and how you try to use custom types in embedded? TaskForms.
Camunda has a nice example how to do this with embedded TaskForms here:
https://github.com/camunda/camunda-bpm-examples/tree/master/usertask/task-form-embedded-serialized-java-object

The custom type in generated forms is for types which can be rendered as the value of a single html input field, it is not useful to render complex structures like tables or multiple inputs for bean properties.
https://forum.camunda.org/t/camunda-custom-form-field-type/501 describes how the custom type works:
The custom type must extend AbstractFormFieldType, which provides mappings between model types and form display types, see DateTypeValue for an example. Then you must tell the bpmn engine about your custom type using ProcessEngineConfiguration.setCustomFormTypes() in a ProcessEnginePlugin which has access to the bpm engine configuration.
The generated form will render the form display type as a single input field, only alternatives are datepicker for date and select for enum, as you see in HtmlFormEngine#renderFormField:
if(isEnum(formField)) {
// <select ...>
renderSelectBox(formField, documentBuilder);
} else if (isDate(formField)){
renderDatePicker(formField, documentBuilder);
} else {
// <input ...>
renderInputField(formField, documentBuilder);
}
This is org.camunda.bpm.engine.impl.form.engine.HtmlFormEngine#renderInputField, it renders a single input:
protected void renderInputField(FormField formField,
HtmlDocumentBuilder documentBuilder) {
HtmlElementWriter inputField = new HtmlElementWriter(INPUT_ELEMENT, true);
addCommonFormFieldAttributes(formField, inputField);
String inputType = !isBoolean(formField) ? TEXT_INPUT_TYPE : CHECKBOX_INPUT_TYPE;
inputField.attribute(TYPE_ATTRIBUTE, inputType);
// add default value
Object defaultValue = formField.getDefaultValue();
if(defaultValue != null) {
inputField.attribute(VALUE_ATTRIBUTE, defaultValue.toString());
}
// <input ... />
documentBuilder.startElement(inputField).endElement();
}

Related

Sitecore how to show item's field in a datasource instead of item name

In a templateItem I have following information for a field.
Name : Product type
field type : 'Droplink'
DataSource : DataSource=/sitecore/content/Enumerations/Products/Product type/
When the content editor creates an item based on above template, for the field 'Product type' in the dropdown he will see the items under ../Product type. My question is for the items which are show in dropdown how to show some other field instead of item name
This functionality does not exist out of the box, although the code for the DropLink field looks like has code in there to be able to do this (take a look at the GetItemHeader() method in Sitecore.Shell.Applications.ContentEditor.LookupEx), I do not know how to utilize the parameter through the Content Editor though...
It's simple enough to create a custom field to achieve this though:
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Shell.Applications.ContentEditor;
namespace MyProject.Custom.Fields
{
public class CustomDropLink : LookupEx
{
protected override string GetItemHeader(Item item)
{
if (string.IsNullOrEmpty(this.FieldName))
this.FieldName = StringUtil.ExtractParameter("FieldName", this.Source).Trim();
return base.GetItemHeader(item);
}
}
}
Then register your custom class in the core database under /sitecore/system/Field types/. You can do this by duplicating /sitecore/system/Field types/Link Types/Droplink and setting the following values:
Assembly: MyProject.Custom
Class: MyProject.Custom.Fields.CustomDropLink
Control: <set this to empty>
Then when you utilise this field set the Source of your field like so:
Datasource=/sitecore/content/path/to/items&FieldName=Title

Drupal 8, get programmatically the list of fields of a custom content

I want create programmatically a custom content (custom content created via the admin UI). But, before the creation, I want check programmatically the types of fields of my custom content
My custom content contains a field "body" (type text), a field "description" (type text), an int field (type int), an attached file field (type fid ?)...
I test several ways with the new api of Drupal 8, my last try..
// I get the entity object "my_custom_content"
$entity_object = NodeType::load("my_custom_content");
dpm($entity_object); //Work perfectly
$test = \Drupal::getContainer()->get("entity_field.manager")->getFieldDefinitions("my_custom_content",$entity_object->bundle())
//The \Drupal::getConta... Return an error : The "my_custom_content" entity type does not exist.
With this $entity_object, how can I get the list of the fields of my custom content ?
I see the EntityFieldManager Class, the FieldItemList Class...But I still do not understand how to play with drupal 8 / class / poo ... :/
Thanks !
NodeType is the (config) bundle entity for the Node (content) entity.
The correct call would be:
\Drupal::service('entity_field.manager')->getFieldDefinitions('node', 'my_custom_content');
To get the field definitions of any entity_type use the following structure:
\Drupal::service('entity_field.manager')->getFieldDefinitions(ENTITY_TYPE_ID, BUNDLE_ID);
For example, if you want to get all the field definitions of a paragraph bundle with the id multy_purpose_link then replace ENTITY_TYPE_ID with paragraph and BUNDLE_ID with multy_purpose_link
\Drupal::service('entity_field.manager')->getFieldDefinitions('paragraph', 'multy_purpose_link');
The given answers are deprecated. You should now load the entity and just use getFieldDefinitions() to fetch the field definitions.
$node = Node::load($slide_id);
$field_defs = $node->getFieldDefinitions();
Or
$field_defs = \Drupal::service('entity_field.manager')->getFieldDefinitions('taxonomy_term', '<taxonomy machine name here>');
If you want to get the list of field_definitions for a taxonomy vocabulary
If the entity type does not have a bundle, for example the user entity.
Try this:
// All user fields and ones added
$user_fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('user','user');
// Just default
$default_user_fields = \Drupal::service('entity_field.manager')->getFieldDefinitions('user', NULL);

GRAILS: Can I call service logic from _FORM.GSP template?

I'm refactoring scaffolding templates and I hit a wall with this issue:
I was trying to call service (some security logic) from template _FORM.GSP - but in the code part, not in the output part
I've read and tried what was suggested in here: How do I call a Grails service from a gsp?
I've tried to use taglib, but my knowledge of grails may not be extensive enough for that
I've tried add import and def to the beginning of _FORM.GSP file (both grailsApplication and application instantiation of service were crashing on missing property application resp. missing property grailsApplication)
I've even tried to call the taglib from the code both directly as method isAllowedToEdit and also as g.isAllowedToEdit both crashing on unknown method resp. "no such property g"
it seems that template _form.gsp has different rules than standard gsp view
I want to do something like this:
private renderFieldForProperty(p, owningClass, prefix = "") {
boolean hasHibernate = pluginManager?.hasGrailsPlugin('hibernate')
boolean display = true
boolean required = false
if (hasHibernate) {
cp = owningClass.constrainedProperties[p.name]
display = (cp ? cp.display : true)
required = (cp ? !(cp.propertyType in [boolean, Boolean]) && !cp.nullable && (cp.propertyType != String || !cp.blank) : false)
}
/* trying to do this part */
// I want to assign value to cp.editable - so later I can render read-only fields in renderEdit
if (!mySecurityService.canEdit(springSecurityService.currentUser, owningClass.getClass(), actionName, p.name)) {
cp.editable = false
}
/* trying to do this part */
if (display) { %>
<div class="fieldcontain \${hasErrors(bean: ${propertyName}, field: '${prefix}${p.name}', 'error')} ${required ? 'required' : ''}">
<label for="${prefix}${p.name}">
<g:message code="${domainClass.propertyName}.${prefix}${p.name}.label" default="${p.naturalName}" />
<% if (required) { %><span class="required-indicator">*</span><% } %>
</label>
${renderEditor(p)}
</div>
<% } } %>
if there is any way to assign cp.editable - I'll try your suggestions
it seems that template _form.gsp has different rules than standard gsp view
The generated _form.gsp works same as other gsps but the template inside the scr/templates/scaffolding/ is different. Customizing the templates like you are doing is a bit more tricky. Keep in mind that the logic you are writing is for Grails on how to generate views(gsp). Meaning you are telling Grails to check some logic before generating the views in memory or in the file. You might be able to accomplish that to some extend for dynamic (in memory) scaffolding at run-time but for sure not for static scaffolding. That's because Grails
is not aware of currentUser when generating the templates.
Your problem will be much simpler if you generate your views and then customize them instead of modifying their templates. Then you can inject your services and do other checks. However, as you also mentioned those logics are better off in a tag library here.
Also since you mentioned security, rendering a field non-editable does not guaranty inability to edit your fields. I would suggest to put the check logic inside your controller for example in SAVE or UPDATE action to prevent any unauthorized user editing fields.
Did you try this?
<%# page import="com.myproject.MyService" %>
<%
def myService = grailsApplication.classLoader.loadClass('com.myproject.MyService').newInstance()
%>
this will work for sure.
go through this link : click here

How to add multiple forms Joomla 2.5 component

I am developing a joomla website which required some custom component to integrate manage portfolio, user profile etc. We downloaded one of the hello_world MVC component for joomla 2.5[http://docs.joomla.org/Developing_a_Model-View-Controller_Component/2.5/Introduction] and did necessary customization. First component worked well. But now we need a new component that is having multiple forms required to integrate.
Eg: Store types for one form, store details for another form, manage country/ state by another form.
In the default component having option for manage one form [add/edit/delete/view]. Here I tried to modify/replicate but I failed.
Can anyone suggest the architecture/ sample code to manage multiple forms [Add/edit/delete/view] in joomla 2.5 component creation.
Any help will be apreciate?
Supposing You're speaking of forms stored in the model/forms folder... You should try to override the getForm() function in your model, to call the right form. You should pass a 'layout' when calling the page and then get it in the model constructor.
May be so:
class YourComponentModelYourModel extends JModelAdmin{
public function __construct($config = array()){
switch(JRequest::getVar('layout')){
case 'firstlayout' : $this->form='firstform';
break;
case 'secondlayout' : $this->form='secondform';
break;
default : $this->form='defaultform';
}
parent::__construct($config);
}
...
public function getForm($data = array(), $loadData = true)
{
// Get the form.
$form = $this->loadForm('com_yourcomponent.'.$this->form,$this->form,
array('control' => 'jform', 'load_data' => $loadData));
if (empty($form)){return false;}
return $form;
}
You must put a layout for each form in the views/YourView/tmpl folder and the form declaration must call the layout also :
<form action="<?php echo JRoute::_('index.php?option=com_yourcomponent&layout=firstlayout&id='.(int) $this->item->id); ?>"
method="post" name="adminForm" id="draw-form">

Adding a search box to filter a list of results in Symfony?

I need to put a search box within a list of objects as a result of a typical indexSuccess action in Symfony. The goal is simple: filter the list according to a criteria.
I've been reading the Zend Lucene approach in Jobeet tutorial, but it seems like using a sledge-hammer to crack a nut (at least for my requirements).
I'm more interested in the auto-generated admin filter forms but I don't know how to implement it in a frontend.
I could simply pass the search box content to the action and build a custom query, but is there any better way to do this?
EDIT
I forgot to mention that I would like to have a single generic input field instead of an input field for each model attribute.
Thanks!
I'm using this solution, instead of integrating Zend Lucene I manage to use the autogenerated Symonfy's filters. This is the way i'm doing it:
//module/actions.class.php
public function executeIndex(sfWebRequest $request)
{
//set the form filter
$this->searchForm = new EmployeeFormFilter();
//bind it empty to fetch all data
$this->searchForm->bind(array());
//fetch all
$this->employees = $this->searchForm->getQuery()->execute();
...
}
I made a search action which does the search
public function executeSearch(sfWebRequest $request)
{
//create filter
$this->searchForm = new EmployeeFormFilter();
//bind parameter
$fields = $request->getParameter($this->searchForm->getName());
//bind
$this->searchForm->bind($fields);
//set paginator
$this->employees = $this->searchForm->getQuery()->execute();
...
//template
$this->setTemplate("index");
}
It's important that the search form goes to mymodule/search action.
Actually, i'm also using the sfDoctrinePager for paginate setting directly the query that the form generate to get results properly paginated.
If you want to add more fields to the search form check this :)
I finally made a custom form using the default MyModuleForm generated by Symfony
public function executeIndex {
...
// Add a form to filter results
$this->form = new MyModuleForm();
}
but displaying only a custom field:
<div id="search_box">
<input type="text" name="criteria" id="search_box_criteria" value="Search..." />
<?php echo link_to('Search', '#my_module_search?criteria=') ?>
</div>
Then I created a route named #my_module_search linked to the index action:
my_module_search:
url: my_module/search/:criteria
param: { module: my_module, action: index }
requirements: { criteria: .* } # Terms are optional, show all by default
With Javascript (jQuery in this case) I append the text entered to the criteria parameter in the href attribute of the link:
$('#search_box a').click(function(){
$(this).attr('href', $(this).attr('href') + $(this).prev().val());
});
And finally, back to the executeIndex action, I detect if text was entered and add custom filters to the DoctrineQuery object:
public function executeIndex {
...
// Deal with search criteria
if ( $text = $request->getParameter('criteria') ) {
$query = $this->pager->getQuery()
->where("MyTable.name LIKE ?", "%$text%")
->orWhere("MyTable.remarks LIKE ?", "%$text%")
...;
}
$this->pager->setQuery($query);
...
// Add a form to filter results
$this->form = new MyModuleForm();
}
Actually, the code is more complex, because I wrote some partials and some methods in parent classes to reuse code. But this is the best I can came up with.