Building selection lists in ASP pages without reference to Metadata

6 minute read time.
From time to time you will need to build pages that can not directly be based on a Meta data definition of a screen. For example if you need to construct a page that allows cloning of an entity or perhaps interaction with an external system. The CRM objects allow to you to easily build screens and entries that are unbound to underlying data structures.

The basic pattern of screen unbound to Meta data looks like this:
  1. Create screen
  2. Create field
  3. Set field properties
  4. Add field to screen
  5. Write block to web
  6. Handle save mode of screen
The following examples will take us through the building of a page that has a form and fields unbound to a record. The page will be in edit mode and when the page is 'saved' the data entered will be written back to the page to demonstrate the passing of unbound data.

The CRM.GetBlock() method allows you to create a block without reference to existing metadata. In the example (1) below you can see two 'block' types being referenced. The 'entrygroup' is the screen. The 'entry' is the field.

Example 1

var customScreenBlock = CRM.GetBlock('entrygroup');
var customTextEntryBlock = CRM.GetBlock('entry');


If we add a field that is unbound to meta data definitions then we will have to set all its relevant properties. The field is entry on an HTML form therefore it will need to know its type, name, length and any default value.

You will need to reference the description in the Developers guide for the eWareEntryBlock Object.

A basic text entry block might look like example (2)

Example 2

with (customTextEntryBlock)
{
EntryType = 10; //single line text entry
DefaultType = 1
DefaultValue = 'Hello World';
FieldName = 'custom_text'; //field name in HTML form
Caption = 'TextField:';
CaptionPos = CapTop; // CRM caption location constants defined in eWare.js file
maxLength = 60;
}


The EntryType and DefaultType differ from field type to field type. A date field might look like example (3).

Example 3

var customDateEntryBlock = CRM.GetBlock('entry');
with (customDateEntryBlock)
{
EntryType = 42; //Date Only
//EntryType = 41; //Date Time
DefaultType = 6; //Current Date
//DefaultType = 14; //Current Date plus 30
FieldName = 'custom_date'; //This names the field;
Caption = CRM.GetTrans('colnames','Comm_DateTime')+':'; //Translation for the column
CaptionPos = CapTop; // caption location constants defined in eWare.js file
NewLine = false;
}


EntryType then determines the nature of the field. There are a few types which are selection lists. The example (4) below shows how a user selection list can be built. Selection lists need to be 'sized' to control the drop down behaviour.

Example 4

var customUserEntryBlock = CRM.GetBlock('entry');
with(customUserEntryBlock)
{
EntryType = 22
FieldName = 'custom_userid'; //This names the field;
Caption = 'User:';
CaptionPos = CapTop; // caption location constants defined in eWare.js file
Size= 1;
NewLine = false;
}


This example (5) shows how a team selection list can be added.

Example 5

var customChannelEntryBlock = CRM.GetBlock('entry');
with(customChannelEntryBlock)
{
EntryType = 23;
Caption = CRM.GetTrans('ColNames','oppo_Channelid')+':'; //Translation for the column
CaptionPos = CapTop; // caption location constants defined in eWare.js file
FieldName = 'custom_channelid'; //This names the field;
AllowBlank = false
Size = 1;
NewLine = true;
}


The examples 4 & 5 show how the selection lists are created automatically using the existing user and team list behaviour. We can build selection lists that use existing pull down values very easily. In the example (6) below we might need to add a list of countries. This has been done by using the LookUpFamily property. The LookUpFamily is the translation capt_family that groups the selection values (capt_code) together.

Example 6

var customSelectionEntryBlock = CRM.GetBlock('entry');
with(customSelectionEntryBlock)
{
EntryType = 21 //Selection from Lookup
AllowBlank = true //Relevant when EntryType = 21, adds blank option to drop down list.
Caption = eWare.GetTrans('ColNames','addr_country')+':'; //Translation for the column
CaptionPos = CapTop; // eWare caption location constants defined in eWare.js file
//MultipleSelect = true; //can more than one value be selected?
FieldName = 'custom_country'; //This names the field;
LookUpFamily = "addr_country" //uses family for selection items.
RemoveLookup('UK') //removes list item from selection
Size = 1;
NewLine = false;
}


Selection however might need to be added into the system that are based on the application data held in the system rather that the meta data. For example a selection list referencing the marketing campaigns. The example (7) below shows how we can use the eWareRecord object to produce the list of data for the selection, and how the eWareEntryBlock can be used to position and control the field in the form. But it also shows that we will need to use custom HTML to assemble the custom selection list.

Note: Because we are forcing our own selection list into the field using the EntryBlock caption property we should take care to make the field ReadOnly.

Example 7

var customAppDataSelectionEntryBlock = CRM.GetBlock('entry');

var CustomField = ''
var CampaignRecords = CRM.FindRecord('campaigns','camp_deleted is null');
CampaignRecords.OrderBy = 'camp_name' //ASC and DESC can be used.
while (!CampaignRecords.eof) //eof checks for end of data and instantiates query
{
CustomField+=''+CampaignRecords.camp_name+''
CampaignRecords.NextRecord();
}
CustomField +='';

with(customAppDataSelectionEntryBlock)
{
ReadOnly = true; //see note above.
NewLine = false;
Caption = CRM.GetTrans('ColNames','Camp_Name')+':
'+CustomField
}


The form can be build by adding the entryblocks into the entrygroup as in the example(8) below:

Example 8

with(customScreenBlock)
{
Title='Custom Form';
AddBlock(customTextEntryBlock);
AddBlock(customDateEntryBlock);
AddBlock(customUserEntryBlock);
AddBlock(customChannelEntryBlock);
AddBlock(customSelectionEntryBlock);
AddBlock(customAppDataSelectionEntryBlock);
}


A form by default will be drawn in View mode. This is inappropriate for a form which is unbound to data and therefore does not have an existing associated record. We should have the form appear in edit mode using the switch code in the below example. The switch code would normally be placed towards the top of the ASP code. This will be shown in the completed example.

Example 9

if (CRM.Mode == View)
{
CRM.Mode = Edit;
}


The page is assembled and written using the code below in example 10. If this page had been bound to a record then the eWareRecord object would normally be passed into the Execute method of the EntryGroupBlock. This would then automatically handle the move from view, to edit, to save modes. We have already discussed how we need to start the form in Edit mode, but we also need to consider what happens when the 'Save' button is clicked. We will need to handle the submitted data when the form is changed to 'Save' mode.

The fields that we have added in the above example will be available in the standard ASP Form collection. They exist as name/value pairs using the name set by the EntryBlock's FieldName property.

Note: the selection list created in example 7 does not have its field name set using the FieldName property.

Example 10

CRM.AddContent(customScreenBlock.Execute());
Response.Write(CRM.GetPage()); //use default tab group

if (CRM.Mode == Save)
{
Response.Write('custom_text:='+Request.Form('custom_text')+'
');
Response.Write('custom_date:='+Request.Form('custom_date')+'
');
Response.Write('custom_userid:='+Request.Form('custom_userid')+'
');
Response.Write('custom_channelid:='+Request.Form('custom_channelid')+'
');
Response.Write('custom_country:='+Request.Form('custom_country')+'
');
Response.Write('custom_campaign:='+Request.Form('custom_campaign')+'
');
}

  • Jeff"¦

    I got this to work. At first I thought it was because you had this"¦

    var customScreenBlock = CRM.GetBlock('entrygroup');

    var customTextEntryBlock = CRM.GetBlock('entry');

    var customAppDataSelectionEntryBlock = CRM.GetBlock('entry');

    and I essentially had this"¦

    var customScreenBlock = CRM.GetBlock('entrygroup');

    var customTextEntryBlock = CRM.GetBlock('entry');

    So I added the additional line

    var customAppDataSelectionEntryBlock = CRM.GetBlock('entry');

    AND my blocks were not named exactly the same as yours, so I changed some of the names just to keep track of everything.

    Once I was done, my page worked.

    However, later I realized that var customTextEntryBlock = CRM.GetBlock('entry'); is not actually doing anything in your code example.

    I commented it out in your example your page still worked. So I commented it out in my page and my page still worked.

    So what I thought was this issue"¦wasn"Tmt really. Ultimately, I think I must have had a spelling issue in my original code that I resolved when I was changing my block names to match yours.

    Again..THANK YOU! For your assistance.

  • Jeff-

    Thank you! I will compare this to what I am doing and see if I am missing something.

    I appreciate your assistance....

  • Michele

    This does work in 7.2 and 7.3

    This is the full code I have just tested.

    if (CRM.Mode == View)

    {

    CRM.Mode = Edit;

    }

    var customScreenBlock = CRM.GetBlock('entrygroup');

    var customTextEntryBlock = CRM.GetBlock('entry');

    var customAppDataSelectionEntryBlock = CRM.GetBlock('entry');

    var CustomField = ''

    var CampaignRecords = CRM.FindRecord('campaigns','camp_deleted is null');

    CampaignRecords.OrderBy = 'camp_name' //ASC and DESC can be used.

    while (!CampaignRecords.eof) //eof checks for end of data and instantiates query

    {

    CustomField+=''+CampaignRecords.camp_name+''

    CampaignRecords.NextRecord();

    }

    CustomField +=''

    with(customAppDataSelectionEntryBlock)

    {

    ReadOnly = true; //see note above.

    NewLine = false;

    Caption = CRM.GetTrans('ColNames','Camp_Name')+':
    '+CustomField

    }

    with(customScreenBlock)

    {

    Title='Custom Form'

    AddBlock(customAppDataSelectionEntryBlock);

    }

    CRM.AddContent(customScreenBlock.Execute());

    Response.Write(CRM.GetPage()); //use default tab group

    if (CRM.Mode == Save)

    {

    Response.Write('custom_campaign:='+Request.Form('custom_campaign')+'
    ');

    }

  • Jeff...

    Does this still work in 7.2? I tried it and I am not getting it to work. I am going to go back and double check everything to see if I missed something or if I misspelled something. However, it occurred to me that perhaps this is done differently in 7.2.

    I am trying to create an ASP page with two text boxes without reference to Meta Data. Therefore, I am using example 1, example 2 and example 10. I know that I need to go back and add example 9 (switch view mode). I just get a blank screen in Sage CRM when I view it.

    Thank you for your assistance!

  • Jeff, I've tried adding a date time field EntryType = 41; //Date Time using your example above.

    When changing the time i get:

    An error has occurred in the script on the page.

    Unable to get the value of the property 'value': object is null or undefined

    My crm version is Version 7.1.f S is this normal behaviour?