This is a migrated thread and some comments may be shown as answers.

Delete Empty Merge Fields

1 Answer 99 Views
RichTextBox
This is a migrated thread and some comments may be shown as answers.
Steve
Top achievements
Rank 1
Steve asked on 12 Mar 2015, 01:02 PM
Hi,

I would like to be able to either not insert a custom merge field document fragment if the result is empty or iterate over the document merge fields and delete empty ones.

I have a custom merge field as follows:
public class CustomMergeField : MergeField
    {
        public const string CustomFieldName = "MATCustomField";
 
        static CustomMergeField()
        {
            CodeBasedFieldFactory.RegisterFieldType(CustomMergeField.CustomFieldName, () =>
            {
                return new CustomMergeField();
            });
        }
 
        public override string FieldTypeName
        {
            get
            {
                return CustomMergeField.CustomFieldName;
            }
        }
 
        public override Field CreateInstance()
        {
            return new CustomMergeField();
        }
 
        public bool ResultFragmentEmpty
        {
            get { return base.IsResultFragmentEmpty(); }
        }
        protected override DocumentFragment GetResultFragment()
        {
            var d = this.Document.MailMergeDataSource.CurrentItem as Dictionary<string, Object>;
            if (d == null)
            {
                return this.CreateFragmentFromText(this.FieldCode);
            }
            else
            {
                if (d.ContainsKey(this.PropertyPath))
                {
                    var f = d[this.PropertyPath] as DGField;
                    if (f != null && f.Data != null)
                    {
                        switch (f.DataType)
                        {
                            case DGField.DataTypeOptions.String:
                                {
                                    var DataString = f.Data.ToString();
                                    //DataString = DataString.Replace(Environment.NewLine, FormattingSymbolLayoutBox.LINE_BREAK); //"¬""¶"
                                    if (DataString.Contains(Environment.NewLine))
                                    {
                                        var lines = DataString.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
                                         
                                        RadDocumentEditor editor = new RadDocumentEditor(new RadDocument());
                                        editor.ChangeParagraphLineSpacing(1.15);
                                        for (int i = 0; i < lines.Length; i++)
                                        {
                                            editor.Insert(lines[i]);
                                            if (i < lines.Length - 1)
                                            {
                                                editor.Insert(Environment.NewLine);
                                            }
                                        }
 
                                        return new DocumentFragment(editor.Document);
                                    }
 
                                    return this.CreateFragmentFromText(DataString);
                                }
                            case DGField.DataTypeOptions.Date:
                                {
                                    if (f.SchemaName == "General.DateNow")
                                    {
                                        return this.CreateFragmentFromText(DateTime.Now.ToShortDateString());
                                    }
                                    else if (f.SchemaName == "General.DateNowLongFormat")
                                    {
                                        return this.CreateFragmentFromText(DateTime.Now.ToLongDateString());
                                    }
                                    if (f.SchemaName.Contains("LongFormat"))
                                    {
                                        return this.CreateFragmentFromText(((DateTime)f.Data).ToLongDateString());
                                    }
                                    return this.CreateFragmentFromText(((DateTime)f.Data).ToShortDateString());
                                }
                            case DGField.DataTypeOptions.Currency:
                                {
                                    string CurrencySymbol;
                                    int CurrencyPrecision;
                                    if (d.ContainsKey("currency.currencysymbol"))
                                    {
                                        CurrencySymbol = ((DGField)d["currency.currencysymbol"]).Data.ToString();
                                    }
                                    else
                                    {
                                        CurrencySymbol = "£";
                                    }
 
                                    if (d.ContainsKey("currency.currencyprecision"))
                                    {
                                        CurrencyPrecision = (int)((DGField)d["currency.currencyprecision"]).Data;
                                    }
                                    else
                                    {
                                        CurrencyPrecision = 2;
                                    }
                                    return this.CreateFragmentFromText(Formatting.Currency.DecimalToCurrency(Convert.ToDecimal(((Money)f.Data).Value), CurrencyPrecision, CurrencySymbol));
                                }
                            case DGField.DataTypeOptions.Lookup:
                                return this.CreateFragmentFromText(((EntityReference)f.Data).Name);
                            default:
                                return this.CreateFragmentFromText(f.Data.ToString());
                        }
                    }
                    else
                    {
                        return this.CreateFragmentFromText(string.Empty);
                    }
                }
                else
                {
                    //return null;
                    return this.CreateFragmentFromText(string.Empty);
                }
            }
        }
    }

If the data passed in is empty then ideally I want nothing to be inserted in the document because it leaves white space and in some places a blank line.

Also your examples if using the TextAfterIfNotEmpty doesn't work as the ¬ symbol just appears as that in my documents. You can see above I have had to comment this symbol out as it just appears inline with the fields all on one line.

I have tried the following method to delete merge fields which are empty but nothing happens.

private void ClearBlankFields(object parameter)
        {
            var fields = this.View.radRichTextBox.Document.EnumerateChildrenOfType<FieldRangeStart>().Where(x => x.EnumerateChildrenOfType<FieldRangeStart>().Any(f => f.Field is CustomMergeField));
            foreach (var f in fields)
            {
                if (((CustomMergeField)f.Field).ResultFragmentEmpty)
                {
                    f.Parent.Children.Remove(f);
                }
            }
        }

It does not throw an exception but the field is still present.

Thanks for your help

1 Answer, 1 is accepted

Sort by
0
Tanya
Telerik team
answered on 16 Mar 2015, 03:39 PM
Hello Steve,

In order to achieve this behavior you could iterate through all merge fields in result mode, select them and check if the selection contains text. If the field is empty, the selection can be used to delete the whole field. In the snippet below is demonstrated how exactly this could be implemented:
this.editor.Document.FieldsDisplayMode = FieldDisplayMode.Result;
var fields = this.editor.Document.GetAnnotationMarkersOfType<FieldRangeStart>().ToList();
 
for (int i = 0; i < fields.Count(); i++)
{
    if (fields[i].Field is MergeField && (fields[i].Field as MergeField).DisplayMode == FieldDisplayMode.Result)
    {
        this.editor.Document.CaretPosition.MoveToStartOfDocumentElement(fields[i]);
        DocumentPosition start = new DocumentPosition(this.editor.Document.CaretPosition);
        this.editor.Document.CaretPosition.MoveToStartOfDocumentElement(fields[i].End);
        DocumentPosition end = new DocumentPosition(this.editor.Document.CaretPosition);
 
        this.editor.Document.Selection.SetSelectionStart(start);
        this.editor.Document.Selection.AddSelectionEnd(end);
 
        string value = this.editor.Document.Selection.GetSelectedText();
 
        if (string.IsNullOrEmpty(value))
        {
            this.editor.Delete(false);
        }
    }
}

Please, let me know if you have any other questions.

Regards,
Tanya
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
RichTextBox
Asked by
Steve
Top achievements
Rank 1
Answers by
Tanya
Telerik team
Share this question
or