Hi,
I need an input field with a timepicker. I use the datepicker for dates:
which is documented here:
Is there a similar thing available for time?
Regards,
Nicole
Hi,
I need an input field with a timepicker. I use the datepicker for dates:
which is documented here:
Is there a similar thing available for time?
Regards,
Nicole
Hello @hassang,
I tried it but I am not familiar with angular and setting up angular projects. I always get the error:
I copied the code in my camunda form:
<!doctype html>
<html ng-app="ui.bootstrap.demo">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<form name="generatedForm" role="form">
<div ng-controller="TimepickerDemoCtrl">
<div uib-timepicker ng-model="mytime" ng-change="changed()" hour-step="hstep" minute-step="mstep" show-meridian="ismeridian"></div>
<pre class="alert alert-info">Time is: {{mytime | date:'shortTime' }}</pre>
<div class="row">
<div class="col-xs-6">
Hours step is:
<select class="form-control" ng-model="hstep" ng-options="opt for opt in options.hstep"></select>
</div>
<div class="col-xs-6">
Minutes step is:
<select class="form-control" ng-model="mstep" ng-options="opt for opt in options.mstep"></select>
</div>
</div>
<hr>
<button type="button" class="btn btn-info" ng-click="toggleMode()">12H / 24H</button>
<button type="button" class="btn btn-default" ng-click="update()">Set to 14:00</button>
<button type="button" class="btn btn-danger" ng-click="clear()">Clear</button>
</div>
</form>
</body>
</html>
and added the example.js in the same folder:
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('TimepickerDemoCtrl', function ($scope, $log) {
$scope.mytime = new Date();
$scope.hstep = 1;
$scope.mstep = 15;
$scope.options = {
hstep: [1, 2, 3],
mstep: [1, 5, 10, 15, 25, 30]
};
$scope.ismeridian = true;
$scope.toggleMode = function() {
$scope.ismeridian = ! $scope.ismeridian;
};
$scope.update = function() {
var d = new Date();
d.setHours( 14 );
d.setMinutes( 0 );
$scope.mytime = d;
};
$scope.changed = function () {
$log.log('Time changed to: ' + $scope.mytime);
};
$scope.clear = function() {
$scope.mytime = null;
};
});
Any ideas?
Thank you, Nicole
Hi @NickiMueller,
Kindly find attached a simple working example
The same HTML form is used as a start and task form.
Please deploy the process and form together as in the below snip
test-html-form-process.bpmn (3.0 KB)
I am attaching the content of test-form.html as uploading HTML files to the forum is not allowed
<script cam-script type="text/form-script">
inject([ '$rootScope', '$scope', '$log', function($rootScope, $scope, $log) {
$scope.newTestForm = {};
$scope.newTestForm.isPnFormHeader = true;
$scope.newTestForm.isPnFormHeaderOpen = true;
$scope.newTestForm.isPnAssigneeActionVisible = false;
$scope.newTestForm.isPnAssigneeActionDisabled = true;
$scope.newTestForm.isPnAssigneeActionOpen = false;
var variableManager = camForm.variableManager;
var taskService = camForm.client.resource('task');
$scope.loggedInUser = $rootScope.authentication.name;
$scope.changed = function () {
$log.log('Time changed to: ' + $scope.testBusinessObject.timeValue);
};
camForm.on('form-loaded', function () {
if (!camForm.taskId) {
// start form
$scope.testBusinessObject = {};
// initial value for timeValue
$scope.testBusinessObject.timeValue = new Date();
camForm.variableManager.createVariable({
name: 'testBusinessObject',
type: 'json',
value: $scope.testBusinessObject
});
} else {
// task form
// tell the form SDK to fetch the json variable name 'testBusinessObject'
variableManager.fetchVariable('testBusinessObject');
}
});
camForm.on('variables-fetched', function () {
if (camForm.taskId) {
// task form
taskService.get(camForm.taskId, function (err, task) {
// console.log(JSON.stringify(task));
switch (task.taskDefinitionKey) {
case "ut-task1":
// only visible for ut-task1
$scope.newTestForm.isPnAssigneeActionVisible = true;
$scope.newTestForm.isPnAssigneeActionDisabled = false;
$scope.newTestForm.isPnAssigneeActionOpen = true;
break;
default:
$scope.newTestForm.isPnAssigneeActionVisible = false;
$scope.newTestForm.isPnAssigneeActionDisabled = true;
$scope.newTestForm.isPnAssigneeActionOpen = false;
}
});
}
});
camForm.on('variables-restored', function() {
// work with the variable (bind it to the current angularJS $scope)
$scope.testBusinessObject = variableManager.variable('testBusinessObject').value;
});
}]);
</script>
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading" ng-click='newTestForm.isPnFormHeaderOpen = !newTestForm.isPnFormHeaderOpen'>
<h5 class="panel-title">
<span class="pull-right" ng-class="{'glyphicon glyphicon-menu-up':newTestForm.isPnFormHeaderOpen, 'glyphicon glyphicon-menu-down':!newTestForm.isPnFormHeaderOpen}" aria-hidden="true"></span>
Test Form
</h5>
</div>
<div class='panel-collapse collapse' ng-class="{'in' : newTestForm.isPnFormHeaderOpen}">
<div class="panel-body">
<fieldset>
<div class="form-group">
<div class="col-sm-12">
<label for="ctrTimeValue" class="control-label">Time Value</label>
<div id="ctrTimeValue" uib-timepicker
ng-model="testBusinessObject.timeValue"
ng-change="changed()" />
</div>
</div>
</fieldset>
</div>
</div>
</div>
<div class="panel panel-default" ng-if="newTestForm.isPnAssigneeActionVisible">
<div class="panel-heading">
<h4 class="panel-title">
<span class="pull-right" ng-class="{'glyphicon glyphicon-menu-up':newTestForm.isPnAssigneeActionOpen, 'glyphicon glyphicon-menu-down':!newTestForm.isPnAssigneeActionOpen}" aria-hidden="true"></span>
Assignee Action
</h4>
</div>
<div class='panel-collapse collapse' ng-class="{'in' : newTestForm.isPnAssigneeActionOpen}">
<div class="panel-body">
Assignee Action Details
</div>
</div>
</div>
</div>
Hi @hassang,
thank you. I will test it with my application. That is what I looked for.
Thank you,
regards, Nicole
Hi @hassang,
I now have the problem that I do not know how to bind the variable ‘timevalue’ to am cam-variable respectively delegateExecution object. I tried several possibilities but nothing worked.
In my EJB I want to read out the time variable with:
public void saveTime(DelegateExecution delegateExecution) {
Map<String, Object> variables = delegateExecution.getVariables();
Date thesisColloquiumTime = (Date) variables.get("timeValue");
}
So I tried the following in my form:
<div id="ctrTimeValue" uib-timepicker
ng-model="testBusinessObject.timeValue"
ng-change="changed()" cam-variable-name="timeValue" cam-variable-type="Date" />
That does not work, so I tried it with a separate input field:
<div class="col-sm-12">
<label for="ctrTimeValue" class="control-label">Time Value</label>
<div id="ctrTimeValue" uib-timepicker ng-model="testBusinessObject.timeValue" ng-change="changed()" />
<input cam-variable-name="timeValue" cam-variable-type="Date" ng-model="testBusinessObject.timeValue" />
</div>
The third variant was to put the input field after the Time value div:
In this variant I can see the Input Field with the value but when I complete the task I get an error.
Error:
Any ideas would be great.
Thank you.
Nicole
Hi @NickiMueller,
In the example provided, JSON object is used to store the form’s data “testBusinessObject” so you can access the time value as below
JsonValue testBusinessObject = execution.getVariableTyped("testBusinessObject");
SpinJsonNode jsonNode = testBusinessObject.getValue();
jsonNode.prop("timeValue").value();
If the requirement is to have time value stored in a separate process variable then below HTML content can be used.
Notice: the value of Date typed variable should be updated on form submission.
<script cam-script type="text/form-script">
inject([ '$rootScope', '$scope', '$log', function($rootScope, $scope, $log) {
$scope.newTestForm = {};
$scope.newTestForm.isPnFormHeader = true;
$scope.newTestForm.isPnFormHeaderOpen = true;
$scope.newTestForm.isPnAssigneeActionVisible = false;
$scope.newTestForm.isPnAssigneeActionDisabled = true;
$scope.newTestForm.isPnAssigneeActionOpen = false;
var variableManager = camForm.variableManager;
var taskService = camForm.client.resource('task');
$scope.loggedInUser = $rootScope.authentication.name;
$scope.changed = function () {
$log.log('Time changed to: ' + $scope.testBusinessObject.timeValue);
};
camForm.on('form-loaded', function () {
if (!camForm.taskId) {
// start form
$scope.testBusinessObject = {};
// initial value for timeValue
$scope.testBusinessObject.timeValue = new Date();
camForm.variableManager.createVariable({
name: 'testBusinessObject',
type: 'json',
value: $scope.testBusinessObject
});
camForm.variableManager.createVariable({
name: 'timeValue',
type: 'Date',
value: $scope.testBusinessObject.timeValue
});
} else {
// task form
// tell the form SDK to fetch the variables
variableManager.fetchVariable('testBusinessObject');
variableManager.fetchVariable('timeValue');
}
});
camForm.on('variables-fetched', function () {
if (camForm.taskId) {
// task form
taskService.get(camForm.taskId, function (err, task) {
// console.log(JSON.stringify(task));
switch (task.taskDefinitionKey) {
case "ut-task1":
// only visible for ut-task1
$scope.newTestForm.isPnAssigneeActionVisible = true;
$scope.newTestForm.isPnAssigneeActionDisabled = false;
$scope.newTestForm.isPnAssigneeActionOpen = true;
break;
default:
$scope.newTestForm.isPnAssigneeActionVisible = false;
$scope.newTestForm.isPnAssigneeActionDisabled = true;
$scope.newTestForm.isPnAssigneeActionOpen = false;
}
});
}
});
camForm.on('variables-restored', function() {
// work with the variable (bind it to the current angularJS $scope)
$scope.testBusinessObject = variableManager.variable('testBusinessObject').value;
});
camForm.on('submit', function() {
variableManager.variable('timeValue').value = $scope.testBusinessObject.timeValue;
});
}]);
</script>
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-heading" ng-click='newTestForm.isPnFormHeaderOpen = !newTestForm.isPnFormHeaderOpen'>
<h5 class="panel-title">
<span class="pull-right" ng-class="{'glyphicon glyphicon-menu-up':newTestForm.isPnFormHeaderOpen, 'glyphicon glyphicon-menu-down':!newTestForm.isPnFormHeaderOpen}" aria-hidden="true"></span>
Test Form
</h5>
</div>
<div class='panel-collapse collapse' ng-class="{'in' : newTestForm.isPnFormHeaderOpen}">
<div class="panel-body">
<fieldset>
<div class="form-group">
<div class="col-sm-12">
<label for="ctrTimeValue" class="control-label">Time Value</label>
<div id="ctrTimeValue" uib-timepicker
ng-model="testBusinessObject.timeValue"
ng-change="changed()" />
</div>
</div>
</fieldset>
</div>
</div>
</div>
<div class="panel panel-default" ng-if="newTestForm.isPnAssigneeActionVisible">
<div class="panel-heading">
<h4 class="panel-title">
<span class="pull-right" ng-class="{'glyphicon glyphicon-menu-up':newTestForm.isPnAssigneeActionOpen, 'glyphicon glyphicon-menu-down':!newTestForm.isPnAssigneeActionOpen}" aria-hidden="true"></span>
Assignee Action
</h4>
</div>
<div class='panel-collapse collapse' ng-class="{'in' : newTestForm.isPnAssigneeActionOpen}">
<div class="panel-body">
Assignee Action Details
</div>
</div>
</div>
</div>
Hi @hassang,
unfortunately the testBusinessObject is null
I used the html-form from the working example.
Any more ideas?
Thank you so much,
Nicole
Did you check the existence of the variable after form’s submission (from the cockpit app)?
May I know when you are trying to access the variable? Is it after form’s submission? or before?
Hi @NickiMueller,
Kindly find attached a working example with a task listener configured to be invoked on the complete event.
Attached is the HTML form (Notice: remove the .form
extension)
test-form.html.form (4.1 KB)
I checked it, it is not visible in cockpit.
After submission
@hassang, I will check this later, thank you!
Hi @hassang ,
all your examples work, if I execute them standalone. But if I try to embedd them in my application there is always something that goes wrong. The last example throws an exception like this:
Caused by: org.graalvm.polyglot.PolyglotException: TypeError: Cannot read property 'getValue' of null
I think about reading in the time with normal input fields with type String and then convert it into type Date/Time… dirty but I think I can not spend more time in the other way.
Thank you anyway for your input and help.
Have a good day,
Nicole