Knowledge found and lost while working with Microsoft Dynamics CRM
RSS icon Home icon
  • Changing a Checkbox Attribute’s Functionality

    Posted on April 20th, 2009 mitch Print Print 2 comments

    Each CRM Form field has an OnChange event associated with it that allows you ( the developer ) to execute JavaScript when the user changes the value of the attribute.  This event is fired when you change the attribute’s value and you leave the field – by clicking or using the Tab key.

    In certain instances, I have had bit attributes on the CRM Form which are formatted to display as a Checkbox.

    I would like the JavaScript added to the OnChange event to be executed immediately upon the user clicking the checkbox and changing the value. NOT when the user leaves the field.

    Using the following code, you can add that functionality:

    function ClickMe()
    {
      crmForm.all.new_checkboxfield.FireOnChange();
    }
     
    crmForm.all.new_checkboxfield.attachEvent('onclick',ClickMe, false);

    How It Works

    In the Form’s OnLoad event:

    1)I create a small JavaScript function called ClickMe that does nothing more than call the OnChange event for the bit attribute we’re working with.

    2) I use the JavaScript function attachEvent to attach the ClickMe function to the onclick event of the attribute.

    Once this code is published, any time the user clicks the checkbox, it will execute the OnChange code for the attribute.

    If you need to add this functionality to additional attributes, just duplicate the above code.

    Customization, Dynamics CRM, Unsupported
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    571 views
  • Adding a toolbar button to create new, related entities

    Posted on November 9th, 2007 mitch Print Print 10 comments

    [unsupported]

    One of my current projects has requirements to add toolbar buttons to allow the user to create a new, related Entity such as a phone call or appointment with a click of a button.

    Buttons are added to the toolbar by modifying the isv.config.xml and inserting code similar to the following:

    <Button
        Title="Phone Call"
        ToolTip="Create a phone call"
        Icon="/_imgs/ico_16_1071.gif"
        JavaScript="locAddRelatedTo(4210);"
    />

    I would like to point out the JavaScript function locAddRelatedTo().  This will open a new window containing a new CRM Entity.  The Entity being created is determined by the parameter passed to the function.  The parameter is the ID of the Entity in question.  In the above example, 4210 is the Entity ID for the Phone Call Activity.  Substitute any valid Entity ID to create a new built-in or custom Entity.

    Customization, Dynamics CRM, Unsupported
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    3,459 views
  • Understanding Entity Ownership in MSCRM 3.0

    Posted on February 18th, 2006 mitch Print Print 2 comments

    When you create a new Entity within MSCRM you have a choice to make regarding the ownership of that Entity.

    From the MSCRM 3.0 Help File:

    In the Ownership list, select either:

    • User
      Records for this entity can be owned by individual users. For example contact records are set to User.–   OR –
    • Organization
      Records for this entity are used for reference by all Microsoft CRM users, and so are not owned by individual users. For example, product records are set to Organization.

     

    While attending an MSCRM Troubleshooting class last week, I learned something that isn't readily apparant when you are creating enties:

    In order for a custom entity to be available to the CRM Workflow module, it must be created with an ownership of User.

    This was news to me, and unfortunately, unwelcome news. I had just created 12 custom Entities that had a combined total of over 100 Attributes and Relationships out the wazzoo. Since you can't change the Ownership type after creation, I was looking at spending a few hours deleting my existing Entities and recreating them from scratch. 

    And after thinking about it, I understand why the ownership requirement for workflow exists, I just wish it had been better documented.

    Anyway, I was thinking ( mustly hoping ) that there just had to be a way to alter the definition of the Entity without having to manually recreate it.  It turns out, there is, but it is a bit of work.

     

    The following information is provided as-is, without any warranty, either expressed or implied.

    It is probably unsupported by Microsoft as well.

    Use this information for reference and as a last-resort.  

     

    How Entities are Organized 

    With the exception of three Attributes, the tables of a User Owned Entity and an Organizational Owned Entity are exactly alike. The following table contains the Attributes created when you create both types of Entities. Those in bold are specific to that Ownership type.

    Organization Ownership User Ownership
    Name Type Name Type
    createdby lookup createdby lookup
    createdon datetime createdon datetime
    createdon datetime createdon datetime
    modifiedby lookup modifiedby lookup
    modifiedon datetime modifiedon datetime
    new_2blankoid primarykey new_2blankoid primarykey
    new_name nvarchar new_name nvarchar
    statecode state statecode state
    statuscode status statuscode status
    organizationid lookup ownerid owner
        owningbusinessunit lookup

    So, how do we convert an Entity from one ownership type to another as cleanly as possible and keeping the destruction to a minimum?  I've successfully performed the following steps and have seen no side effects.

    Step 1: Back up your CRM databases.

    Step 2: Export All Customizations.

    Even though you may only be working with one or two Entities, I feel it is best that all Entities be included in the export to ensure that we don't miss anything.

    Step 3: Make a backup copy of your exported customizations.

    Just in case your edits do not work as planned.

    Step 4: Delete the custom entity that needs to be reassigned Ownership.

    Sorry, there is just no way around this step. The Import Customizations process only adds data and changes, it will not delete anything, and we must delete attributes.  That means data loss.

    Step 5: Open the exported customizations in WordPad.

    Or whatever your favorite XML editor is.  Just remember how picky CRM 3.0 is about its XML format.  Personally, I use WordPad because it doesn't introduce additional line feed characters that so offend CRM.

    Note: Steps 6 – 8 will be repeated for each Entity that needs to be altered.

    Note 2: DO NOT attempt to copy the following XML from this blog and insert it into your CRM Export file. It will break the file and you will be unable to import it.  I would suggest Exporting a single Entity with User Ownership and have that open in a separate WordPad instance to copy the code from.

    Step 6: Change the ownership type.

    Find the following code: 

    <OwnershipTypeMask>OrgOwned</OwnershipTypeMask>
    And replace it with the following:

    <OwnershipTypeMask>UserOwned</OwnershipTypeMask>
     

    Step 7:  Remove the Organization Attributes and Insert the User Attributes

    DELETE THE FOLLOWING CODE

    <attribute PhysicalName="OrganizationId">
    <Type>lookup</Type>
    <ValidForReadApi>1</ValidForReadApi>
    <ReferencedEntityObjectTypeCode>1019
    </ReferencedEntityObjectTypeCode>
    <Description>Unique identifier for the organization</Description>
    </attribute>
    INSERT THE FOLLOWING CODE

    <attribute PhysicalName="OwnerId">
    <Type>owner</Type>
    <IsNullable>0</IsNullable>
    <ValidForCreateApi>1</ValidForCreateApi>
    <ValidForUpdateApi>1</ValidForUpdateApi>
    <ValidForReadApi>1</ValidForReadApi>
    <IsLogical>1</IsLogical>
    <DisplayMask>ValidForAdvancedFind|ValidForForm|ValidForGrid
    </DisplayMask>
    <Description>Owner Id</Description>
    </attribute>
    <attribute PhysicalName="OwnerIdDsc">
    <Type>int</Type>
    <IsNullable>0</IsNullable>
    <ValidForReadApi>1</ValidForReadApi>
    <IsLogical>1</IsLogical>
    <AttributeOf>OwnerId</AttributeOf>
    <XmlAbbreviation>dsc</XmlAbbreviation>
    <Description />
    </attribute>
    <attribute PhysicalName="OwnerIdName">
    <Type>nvarchar</Type>
    <Length>320</Length>
    <IsNullable>0</IsNullable>
    <ValidForReadApi>1</ValidForReadApi>
    <IsLogical>1</IsLogical>
    <AttributeOf>OwnerId</AttributeOf>
    <XmlAbbreviation>name</XmlAbbreviation>
    <IsSortAttribute>1</IsSortAttribute>
    <Description>Name of the owner</Description>
    </attribute>
    <attribute PhysicalName="OwnerIdType">
    <Type>int</Type>
    <ValidForCreateApi>1</ValidForCreateApi>
    <ValidForReadApi>1</ValidForReadApi>
    <IsLogical>1</IsLogical>
    <DisplayMask>ObjectTypeCode</DisplayMask>
    <AttributeOf>OwnerId</AttributeOf>
    <XmlAbbreviation>type</XmlAbbreviation>
    <Description>Owner Id Type</Description>
    </attribute>
    <attribute PhysicalName="OwningBusinessUnit">
    <Type>lookup</Type>
    <ValidForReadApi>1</ValidForReadApi>
    <ReferencedEntityObjectTypeCode>10
    </ReferencedEntityObjectTypeCode>
    <Description>Unique identifier for the business unit that owns the record</Description>
    </attribute>
    <attribute PhysicalName="OwningUser">
    <Type>lookup</Type>
    <ValidForCreateApi>1</ValidForCreateApi>
    <ValidForUpdateApi>1</ValidForUpdateApi>
    <ValidForReadApi>1</ValidForReadApi>
    <ReferencedEntityObjectTypeCode>8
    </ReferencedEntityObjectTypeCode>
    <AggregateOf>OwnerId</AggregateOf>
    <Description>Unique identifier for the user that owns the record.</Description>
    </attribute>
     

    Step 8: Change the form fields from Organization to User. 

    DELETE THE FOLLOWING

    <field name="organizationid" requiredlevel="na">
    <displaynames>
    <displayname description="Organization Id" languagecode="1033" />
    </displaynames>
    </field>
    INSERT THE FOLLOWING

    <field name="ownerid" requiredlevel="na">
    <displaynames>
    <displayname description="Owner" languagecode="1033" />
    </displaynames>
    </field>
    <field name="owningbusinessunit" requiredlevel="na">
    <displaynames>
    <displayname description="Owning Business Unit" languagecode="1033" />
    </displaynames>
    </field>

    Step 9: Save and close the Export file

    Step 10: Import the modified Exported customizations

    Step 11: Publish All Customizations

    Do this before you do anything else with the system as it will ensure that all of the data is completely replication throughout the CRM 3.0 system.

    Finished.

    Just to make sure everything is fine within the CRM 3.0 system, I perform the additional steps:

    Step 12: Add a temporary Attribute to the altered Entity.

    This is really just to make sure that the CRM Entity modification process still functions as expected.

    Step 13: Add that Attribute to the data entry Form.

    Step 14: Publish the Entity

    Step 15: Create and save a new record for the altered Entity.

    Step 16: Delete the temporary Attribute from the Entity.

    Step 17: Publish the Entity.

    Really Finished.

     

    Good luck and if you find any issues, please let me know.

     

    Customization, Dynamics CRM, Unsupported
    1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 4.50 out of 5)
    Loading ... Loading ...
    3,939 views
  • Researching MSCRM 3.0 Internals

    Posted on February 18th, 2006 mitch Print Print No comments

    In the Microsoft Business Solutions CRM Developer Newsgroup, Arne Janning gave an excellent suggestion for those of you with developer inclinations and a willingness to explore the MSCRM system to learn more about its inner-workings.

    Open Notepad and create a file that looks like this:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
      <ItemGroup>
        <Item Include="*/**" />
      </ItemGroup>
    </Project>
     
     

    Note: If you copy and paste the above text into notepad or VS2005, make sure the double-quotes are normal double-quotes and not the special "pretty" quotes. VS doesn't like the fancy quotes and will give you errors when you attempt to open the file.

    Save this with a .csproj extension in the root-folder of your MSCRM web site. Load Visual Studio 2005, select Open Project, navigate to the MSCRM web site then double-click on the .csproj file.Just don't do anything unwise like saving any of the files. We don't want to run the risk of upsetting CRM in any way – or damaging the files and rendering the site unusable.

    I also hope I don't need to state that it is a really bad idea to do this to a production server, do I?

     

    References:

    CRM Developer Newsgroup Post

     

     

    Customization, Dynamics CRM, Unsupported
    1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
    Loading ... Loading ...
    1,527 views
  • Including custom JavaScript files in MSCRM 3.0

    Posted on February 18th, 2006 mitch Print Print 6 comments

    The more you get into MSCRM development, the more you will probably realize that you are writing quite a bit of JavaScript to control various aspects of the CRM Client experience.  As most programmers find, the more code you write, the more you write code.  You also start developing a code library containing your most often used functions so that you don't have to rewrite them each time you need them.

    In most programming languages, the concept of an Include File exists. Include files are usually referenced at the beginning of your source code file and are merely instructions to your compiler, interpreter, or whatever, to include the contents of that file within your program. 

    This allows you to create a library of related sub-routines or functions that can be referenced from any number of other programs. Since you only have one copy of those routines, it cuts down on your maintenance requirements.

    So how does any of this relate to MSCRM?

    MSCRM version 3.0 gives you the ability to peform actions when the value of a form field changes – the OnChange Event.  This allows you to take action whenever a user changes a particular form.  Take a look at this example:

    The OnChange events for both Price and Quantity contain the following JavaScript code to automatically add the two fields together:

    crmForm.all.new_total.DataValue=
    crmForm.all.new_price.DataValue*
    crmForm.all.new_quantity.DataValue 

    This is really not very much code and there are really only two fields involved so it's pretty easy to maintain.  But, what happens if you have five or ten fields to calculate. That really becomes work at that point, and it can create a maintenance nightmare as well.

    You can solve this problem by putting the above JavaScript into a file on disk and include that file in the Form's OnLoad event.  Here's how it will work:

     

    Create the .js file:

    Open Notepad and copy the following Javascript into it

    function OrderFormAdd()
    {
       crmForm.all.new_total.DataValue=
       crmForm.all.new_price.DataValue*
       crmForm.all.new_quantity.DataValue 
    }

    Save this file as myfunctions.js and place it in a directory below your MSCRM web directory called myscripts.

     

    Reference your .js file:

    In the OnLoad event of your Form, include the following code: 

    var script = document.createElement('script');
    script.language = 'javascript';
    script.src = '/myscripts/myfunctions.js';
    document.getElementsByTagName('head')[0].appendChild(script);

     

    Update the OnChange Events:

    Now we need to update the OnChange events for the Price and Quantity fields. Remove the existing JavaScript and replace it with the following:

    OrderFormAdd();

     

    Save and publish your form and you are done.  From now on, any time you need to modify the calculation on the Order Form, just edit the myfunctions.js file. No additional work needs to be done to the CRM Form.

    Note:

    • If you make a change to the .js file and you don't see the change take effect, delete your browser's temporary Internet files and try it again. The client can cache the .js and it will be using the older copy instead of the newly updated master copy.

     

    Using Included Functions in the Form OnLoad Event:

    It was pointed out by "Alex" who wrote the actual JavaScript include code that it is possible to run into a timing issue because the include file has not yet finished appending to the CRM Form.  This is really only a problem if you need to access a function from your include file from within the OnLoad event.

    To circumvent this issue, we need to wait for the script's state to change to "loaded" before any functions in the include file can be accessed:

    var script = document.createElement('script');
    script.language = 'javascript';
    script.src = '/myscripts/myfunctions.js';
    document.getElementsByTagName('head')[0].appendChild(script);

    var f = function()
    {
      if (event.srcElement.readyState == "loaded")
       SomeFunction(); // some function from MyFunctions.js
    }

    script.attachEvent("onreadystatechange", f);

     

    Additional Notes:

    This solution will not work if you have the CRM 3.0 Outlook Laptop Client deployed. This is because the Laptop client utilizes a local Web server and if physically disconnected from the main CRM web server, the JavaScript file will be unavailable and a script error on the page will result.

    In addition, since the JavaScript file is not actually part of the CRM system, it is not replicated to the Laptop client during syncronization.

    Michaeljon Miller has a post discussing CRM SDK access while offline.

     

    References:

    The JavaScript code for this article was taken from a newsgroup conversation between Ronald Lemmen and "Alex."  Please consult the original thread for context.

    CRM Developer Newsgroup Post

    Using the CRM SDK offline

     

    Customization, Dynamics CRM, Unsupported
    1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 4.50 out of 5)
    Loading ... Loading ...
    7,537 views