Create a Workflow Template using a "start" expression to look the same way as a "gallery" view

Hello,

Is it possible to do something like this?
Use a “start” expression to create a workflow template that imitates a grid.

The intention is to reproduce a photo gallery on a pdf report.

Any thoughts?

Thanks

Solved Solved
0 27 2,177
1 ACCEPTED SOLUTION

It needs a nested table structure…

View solution in original post

27 REPLIES 27

I am not sure if this is responsive to your question, but you can do what is described in topic “Customer Template in Table Format” in this article https://help.appsheet.com/en/articles/2697047-sample-email-templates

Steve
Participant V

A very good question! Off the top of my head and even after a bit of thought, I can’t think of an easy way (or even a difficult way) to do what you want. I hope others chime in with some ideas!

Actually it should be doable. Are you able to show what kind of template you would like to have… for example how many images in one row. Then… how many images do you have in one record. Are these image fields required fields?

Sorry for the delay.
I would like to have a grid with 3 columns. For now, my records have one column for images.
But I can convert this table adding 3 requested image fields if this is what you are suggesting. Is it? What is your idea?

Hello,

I’ve made some complex template, can you link a photo, a document, or anything that shows what the final result has to look?

I believe the best option is if I make a small sample app

The result could be something like this. This is generated from child records where you have only one image column.

Though you can add headers as well like the Gallery view has…

This is exactly what I need!!! Can you please reveal the magic behind it, man? God bless you! hahahah

It needs a nested table structure…

Finally you found a trick! which should have been a long running mystery to find this type of tricks. I never come up with using MOD expression.

This is super awesome.

Quick question.

[_rownumber] field and its value is always adhere to the original table rather than “slice”.

For instance, let me explain simple case.

The table “image” looks like this

row number | image
1 | xvdsfsafdas.jpg
2 | fdsagasfas.jpg
3 | fgafasdfas.jpg
4 | htgafsddfsa.jpg
5 | dsafafdsa.jpg
6 | fffdsafafdsa.jpg
7 | fdsagasfada.jpg]

then the [related Images] ref fields should looks like this.

1 | xvdsfsafdas.jpg
3 | fgafasdfas.jpg
7 | fdsagasfada.jpg]

rather than,

1 | xvdsfsafdas.jpg
2 | fgafasdfas.jpg
3 | fdsagasfada.jpg]

What I mean is sliced, related table"s rownumber is not recalculated based on the slice condition, but inherit the row number from the original table.

On your demo case, we have 4 column, but I assume in the extreme case, we may have 2 images on the first column in the table, but none of images for the rest of 3 columns, based on the number of [_rownumber] being returned the slice (slice, in this case, is related rows based on ref.)

If the slice will be able to regenerate the new row number based on the selected number of the row, your template should perfectly work, what do you think?

Im just thinking of the trick @Suvrutt_Gurjar introduced to me before will add fuel to your trick to generate the serial number (alternative to row number) to run your trick more efficiently, although this is just based on impression, not testing anything at all.

At the end, the expressions will get bit expensive and heavy, but Im on the feeling that we could achieve the goal to display the multiple columns on template out of the multiple rows.

@Suvrutt_Gurjar
I invite your thoughts as well!

Looking forward to see you all response tomorrow, now time goes to bed…

@Aleksi

In this example I only wanted to show how you can generate the template using nested tables. Yes you are correct that it can happen that one column have all images. In this case you don’t need to have a virtual sequential number to avoid that. You would only need to know how many images to but in every column. Those groups you can read with a virtual column like…
LIST(
CEILING(COUNT([RELATED CHILDS])/4.0),
CEILING((COUNT([RELATED CHILDS])-1)/4.0),
CEILING((COUNT([RELATED CHILDS])-2)/4.0),
CEILING((COUNT([RELATED CHILDS])-3)/4.0)
)
and the result is for example like 3,3,2,2. Then you can use it for filtering directly in the template. The template could be like this.

As we can see, there are lot of ways how you can solve your challenges and that’s always interesting And I’m sure there is more clever way to do the same, but this was the first idea how to solve it.

Hi Aleksi,
Thank for sharing innovative ideas as always.
Inspired by your trick, I worked around with my own idea, employing dynamic rownumbers based on the slice (actually not a slice, but related child table rows), and use such a dynamic rownumber to dynamically assign to the template table with multiple column (my case was max 3 column rather than 4 in light of the width of the template which is portrait / A4 setting) together with MOD expression.

It is now perfectly working fine as well, although I took a bit different approach from yours, but ended up with the exactly same result, which is most important.

@tsuji_koichi and @aleksi,

Thank you for sharing some very innovative ideas. Very interesting solutions for "gallery " views in the reports.

As you can see, there are many ways as always

Not totally related but,

I use this kind of gallery template since long, but i stopped using it cause of this:

I never truly found an efficient and resilient way to generate an “index of the not empty column image”

I have 70 image columns !

It’s mandatory for my client to have an excel output with image next to others without empty cell.

Since i used Excel,

I solved it by creating an extra sheet where AppSheet output in a vertical manner every /image path file

then i used a macro to suppress all empty row, this do the job.

But do you know a way to do it directly inside Appsheet or inside << Template Expression >>

Anyway a big thank for the nested index tip.

Hi Aleksi, 
I follow your suggestions and it works really great !

But could you also advise how we can put the code so that it can displays the images in grid that are sorted by a column ? For example, sort by [LAST MODIFIED] column. Thank you.

kvngo94_0-1710334565160.png

 

Very elegant. Thank you!

Is it possible that what ever image column can be blank? No rule at all?

Yes,
Some image are mandatory but some are optional.

So i would say 30% column will be blank every time.

Can those images be like…
1,5
3,8
4,10

One option is to use IF: & EndIf formula. Template could be like…

@Aleksi I’m trying out an example of your same template but in word, and it doesn’t seem to want to work. Any ideas?

Error:
“DiagnosticFrameworkWrapper.CustomerFacingException: Request cancelled: took too long to process: Executing function batch: SELECT 70 of 148\r\n at Nirvana.Data.AppDataContext.CheckCancellation(String errorMessage) in d:\a\1\s\V2API\DataLayer\AppDataContext.cs:line 764\r\n at Jeenee.DataTypes.BuiltinFunction.RunBatch(Evaluatable funcExpressionEvaluatable, BatchDataContext batchDataContext, List1 children, BatchArguments batchArguments) in d:\\a\\1\\s\\DataTypes\\Expressions\\Functions\\FunctionRegistry.cs:line 80\r\n at Jeenee.DataTypes.BuiltinFunctionExpression.Evaluatable.runBatch(BatchDataContext batchDataContext, BatchArguments batchArguments) in d:\\a\\1\\s\\DataTypes\\Expressions\\FunctionExpression.cs:line 170\r\n at Jeenee.DataTypes.AppEvaluatable.RunBatch(BatchDataContext batchDataContext, BatchTrace batchTrace) in d:\\a\\1\\s\\DataTypes\\Expressions\\AppEvaluatable.cs:line 336\r\n at Nirvana.Data.DataLayer.GetComputedFieldValuesBatch(Context context, IDataContext dataContext, TableData tableData, SchemaField attr, Int32 col) in d:\\a\\1\\s\\V2API\\DataLayer\\VirtualColumns.cs:line 375\r\n at Nirvana.Data.DataLayer.GetComputedFieldValues(Context context, IDataContext dataContext, TableData tableData, SchemaField attr) in d:\\a\\1\\s\\V2API\\DataLayer\\VirtualColumns.cs:line 342\r\n at Nirvana.Data.DataLayer.AugmentVirtualColumns(Context context, TableData tableData, ItemSchema tableSchema, IEnumerable1 columns, IDataContext dataContext) in d:\a\1\s\V2API\DataLayer\VirtualColumns.cs:line 264\r\n at Nirvana.Data.AppDataContext.augmentDesiredVirtualColumns(TableDataCacheEntry tableDataCacheEntry, ItemSchema tableSchema, ICollection1 desiredColumnPositions, IDataContext dataContext) in d:\\a\\1\\s\\V2API\\DataLayer\\AppDataContext.cs:line 877\r\n at Nirvana.Data.AppDataContext.addColumnsIfNecessary(TableDataCacheEntry tableDataCacheEntry, String tableName, ItemSchema thisSchema, ICollection1 columnPositions, Boolean& addedColumns) in d:\a\1\s\V2API\DataLayer\AppDataContext.cs:line 891\r\n at Nirvana.Data.AppDataContext.GetRootTableDataFromCache(String tableName, ICollection1 columnPositions, Boolean& addedColumns) in d:\\a\\1\\s\\V2API\\DataLayer\\AppDataContext.cs:line 977\r\n at Nirvana.Data.AppDataContext.GetTableIndexFromCache(String tableName, ItemSchema tableSchema, ICollection1 keyColumnPositions, ICollection1 requiredVirtualColumns) in d:\\a\\1\\s\\V2API\\DataLayer\\AppDataContext.cs:line 1124\r\n at Nirvana.Data.AppDataContext.GetRowByKey(String tableName, String tableKeyValue, ICollection1 requiredVirtualColumns) in d:\a\1\s\V2API\DataLayer\AppDataContext.cs:line 701\r\n at Nirvana.Data.TemplateHtml.Replace(Context context, WorkflowTemplateBindContext bindContext, String tableName, Boolean compatibilityMode, Int32 columnSliceMapping, Change change, AppDataContext appDataContext, UpdateModeEnum updateMode, EmailExpressions emailExpressions, Templates templates, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\TemplateHtml\TemplateHtml.cs:line 74\r\n at Nirvana.Data.TemplateHtml.Replace(Context context, WorkflowTemplateBindContext bindContext, String tableName, Boolean compatibilityMode, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, EmailExpressions emailExpressions, Templates templates, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\TemplateHtml\TemplateHtml.cs:line 273\r\n at Nirvana.Data.Templates.Replace(Context context, WorkflowTemplateBindContext bindContext, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, EmailExpressions emailExpressions, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\TemplateCommon\Templates.cs:line 74\r\n at Nirvana.Data.WorkflowTemplate.Replace(Context context, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, EmailExpressions emailExpressions, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\WorkflowTemplate\WorkflowTemplate.cs:line 686\r\n at Nirvana.Data.WorkflowActionEmail.GetAttachment(Context context, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, EmailExpressions emailExpressions, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Action\WorkflowActionEmail.cs:line 228\r\n at Nirvana.Data.WorkflowActionEmail.Create(Context context, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, ActionDefinition actionDefinition, WorkflowLogEvent workflowLogEvent) in d:\a\1\s\V2API\Workflow\Action\WorkflowActionEmail.cs:line 49\r\n at Nirvana.Data.WorkflowRuleEvaluator.CreateActionResults(Context context, WorkflowActionBase workflowAction, AppTemplate appTemplate, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, WorkflowLogEvent workflowLogEvent) in d:\a\1\s\V2API\Workflow\Evaluators\WorkflowRuleEvaluator.cs:line 126\r\n at Nirvana.Data.WorkflowRuleEvaluator.PerformActions(Context context, AppTemplate appTemplate, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, WorkflowLogEvent workflowLogEvent) in d:\a\1\s\V2API\Workflow\Evaluators\WorkflowRuleEvaluator.cs:line 355\r\n at Nirvana.Data.WorkflowRuleEvaluator.ProcessRule(Context context, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode) in d:\a\1\s\V2API\Workflow\Evaluators\WorkflowRuleEvaluator.cs:line 492”

Esto es interesante....

Es posible utilizarlo para etiquetas postales de direcciones para hojas de etiquetas tamaño A4 y 2 etiquetas por fila y 8 filas???

Top Labels in this Space