Showing posts with label Form Control. Show all posts
Showing posts with label Form Control. Show all posts

Tuesday, 14 June 2011

CRM 2011: Get parent window attribute data, when opening from grid view.


Good day, fine people of the Internet.

A request was handed to me in my day to day work, which required some custom JavaScript work. Essentially, the requirement was for an onLoad event attached to a custom entity, this event must query the parent entity it was opened from, and depending on the result returned, sets the values of various fields on the form.

My custom entity has a relationship of N:1 with contact, however depending on the contact type (customer, supplier etc.) my custom entity will behave differently.

Through various research methods (Google) it seems the standard way to query an attribute on a parent window is to use..

window.parent.opener.Xrm.Page.getAttribute("Attribute_Name")
And to get the attribute’s value / data
window.parent.opener.Xrm.Page.getAttribute("Attribute_Name").getValue();

Great, Job done!!… errr…Not quite.

This scenario is ONLY suitable, when creating my new entity record from the navigation bar link, and hitting new.

For my scenario, I have a grid view on the contact entity, which lists the custom entity records. From here, I can click the grid, and add new record via the ribbon.
lo and behold, my page threw a tantrum along with an error.

After some debugging and a few moments rocking in the corner, I discovered the problem/solution

The problem:
window.parent.opener.Xrm.Page.getAttribute("Attribute_Name") Will not work when launching the entity from a grid view, because you cannot call the getAttribute method! ... WHY?
Because this a "short-cut" to the method used in standard form control, which does not exist when you open a record from a grid.

The solution:
Use this…

window.parent.opener.Xrm.Page.data.entity.attributes.get("Attribute_Name");
And to get the attribute’s value / data
window.parent.opener.Xrm.Page.data.entity.attributes.get("Attribute_Name").getValue();   

NOTE:
If you have a scenario where your record can be opened from both a grid AND the navigation area, this new method will not work for both, It’s only for grid launches.

My overall solution is to use both methods in my events, with a try/catch surrounding them.
Then, my remaining logic begins on whichever is successful.

Hope this helps you..
Craig Hamer

Tuesday, 11 January 2011

Javascript Button Making, with Style!

First Blog ever, HIGH FIVE!


Working with Dynamics CRM, you’ll inevitably need to add bespoke controls to custom or system entities in order to manipulate the data contained on a form. Here’s a example of one custom button I use which has a function of Inserting a generic signature once clicked.



Being fairly new to JavaScript, my initial attempts to add functionality like this to CRM 4 was somewhat ... "sickening" 
but after numerous attempts using what I've found on the CRM community forums, I've think I’ve now got the most efficient combination of the code so far, but more importantly, they now look like REAL buttons. 

Here’s my most recent method and coding for this.

First the basics



* Create a new attribute of type nvarchar (named Button1 to use in the code below)
* Add the field to your form wherever you want the button to be located.


The Code below can paste directly into the Form’s OnLoad event (making sure to tick “Event is enabled”) This converts the attribute to a functioning button. Rather than use a standard "light blue" background this variation ensures that it is styled in such a way that fits the rest of Dynamics CRM 4's UI.


I'm still new to Javascript, so forgive me if some of my habits aren't common place


The first section of script is the "ButtonScript" function will transform the nvarchar attribute to a Stylish CRM button with pretty gradients. Of course, you can update fields such as FontSize, FontFamily etc. however I find this combination gives best results.


The final few lines of "buttonScript" attach the preceeding events required for the nvarchar attribute to perform as a button (otherwise you'll get a pretty, yet useless, rectangle)



function buttonstyle(fieldname, buttontext, buttonwidth,clickevent)
            {
            functiontocall=clickevent;
            crmForm.all[fieldname].DataValue = buttontext;
            crmForm.all[fieldname].style.borderRight="#3366cc 1px solid";
            crmForm.all[fieldname].style.paddingRight="5px";
            crmForm.all[fieldname].style.borderTop="#3366cc 1px solid";
            crmForm.all[fieldname].style.paddingLeft="5px";
            crmForm.all[fieldname].style.fontSize="11px";
 //This is the important line below - it gives you the smooth gradient (rather than a blue button with no class)
            crmForm.all[fieldname].style.backgroundImage="url(/_imgs/btn_rest.gif)";
            crmForm.all[fieldname].style.borderLeft="#3366cc 1px solid";
            crmForm.all[fieldname].style.width=buttonwidth;
            crmForm.all[fieldname].style.cursor="pointer";
            crmForm.all[fieldname].style.lineHeight="18px";
            crmForm.all[fieldname].style.borderBottom="#3366cc 1px solid";
            crmForm.all[fieldname].style.backgroundRepeat="repeat-x";      
            crmForm.all[fieldname].style.fontFamily="Tahoma";
            crmForm.all[fieldname].style.height="20px";
            crmForm.all[fieldname].style.backgroundColor="#cee7ff";
            crmForm.all[fieldname].style.textAlign="center";
            crmForm.all[fieldname].style.overflow="hidden";
            crmForm.all[fieldname].attachEvent("onmousedown",push_button);
            crmForm.all[fieldname].attachEvent("onmouseup",release_button);
            crmForm.all[fieldname].attachEvent("onclick",functiontocall);
            crmForm.all[fieldname].attachEvent("onmouseover",over_button);
            crmForm.all[fieldname].attachEvent("onmouseleave",off_button);
            }
           
//Allignment Shift on Click, gives 3D effect        
//ON
function push_button()
            {
            window.event.srcElement.style.marginLeft="1px";
            window.event.srcElement.style.marginTop="1px";
            }
//OFF
function release_button()
            {
            window.event.srcElement.style.marginLeft="0px";
            window.event.srcElement.style.marginTop="0px";
            }
//Mouse over effect, changes image.
//ON
function over_button()
            {
            window.event.srcElement.style.backgroundImage="url(/_imgs/btn_on_lookup.gif')";
            }
//OFF
function off_button()
            {
            window.event.srcElement.style.backgroundImage="url(/_imgs/btn_rest.gif)";
            }

           
//Give the button something to do - e.g Alert something
function button1press() 
            {
            alert('You have Pushed my button');
            }

// Apply to Attribute
buttonstyle('button1','My buttons text','120px',Button1press);



In addition, If you're adding more buttons in the future, it's a simple matter of creating and publishing the new field like before, but now all you need to do is add your extra functions ie, 


function button2press() {'Do something'}
function butto3press() {'Do something else'}
...


and call the same "ButtonStyle"  function to each, ie


buttonstyle('button2','My Second button text','120px',Button2press);
buttonstyle('button3','My Third button text','120px',Button3press);


your buttons will maintain consistency, which makes the UI easier to work with once you start adding more and more. Also, Any updates to the main styling will apply to all buttons on the form (Very handy when it comes to tweaking your work!)


All Comments welcome, but be nice! I'm new to this.
Craig Hamer