Showing different paragraphs using IF Fields

Hi,

I am trying to implement IF FIELDS in a Word template. I am trying to show on word block if a merge field equals to “yes” and another if not:

{IF “«MyField1»”=“yes”} {Photo
«Picture:MyPicture»}

{Justification (Insurance)

«MyField2»}

Is it possible? Or does this feature only allows to perform the IF on 2 MERGED FIELDS?

Thanks,
Omid.

Hi Omid,

Unfortunately, you cannot use images inside the IF field, the evaluation currently supports only simple IF expressions.

Also, the current content model doesn’t support block-level elements inside the Field element.

Note that we plan to address these two limitations in the future, but at the moment I’m afraid I cannot say when exactly that will be.

Regards,
Mario

Thanks Mario for your answer. I will then wait for until it is implemented because supporting picture and word blocks inside the IF block is really important for business apps.

Thanks,
Omid.

Hi Mario,

I really need to implement a feature in my product that relies on the ability of Gembox Document library to handle IF THEN clauses with a block inside the IF and the THEN clause. And the block should contain anything including picture of course.

I am surprised that none of your customers have ever needed this feature. Is is possible to include this feature in a short term release? Then I will upgrade my bundle.

Thanks a lot,
Omid.

Hi Omid,

Yes, this feature was requested, but I’m afraid that currently, we’re working on some other features with greater priority (more users requested them).

For now as a workaround, you could consider creating a merge range that would conditionally end up being removed. For example, you could have a single field inside the range that would be merged when your condition is true, and not merged when it is false. That way the MailMergeClearOptions.RemoveEmptyRanges would delete your range when needed.

I hope this helps.

Regards,
Mario

Hi Mario,

I need to generate a word document containing custom fields with HTML formatting and where I also need to remove empty merged field. I thus tested MailMergeClearOptions as you recommened.

But I am experiencing weird issue when using MailMergeClearOptions with some of the options.
When using: document.MailMerge.ClearOptions = MailMergeClearOptions.RemoveUnusedFields | MailMergeClearOptions.RemoveEmptyRanges my generated word document contains my HTML fields but didn’t remove the empty fields.

When I set ClearOptions with all the options, it removes my empty fields (which is good) but I also removes all the custom HTML fields content:
document.MailMerge.ClearOptions = MailMergeClearOptions.RemoveUnusedFields | MailMergeClearOptions.RemoveEmptyParagraphs | MailMergeClearOptions.RemoveEmptyRanges | MailMergeClearOptions.RemoveEmptyTableRows;

I also purchased the upgrade package so I use the latest binaries.

Is this a bug?
Thanks,
Omid.

Hi Omid,

Please send us a small Visual Studio project that reproduces your issue so that we can investigate it.

Regards,
Mario

Hi Mario,

Any hope the IF feature that allows to conditional display blocks of text, merged fields, pictures etc. be implemented in a future release? It’s really annoying that with such a powerful component as Gembox Document we can’t add complex conditional IF in the word template to show/hide a block.

Thanks.

Omidb you can achieve this by using MailMergeClearOptions.RemoveEmptyRanges as mentioned above.

Mario,

I already use this option but it doesn’t work as expected as I also mentioned before. Unfortunately I can’t send you my template as it is linked to my production code.
But if you have a working sample in C# I’ll be glad to test and enrich it with my test to see if it still works.
Thanks.

Omid, try something like this.

var document = DocumentModel.Load("input.docx");

document.MailMerge.FieldMerging += (sender, e) =>
{
    if (!e.IsValueFound || e.Value == null)
        return;

    if (e.FieldName == "Visible")
        e.Inline = (bool)e.Value ? new Run(e.Document, "") : null;
};

document.MailMerge.ClearOptions = MailMergeClearOptions.RemoveEmptyRanges;

document.MailMerge.Execute(
    new
    {
        Range1 = new { Visible = true },
        Range2 = new { Visible = false },
        Range3 = new { Visible = true },
    });

document.Save("output.docx");

The “input.docx” file contains conditional ranges that have merge fields named “Visible” somewhere (anywhere) within:

If the source doesn’t specify Visible data or if it is false, then the e.Inline will be null and thus the clear options will remove the range.

If the Visible data is true, then an empty Run element will replace the field (e.Inline will be set to empty Run) and the clear options won’t remove the range.

So, for the above given data source, the following is the result:

Last regarding the issue with the custom HTML fields that you previously mentioned, unfortunately, without reproducing your issue I’m not sure how I can help you with that.

Nevertheless, I’m guessing that perhaps the problem could be with the following.
If the mail merge customization for those custom HTML fields contains this:

e.Inline = null;

Try replacing that with this:

e.Inline = new Run(e.Document, "");

I hope this helps.

Regards,
Mario

Hi Mario,

Thanks for this detailed explanation. I’ll dig into it and see how It can help me fulfill my requirement.

Regards,
Omid.

Hi Mario,

Unfortunately you sample doesn’t allow me to implement my logic because all my data that I bind in document.MailMerge.Execute() is built dynamically. So if I want to add in the word document the equivalent of your “Range1” for example, I need to reuse a field in my collection.
Also, I emphasize that I call twice document.MailMerge.Execute():

  • First time like this:

document.MailMerge.Execute(data, null);

where data is a .NET DataSet that contains differents tables with rows that I bind to RangeStart/RangeEnd in the .docx.

  • Second time like:

document.MailMerge.Execute(expando)

where expando is a Dictionary<string, object> that contains simple type fields such as Firstname, Lastname, Age, etc.

Important: just before the second call, I set this:

document.MailMerge.ClearOptions = MailMergeClearOptions.RemoveUnusedFields | MailMergeClearOptions.RemoveEmptyRanges | MailMergeClearOptions.RemoveEmptyParagraphs | MailMergeClearOptions.RemoveEmptyTableRows;

In my case, adding a custom RangeStart that allows me to intercept the value (Visible in your example) seems not possible. For instance, I added something like this

{RangeStart:MyCustomProperty} {FirstName} {LastName} {RangeEnd:MyCustomProperty}

But MyCustomProperty is not present in e.MergeContext.RangeName maybe because the library seeks in the datasource I provided and finds nothing so it removes it from the range names collection.

Thanks.

You don’t need this approach for this case:

{RangeStart:MyCustomProperty} {FirstName} {LastName} {RangeEnd:MyCustomProperty}

That’s because the MailMergeClearOptions.RemoveEmptyParagraphs will end up removing this paragraph if both FirstName and LastName are not merged.

This approach is for when you have multiple paragraphs, paragraphs and tables, or any other arbitrary range that contains multiple block-level elements.

Anyway, for my previous example here is how you can use it with your expando source:

Dictionary<string, object> expando = new();
expando.Add("Range1", new KeyValuePair<string, object>("Visible", true));
expando.Add("Range2", new KeyValuePair<string, object>("Visible", false));
expando.Add("Range3", new KeyValuePair<string, object>("Visible", true));

I hope this helps.

If you need more, please create a small Visual Studio project that demonstrates what you have and specify what you would like to achieve.

Regards,
Mario