Generated Fields in Data Type

Topics: General, Troubleshooting
Apr 18, 2011 at 9:00 AM

What's the best way to keep generated data fields in a data type.

For example in the following case:

Prefix (Can be empty)

FirstName

LastName

FullName (generated, not editable)

 

I was thinking that I would have a Function that updates a String Field that had no Widget, but I don't think that's possible. What's the best way to provide this functionality? Do I need to provide a completely separate function? In C#, I'd set a Property that had some very basic logic (Trimming the field if there's no Prefix, for example)

Coordinator
Apr 18, 2011 at 9:35 AM

The easiest way is to edit form markup:

  1. Click Edit Form Markup in the context menu of your datatype. 
  2. Under the <FieldGroup> element, locate the widget that's related to a generated field
  3. Delete the widget
  4. Save the markup.

 

The only "side effect" of this method is when you need to change widgets you would have to delete your "custom form markup", make your changes and that edit form markup and delete generated widgets once again.

I did it on a few sites - it works.

Apr 18, 2011 at 9:49 AM

And then to generate the Full Name, the function is inserted in this form... or would you subscribe to a listener in code?

Coordinator
Apr 18, 2011 at 10:59 AM

Usually I make a listener in App_Code, subscribe to "OnBeforeAdd" and  "OnBeforeUpdate" event and fill the generated field there.

http://docs.composite.net/C1/Data/DataFAQ.aspx?q=How+to+attach+events+to+Composite+C1+Data+Stores%3F

Apr 18, 2011 at 11:05 AM

If the "generated" field always consists of a well defined pattern of Prefix and Firstname and Lastname, isn't it better to not actually store the value for FullName but make a extension method that generates it at runtime when needed?

public static class MyExtensions
{
   public static string GetFullName(this IDataType data)
   {
      string fullName = String.Format("{0} {1}", data.FirstName.Trim(), data.LastName.Trim());

      if (!String.IsNullOrEmpty(data.Prefix)) 
      {
         fullName = fullName.Insert(0, data.Prefix +". ");
      }

       return fullName;
   }
}


var data = connection.Get<IDataType>().First();
var fullName = data.GetFullName();

Apr 21, 2011 at 5:24 AM
Edited Apr 21, 2011 at 6:07 AM

Thanks burning ice. I was thinking about it more and was thinking that I was going to do this in XSLT... via an XSLT extension method... but your method is something I'm much more comfortable with. Calling this C# function from the XSLT also shouldn't be a problem methinks.

Okay... so think I got it.

I added the function as an External C# Function. Except, that in order to use it in my XSLT Function, I needed to change it to a DataReference<IDataType>

 

See below:

namespace MyCompany {
    public class MyExtensions {
        public static string GetFullName( DataReference<MyCompany.Data.Author> author ) {
            
            string fullName = String.Format( "{0} {1}", author.Data.FirstName.Trim(), author.Data.LastName.Trim() );

            if (!String.IsNullOrWhiteSpace( author.Data.Prefix ))
                fullName = fullName.Insert( 0, author.Data.Prefix + " " );

            if (!String.IsNullOrWhiteSpace( author.Data.Suffix ))
                fullName = fullName + ", " + author.Data.Suffix;

            return fullName;
        }
    }
}

Then, I add the function by specifying MyCompany.MyExtensions as per here: http://docs.composite.net/C1/ASP-NET/CSharpFunctions.aspx/Creating-External-C-Functions

And then, I can add it as a Function in my AuthorBio XSLT Function. I use DataReference<Author> as an input parameter in that function which I pass to the function created.

Is there another way to do this, or am I going about this the wrong way?