Questions and discussion about using ProcessMaker: user interface, running cases & functionality

Moderator: amosbatto

By atuly7
#794521
Hi,
I am using community edition 3.1.2(bitnami)
I just want to know can I show uploaded excel file in panel? and Can I show that panel data in generated output document?
If yes then how?
This is file uploaded by user.
(280 Bytes) Downloaded 126 times
I want to show that file like this.
13.png
13.png (18.31 KiB) Viewed 2183 times
I refered this post but it shows data in grid. I want to show file in panel as shown in above image.
viewtopic.php?f=41&t=710297

And If I get this process, it will very helpful for me.
viewtopic.php?t=709615

Thanks & Regards
User avatar
By amosbatto
#794726
This one took me a while to figure out.
First, create a DynaForm like this:
DynaFormToUploadCsvFile.png
DynaFormToUploadCsvFile.png (75.65 KiB) Viewed 2158 times
Where there are the following fields:
1. Multiple File with ID "cvsFiles" associated with varaible "csvFiles"
2. Submit Button with ID "showContents"
3. Panel with ID "csvPanel" which has the content:
Code: Select all
<table id="csvTable" class="display" width="100%"></table>
4. Submit Button with ID "submit"
5. Hidden field with ID "action"
6. Hidden field with ID "csvData"

Second, add the dataTables library to the DynaForm. In the external libs property of the DynaForm, add:
Code: Select all
https://cdn.datatables.net/1.10.9/js/jquery.dataTables.min.js, https://cdn.datatables.net/1.10.9/css/jquery.dataTables.min.css
Third, add the following JavaScript code to the DynaForm:
Code: Select all
$("#showContents").find("button").click(function() {
   $("#action").setValue("SHOW_CONTENTS");
});

$("#submit").find("button").click(function() {
   $("#action").setValue("");
});

var sData = $("#csvData").getValue();

if (sData == '') {
  $("#csvPanel").hide();
}
else {
  var aData = JSON.parse(sData);
  if (typeof aData != "object" || aData.length < 1) {
    alert("Invalid or empty CSV file");
  }
  else {
    var aHeader = aData.shift();
    var aColumns = [];
    
    for (i in aHeader) {
      aColumns.push( {"title": aHeader[i]} );
    }
    
    $('#csvTable').DataTable( {
        data: aData,
        columns: aColumns
    } );
  }
}
Then, create the following trigger in the process:
Code: Select all
//set to the unique ID of the DynaForm:
$formId = '12208547059961e691679c6060409756';

//possible CSV file types in MIME:
$aMimeCsv = array(
  'text/plain',
  'application/vnd.ms-excel',
  'text/x-csv',
  'application/csv',
  'application/x-csv', 
  'text/csv',
  'text/comma-separated-values',
  'text/x-comma-separated-values',
  'text/tab-separated-values'
);
$g = new G();

if (isset(@@action) and @@action == 'SHOW_CONTENTS') {
	@=csvData = '';
	$aRows = array();
	
	if (!isset(@=csvFiles) or empty(@=csvFiles)) {
		$g->SendMessageText('Please upload a comma-separated-value (CSV) file to display its contents.', 'INFO');
		PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
	}
	
	//construct path to the stored file in the server's file system:
	$filename = @=csvFiles[0]['name'];
	$ext = pathinfo($filename, PATHINFO_EXTENSION);
	$path = PATH_DOCUMENT . $g->getPathFromUID(@@APPLICATION) . PATH_SEP . 
		@=csvFiles[0]['appDocUid'] . '_' . @=csvFiles[0]['version'] . '.' . $ext;

	$finfo = new finfo();
	$fileMimeType = $finfo->file($path, FILEINFO_MIME_TYPE);	

	if (!in_array($fileMimeType, $aMimeCsv)) {
		$g->SendMessageText("File '$filename' is not a comma-separated-value file. ".
			"Please upload a CSV file.", "WARNING");
		$d = new AppDocument();
		$d->remove(@=csvFiles[0]['appDocUid'], @=csvFiles[0]['version']);
		unset(@=csvFiles);
		PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
	}
	
	ini_set('auto_detect_line_endings',TRUE);
	if (($fHandle = fopen($path, "r")) == false) {
		$g->SendMessageText("Unable to open file $path for reading. Please delete it and try again.", "ERROR");
		PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
	}
	
	//In first line figure out whether ',' or ';' used as the delimiter between data
	$delimiter = ','; 
	if (($aData = fgetcsv($fHandle, 0, $delimiter)) == false) {
		$g->SendMessageText("File '$filename' is empty. Upload another file.", "WARNING");
		$d = new AppDocument();
		$d->remove(@=csvFiles[0]['appDocUid'], @=csvFiles[0]['version']);
		unset(@=csvFiles);
		PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
	}
	if (count($aData) == 1) {
		$delimiter = ';';
		rewind($fHandle);
		$aData = fgetcsv($fHandle, 0, $delimiter);
	}
	
	$aRows[] = $aData;
	
	while (($aData = fgetcsv($fHandle, 0, $delimiter)) !== false) {
        $aRows[] = $aData;
	}	
    
	@=csvData = json_encode($aRows);
    fclose($fHandle);
	PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
}
Set this trigger to fire before the step following the DynaForm to upload a CSV file (or before assignment if the last step in the task). The trigger should NOT be fired immediately after the DynaForm, because at that point the CSV file will not yet be saved to the database or the server's file system.

This trigger will use PMFRedirectToStep() to return to the same DynaForm and display the contents of the CSV file in the panel. It will not allow the contents of the file to be changed. If needing to allow the user to change the contents, use a grid instead of a panel.

Then, run a case and select a CSV file to upload.
SelectCsvFileBeforeDisplaying.png
SelectCsvFileBeforeDisplaying.png (9.99 KiB) Viewed 2158 times
If the user clicks on the "Submit" button then the case will continue to the next step in the task, but if the user clicks on the "Show Contents" button, then the subsequent trigger will open the CSV file and place its contents in an array which is serialized as a JSON string in the csvData variable. Finally, the trigger calls PMFRedirectToStep() to redisplay the same DynaForm, with the contents of the CSV file shown in the panel below.
CsvFileDisplayedInPanel.png
CsvFileDisplayedInPanel.png (34.88 KiB) Viewed 2158 times
To try out a sample process containing this code, download and import the following process:
(31.23 KiB) Downloaded 222 times
Note: This code will not work in the ProcessMaker Mobile App, because it doesn't support PMFRedirectToStep(). If needing to display other types of spreadsheet files (Excel, OpenDocument Spreadsheet, etc.) in the panel, then the PHPExcel library can be imported into the trigger and used to open other types of spreadsheets as shown in this example.
By azatrath
#822754
amosbatto wrote: Mon Aug 21, 2017 5:44 pm This one took me a while to figure out.
First, create a DynaForm like this:
DynaFormToUploadCsvFile.png
Where there are the following fields:
1. Multiple File with ID "cvsFiles" associated with varaible "csvFiles"
2. Submit Button with ID "showContents"
3. Panel with ID "csvPanel" which has the content:
Code: Select all
<table id="csvTable" class="display" width="100%"></table>
4. Submit Button with ID "submit"
5. Hidden field with ID "action"
6. Hidden field with ID "csvData"

Second, add the dataTables library to the DynaForm. In the external libs property of the DynaForm, add:
Code: Select all
https://cdn.datatables.net/1.10.9/js/jquery.dataTables.min.js, https://cdn.datatables.net/1.10.9/css/jquery.dataTables.min.css
Third, add the following JavaScript code to the DynaForm:
Code: Select all
$("#showContents").find("button").click(function() {
   $("#action").setValue("SHOW_CONTENTS");
});

$("#submit").find("button").click(function() {
   $("#action").setValue("");
});

var sData = $("#csvData").getValue();

if (sData == '') {
  $("#csvPanel").hide();
}
else {
  var aData = JSON.parse(sData);
  if (typeof aData != "object" || aData.length < 1) {
    alert("Invalid or empty CSV file");
  }
  else {
    var aHeader = aData.shift();
    var aColumns = [];
    
    for (i in aHeader) {
      aColumns.push( {"title": aHeader[i]} );
    }
    
    $('#csvTable').DataTable( {
        data: aData,
        columns: aColumns
    } );
  }
}
Then, create the following trigger in the process:
Code: Select all
//set to the unique ID of the DynaForm:
$formId = '12208547059961e691679c6060409756';

//possible CSV file types in MIME:
$aMimeCsv = array(
  'text/plain',
  'application/vnd.ms-excel',
  'text/x-csv',
  'application/csv',
  'application/x-csv', 
  'text/csv',
  'text/comma-separated-values',
  'text/x-comma-separated-values',
  'text/tab-separated-values'
);
$g = new G();

if (isset(@@action) and @@action == 'SHOW_CONTENTS') {
	@=csvData = '';
	$aRows = array();
	
	if (!isset(@=csvFiles) or empty(@=csvFiles)) {
		$g->SendMessageText('Please upload a comma-separated-value (CSV) file to display its contents.', 'INFO');
		PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
	}
	
	//construct path to the stored file in the server's file system:
	$filename = @=csvFiles[0]['name'];
	$ext = pathinfo($filename, PATHINFO_EXTENSION);
	$path = PATH_DOCUMENT . $g->getPathFromUID(@@APPLICATION) . PATH_SEP . 
		@=csvFiles[0]['appDocUid'] . '_' . @=csvFiles[0]['version'] . '.' . $ext;

	$finfo = new finfo();
	$fileMimeType = $finfo->file($path, FILEINFO_MIME_TYPE);	

	if (!in_array($fileMimeType, $aMimeCsv)) {
		$g->SendMessageText("File '$filename' is not a comma-separated-value file. ".
			"Please upload a CSV file.", "WARNING");
		$d = new AppDocument();
		$d->remove(@=csvFiles[0]['appDocUid'], @=csvFiles[0]['version']);
		unset(@=csvFiles);
		PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
	}
	
	ini_set('auto_detect_line_endings',TRUE);
	if (($fHandle = fopen($path, "r")) == false) {
		$g->SendMessageText("Unable to open file $path for reading. Please delete it and try again.", "ERROR");
		PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
	}
	
	//In first line figure out whether ',' or ';' used as the delimiter between data
	$delimiter = ','; 
	if (($aData = fgetcsv($fHandle, 0, $delimiter)) == false) {
		$g->SendMessageText("File '$filename' is empty. Upload another file.", "WARNING");
		$d = new AppDocument();
		$d->remove(@=csvFiles[0]['appDocUid'], @=csvFiles[0]['version']);
		unset(@=csvFiles);
		PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
	}
	if (count($aData) == 1) {
		$delimiter = ';';
		rewind($fHandle);
		$aData = fgetcsv($fHandle, 0, $delimiter);
	}
	
	$aRows[] = $aData;
	
	while (($aData = fgetcsv($fHandle, 0, $delimiter)) !== false) {
        $aRows[] = $aData;
	}	
    
	@=csvData = json_encode($aRows);
    fclose($fHandle);
	PMFRedirectToStep(@@APPLICATION, @%INDEX, 'DYNAFORM', $formId);
}
Set this trigger to fire before the step following the DynaForm to upload a CSV file (or before assignment if the last step in the task). The trigger should NOT be fired immediately after the DynaForm, because at that point the CSV file will not yet be saved to the database or the server's file system.

This trigger will use PMFRedirectToStep() to return to the same DynaForm and display the contents of the CSV file in the panel. It will not allow the contents of the file to be changed. If needing to allow the user to change the contents, use a grid instead of a panel.

Then, run a case and select a CSV file to upload.
SelectCsvFileBeforeDisplaying.png
If the user clicks on the "Submit" button then the case will continue to the next step in the task, but if the user clicks on the "Show Contents" button, then the subsequent trigger will open the CSV file and place its contents in an array which is serialized as a JSON string in the csvData variable. Finally, the trigger calls PMFRedirectToStep() to redisplay the same DynaForm, with the contents of the CSV file shown in the panel below.
CsvFileDisplayedInPanel.png
To try out a sample process containing this code, download and import the following process:
Display_CSV_File-1.pmx
Note: This code will not work in the ProcessMaker Mobile App, because it doesn't support PMFRedirectToStep(). If needing to display other types of spreadsheet files (Excel, OpenDocument Spreadsheet, etc.) in the panel, then the PHPExcel library can be imported into the trigger and used to open other types of spreadsheets as shown in this example.


amos you really did good example for us, but there is something not right. i uploaded a CSV file and clicked Show Contents, it gave me and empty sheet that you may check at the image.
Ekran Alıntısı.PNG
Ekran Alıntısı.PNG (47.8 KiB) Viewed 1053 times
User avatar
By amosbatto
#822775
Azatrath,
I just tried the process in version 3.3.0 Community (manual install in Debian 9.5 with PHP 5.6.37) and it is able to display CSV files without any problems:
showClientsInDynaform.png
showClientsInDynaform.png (54.35 KiB) Viewed 1044 times
To test this, I created a plain text file named "clients.csv" with the following content:
Code: Select all
ID; First Name; Last Name; Telephone Number; Email Address
34; Billy; Boggs; 784-762-8123; [email protected]
587; Jane; Row; 654-183-2831; [email protected]
847; Sally; Swain; 813-374-7234; [email protected]
7436; John; Johnson; 173-283-8347; [email protected]
If you are seeing something different, what is your environment?

PS: If you are trying to use PhpExcel, it is no longer supported:
"The project has not be maintained for years and must not be used anymore. All users must migrate to its direct successor PhpSpreadsheet, or another alternative."

Hi, In order to delete a case you can follow the[…]

Hi. Have you tried to use JavaScript on your Dyn[…]

Hi Please, could you send information about the c[…]

Dashboard issue

Can you show me what you were trying to do in orde[…]