I’m building a GUI extension that includes a popup that is opened on the click of a new button in the ribbon bar. The popup includes a dropdown that is dynamically populated with some information gathered from the system using the Core Service. At least that’s the idea. I am able to get the button to appear, and it opens the popup, but as soon as I start with the javascript for the popup I get an error Unable to get unique id for element and the CME doesn’t finish loading. Here’s what I have so far:
Popup ASPX
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SwitchUserPopup.aspx.cs" Inherits="SwitchUser.Popups.SwitchUserPopup" %>
<%@ Import Namespace="Tridion.Web.UI.Core" %>
<%@ Import Namespace="Tridion.Web.UI" %>
<%@ Import Namespace="System.Web" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://www.sdltridion.com/web/ui/controls">
<head runat="server">
<title>Select User</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<h1>Select User</h1>
<c:dropdown id="SwitchUserDropdown" runat="server" nullable="false"/>
</div>
</form>
</body>
</html>
Popup ASPX Code
namespace SwitchUser.Popups
{
[ControlResourcesDependency(new [] { typeof(Popup),
typeof(Tridion.Web.UI.Controls.Button),
typeof(Stack),
typeof(Dropdown),
typeof(List) })]
[ControlResources("SwitchUser.Resources")]
public partial class SwitchUserPopup : TridionPage
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
TridionManager tm = new TridionManager();
tm.Editor = "SwitchUser";
System.Web.UI.HtmlControls.HtmlGenericControl dep =
new System.Web.UI.HtmlControls.HtmlGenericControl("dependency");
dep.InnerText = "Tridion.Web.UI.Editors.CME";
tm.dependencies.Add(dep);
System.Web.UI.HtmlControls.HtmlGenericControl dep2 =
new System.Web.UI.HtmlControls.HtmlGenericControl("dependency");
dep2.InnerText = "Tridion.Web.UI.Editors.CME.commands";
tm.dependencies.Add(dep2);
//Add them to the Head section
this.Header.Controls.Add(tm); //At(0, tm);
}
}
}
Popup JS
Type.registerNamespace("SwitchUser.Popups");
SwitchUser.Popups.SwitchUser = function (element) {
Type.enableInterface(this, "SwitchUser.Popups.SwitchUser");
this.addInterface("Tridion.Cme.View");
};
SwitchUser.Popups.SwitchUser.prototype.initialize = function () {
$log.message("Initializing Switch User popup...");
this.callBase("Tridion.Cme.View", "initialize");
var p = this.properties;
var c = p.controls;
c.UserDropdown = $controls.getControl($("#SwitchUserDropdown"), "Tridion.Controls.Dropdown");
};
$display.registerView(SwitchUser.Popups.SwitchUser);
The extension is configured correctly in System.config – I can see the log message in the javascript console. However, I also see this Unable to get unique id for element error with the following additional information:
anonymous(object{..})
WebRequest.completed(object{..})
Net.loadFile$onComplete(object{..})
Net.loadFile$onOperationCompleted()
Xml.loadXmlDocuments$onSuccess(array1)
Xml.loadXmlDocument$onSuccess(array1)
Dropdown.setup$filesLoaded(object{..})
setupDone()
anonymous(function: DisplayController$start())
DisplayController.start()
anonymous()
anonymous(undefined, “Tridion.Controls.Dropdown”)
Tridion.Assert$raiseError(“Unable to get unique id for element.”)
From that logged info it seems that the problem is the dropdown. If I comment out the line in my JS that registers the view then I don’t get the error, but I also don’t get the log message so I suspect that this is a mandatory call. Can anyone shed any light on why this might be happening? I’ve been using the Example PowerTool code as a reference, and I believe I’ve replicated what is there…
Update
I tried to step through the code – I found a suitable line and placed a breakpoint there. Then I reloaded the CME and suddenly my breakpoint was on a line that had no relevance to my code, and I couldn’t find anything related to my code. However, according to the console it is still being executed.
So, instead I put log messages in my initialize method as follows:
SwitchUser.Popups.SwitchUser.prototype.initialize = function () {
$log.message("Initializing Switch User popup...");
this.callBase("Tridion.Cme.View", "initialize");
$log.message("Tridion.Cme.View callBase done");
var p = this.properties;
var c = p.controls;
$log.message("Set properties and controls");
c.UserDropdown = $controls.getControl($("#SwitchUserDropdown"), "Tridion.Controls.Dropdown");
$log.message("Got UserDropdown control");
};
I can see in the console that it logs as far as Set properties and controls and then I get the error.
I put a breakpoint in the getControl method and was able to determine why I was getting the error.
$("#SwitchUserDropdown")was not finding anything so when the code below was running it threw the error:It seems obvious now that I know why it was happening that the code was running at the wrong time. I believe it shouldn’t run when the CME loads, but only when the popup is opened. This leads me to look at the configuration of the resources in my Editor config file. I had previously grouped my popup’s JS with other resources associated with the ribbon toolbar button. By placing the popup specific resources in their own resource group I was able to stop the error and successfully get the control.