4

I tried to execute the following command from the console.

var subject = Xrm.Page.ui.controls.get("subject");

That's the exact syntax I'm using in the web resource that I'm plugging in to CRM. However, I only got an error message saying that "unable to get property 'controls' of undefined or null reference".

I do understand the message. What I want to know is two-fold.

  1. What syntax will work from the console (F12) to refer to the stuff on the screen?
  2. Why doesn't it work the way I did? Where doesn ui come from?

I've checked that I can refer to both Xrm and Crm.Page but apparently ui is null (it's listed when I print out the contents of Page but sett to null).

  • Is your command code wrapped inside a JS function? Because otherwise `Xrm.Page.ui` will always be interpreted as null or not an object, as it is in your case. – amartine Jan 06 '13 at 14:19
  • Can you please explain why that is the case? Xrm is a variable accessible from the console - why does wrapping the call in a function make a difference? Thanks! – Ryan Nov 12 '14 at 06:45
  • 4
    @Ryan I believe he's mistaken or that he misunderstood the question. There's a whole bunch *Xrm* and *Xrm.Page* all over the DOM. But the one that's targeting what one sees is accessed by adding *frames[0]* in front of it (when trying from the console, not from a web resource). Annoyance of the stronger degree... – Konrad Viltersten Nov 13 '14 at 12:51
  • That is extremely useful! Thanks a lot. I don't understand why the frames[0] is required or why it helps though. – Ryan Nov 14 '14 at 04:44
  • I'm not entirely certain but it might have to do with the fact that the application is run in one of these frames, although one doesn't see it. I guess you might try to register **two different** organizations, access them both in the same browser, same window or maybe different browsers or something and check if they might get *frames[0]*, *frames[1]* etc. When CRM talks to it's own controls, it **knows** which instance it is and it can't access another organization. But when console window makes the call, the reference becomes ambiguous. Maybe. Go and check - get back to us and tell. :) – Konrad Viltersten Nov 14 '14 at 15:45

5 Answers5

13

I know this is a kinda old thread, but if you still getting that 'object doesn't support property..' error when executing the command from console, IE F12; try calling it from the frame i.e

frames[0].Xrm.Page.getAttribute("controlId").getValue();

In CRM 2013 it is a little different

frames[1].Xrm.Page
Lazaro Gonzalez
  • 121
  • 1
  • 6
meh
  • 129
  • 1
  • 6
  • You're mistaken. I'm sitting with CRM 2013 right now and it's still *frames[0]*. However, you might want to read the comment I made above. Maybe that's what's happening on your computer? Would be cool to know for once. – Konrad Viltersten Nov 14 '14 at 15:47
  • @lazarogonzales Actually, I have to add that I might have been partly mistaken too. There seems to be a difference between *frames[index]* part between 2011 and 2013 **but also** between on-premises and on-line (and I wouldn't be chocked if the difference varies prior/post updates, rollups and lifts to 2015). Good hint! – Konrad Viltersten Nov 28 '14 at 12:23
  • frames[0] works for me using CRM 2015 Update 0.1 on premise, Chrome 46.0.2490.80 – Tim Partridge Nov 06 '15 at 15:44
  • `Frames[0]` is MONEY! I used to try to debug within some random JS file on the page. It was *always* hard to find one that worked. This lets you enter it right into the console. – AlbatrossCafe Nov 17 '16 at 21:14
3

It's kind of tough to detect the frames across different browsers, so this little javascript can help you out:

for(var i=0;i<5;i++) //loop through 0 to 4
    if(frames[i].Xrm.Page.ui != undefined) //check if undefined    
    {
        Xrm = frames[i].Xrm;  //assign Xrm
        console.info("~: Xrm updated with frame " + i + " :~"); //show info
        break; //breakout the loop
    }

What it does ?

What it's basically doing is to loop through 0-5 to find frame where Xrm.Page.ui is not undefined, once it gets it it assigns it to the Xrm and breaks the loop.

How to use ?

To use it just copy/paste and run in the browser console once per session then after you can run/test all your Xrm codes form the browser console.

Vinod Srivastav
  • 3,644
  • 1
  • 27
  • 40
  • You might consider a bit different syntax in the conditional. First of all, I'd spontaneously try to avoid `!=` if possible and go for `!==`. Secondly, I believe that you could use `if(!frames[i].Xrm.Page.ui)` only. Thirdly, I believe that this could be a part of the condition on the for loop minimizing the number of lines all together. :) – Konrad Viltersten May 02 '17 at 13:04
  • Yup, modifications are possible but **if(!frames[i].Xrm.Page.ui)** won't work and will throw **Unable to get property 'Xrm' of undefined or null reference** – Vinod Srivastav May 03 '17 at 07:56
2

This works for me Xrm.Page.getControl("controlId"). It's just a shortcut for what you have already though...cant-disable-set-to-read-only-protect-gray-out-etc-a-field

Community
  • 1
  • 1
Daryl
  • 18,592
  • 9
  • 78
  • 145
  • When I run the code in a web resource, I get it to find my component (called *subject*) but when I execute it from the console, I get "*Object doesn't support property or method 'getControl'*". It's like *getControl* isn't defined in my *Xrm.Page* when accessed through the console. What can I be doing wrong?! –  Jan 07 '13 at 08:21
  • @AndreasJohansson What version of IE are you running? Have you tried a different computer? I've never had anything working fine when called directly within CRM as opposed to trying to call it manually from the command line... – Daryl Jan 07 '13 at 15:51
  • I've tried IE10 on Win8 and IE8 on Windows Server. Same issue on both. Are you saying that you can e.g. click "new" and start crating a new *Contact* and in the middle of the process, you can press F12 and access the fields contents by `Xrm.Page.getControl("owner").getvalue()`?! –  Jan 07 '13 at 20:31
  • As long as I've clicked the "Start Debugging" button, yes. – Daryl Jan 07 '13 at 20:56
  • And by *Start Debugging* you mean F12, right? Or am I missing something and don't follow the correct approach? –  Jan 08 '13 at 12:18
  • You'll have to push F12 to bring up the developer tools, then F5 to actually start the javascript debugger (or click the script tag, then the "Start Debugging" button) – Daryl Jan 08 '13 at 13:44
  • @AndreasJohansson The kbd-tag doesn't work in comments, regrettably. And +1 on Daryl for stubbornly persistent explanation. – Konrad Viltersten Jan 09 '13 at 19:47
1

In addition to what @Daryl said, I can add that I use different syntax. For some reason, I don't get his to work either. Might have to do with different browser version or something. Instead try to execute this, if you still can't get it to work (although I must admit that his is shorter = better).

Xrm.Page.getAttribute("lastname").getValue();

The lastname parts is tested a minute ago on creation of an instance of entity Contact. I just put in a breakpoint inside a script that is executed onchange and while broken-pointed, I entered the command above to the console.

If neither approach works for you, you've got some weird problem with your CRM or browser.

Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
0

A reason some people need this information is to access their own code. If you need to access your own methods from the console, in 2011, any global methods (or namespaces) in your javascript were also in forms[0]. Obviously, this is a bad idea, just from a naming standpoint. In forms v6+ any global objects or functions are in an object called customScriptsFrame inside frames[0] (or presumably whichever frame the Xrm is found).

frames[0].customScriptsFrame.myFunctionName();

Michael Blackburn
  • 3,161
  • 1
  • 25
  • 18