2

I am implementing a Tridion 2011 (GA) GUI Extension on the Link Popup (the one that opens up when you click on the hyperlink button in a rich text area to enable to you select a component to link to, or url/mailto etc.).

I want to hook into the point where a component is selected or updated within this popup, so that I can load some data based on the selected component's schema. The problem is that the html input field that contains the component uri is disabled (as the value can only be changed by the selector), and I think this is preventing the change event from firing.

In my extension js I have the following, but the function is not called when I select/update a component, only when I change a http/mailto link

$evt.addEventHandler($("#FieldUrl"), "change", onFieldUrlChanged);

function onFieldUrlChanged()
{
    alert("url changed to: " + $("#FieldUrl").value);
}

Is there some other event that would work? Otherwise, is there some way I can hook into the browse popup being closed?

UPDATE

Following Frank's suggestion I am trying to hook into events in the Select Item popup. I have now added an event handler for the browse button click, which in turn adds event handlers for the popup. I was hoping to use insert or even unload, however rather annoyingly the only one which seems to fire is close (which only happens when you do not select a linked component, so not much use to me). My JS code is below:

$evt.addEventHandler($("#BtnBrowse"), "click", onBtnBrowseClicked);
function onBtnBrowseClicked = function (event)
{
    var popup = $display.getView().properties.ItemPopup;
    $evt.addEventHandler(popup, "load", function () { alert('loaded'); });
    $evt.addEventHandler(popup, "insert", function () { alert('insert'); });
    $evt.addEventHandler(popup, "close", function () { alert('close'); });
    $evt.addEventHandler(popup, "unload", function () { alert('unload'); });
}

Using the console I did manage to hook a click event into the actual insert button in the popup, with something like this:

$evt.addEventHandler($display.getView().properties.ItemPopup.properties.view.properties.controls.insertButton, "click", function () { alert('stone the crows'); });

However if I add this in my browse click event handler it errors as $display.getView().properties.ItemPopup.properties.view is null, perhaps as the popup has not fully loaded yet (and as just shown, the load event doesnt work, so I dont see how I can wait for it to load!).

Will
  • 965
  • 5
  • 19
  • Note that actually the issue has nothing to do with the textbox being disabled. The change event does not fire for any input field which has its contents changed programatically, only by user input (I discovered this when I tried to hook into the change for the FieldTitle (textbox) and TargetType (select) fields – Will Aug 17 '12 at 10:37

1 Answers1

2

You probably need to listen to the submit event that each popup fires, instead of the change event you are listening to now.

The change event is a standard HTML event and thus is subject to all the usual rules that come with that (such as it apparently not firing for disabled controls).

The submit event on the other hand is a custom Tridion event. Although that unfortunately means it is less documented, it does have the huge advantage that we can simply read the JavaScript code to see when/how it fires and how to hook it.

I'll see if I can write a small example for you, but in the meantime have a look at this question (and answer) from Nuno: Anguilla - Updating a field's value from a popup?.

If you want to respond to the Component selection in the Hyperlink popup itself, have a look inside Link.js and you'll see that it registers itself for the insert event of the item select popup.

$evt.addEventHandler(p.ItemPopup, "insert",
                     function Link$_onBrowseClicked$onPopupSubmitted(event)

For those keeping track, by then you have this chain of popups:

> Dashboard > Edit Component > Insert Hyperlink > Select Item

Update

I see you are moving towards hooking insert as I suggested. When I try to do that, I also can't capture the insert event from within the Hyperlink popup.

But if I register the handler from within the Item Select Popup itself, it does trigger:

$evt.addEventHandler($display.getView(), "insert", 
                     function() { alert('event fired in item selector'); });

If that is indeed the only way to hook it (I'll look further, but don't know what I'll find) then you should simply load your script file into all popups and register the handler once the view has loaded completely:

$evt.addEventHandler($display, "start", function () {
    $evt.removeEventHandler($display, "start", onDisplayStarted);

    if ($display.getView().getId() == "ItemSelectDialogView") {
        // we're in an Item select popup -> listen for the insert event
        $evt.addEventHandler($display.getView(), "insert", onItemInserted);
    }
}

function onItemInserted(e) {
    $evt.removeEventHandler($display.getView(), "insert", onItemInserted);
    var items = e.data.items;
    ...

As you can see we listen for the start event on $display to ensure the view has loaded properly before we register our insert event handler. Don't forget to remove such event handlers or you'll end up with re-entry problems later.

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 1
    Thanks Frank - registering the event handler in the ItemSelect popup works. so your answer has got me there in the end. Note that I do not need to include the js in all popups, I can use the editor configuration to include a specific js for only the ItemSelectDialog () which contains just the insert event handler, which does the call back to a function in the opener (which loads data based on the schema of the selected component). This done with window.opener.myFunction() – Will Aug 17 '12 at 10:33