9

I would like to get all the Component fields in the Component View from a GUI Extension. I am following the excellent code sampels provided here: GUI extension to hide field in 2011 SP1

My problem is that the fieldBuilder.properties collection does not contain an input property, and only contains 11 total properties at my breakpoint in the GUI Extension. However, when I use the same javascript code in the Chrome console I do get input and also I have a total of 24 properties.

How can I change the EventHandler or my config to get it at a later moment in the window loading? Config and Javascript posted below:

Readonly.js

//If you only want your code to affect certain screens/views, you should listen to Anguilla events like this:
$evt.addEventHandler($display, "start", onDisplayStartedReadonly);

// This callback is called when any view has finished loading
function onDisplayStartedReadonly() {
    console.log('View=' + $display.getView().getId());

    $evt.removeEventHandler($display, "start", onDisplayStartedReadonly);

    if ($display.getView().getId() == "ComponentView") {
        debugger;
        var fieldBuilder = $display.getView().properties.controls.fieldBuilder;

        fieldsContainer = fieldBuilder.properties.input;
        fieldsNode = fieldsContainer.getElement();
        control = null;

        $j(fieldsNode).children().each(function (index, elm) {
            var cntrl = $j('div.input', elm)[0].control;
            console.log('fieldname=' + cntrl.getFieldName());
        });
    }
}

Config:

<?xml version="1.0"?>
<Configuration xmlns="http://www.sdltridion.com/2009/GUI/Configuration/Merge"
               xmlns:cfg="http://www.sdltridion.com/2009/GUI/Configuration"
               xmlns:ext="http://www.sdltridion.com/2009/GUI/extensions"
               xmlns:cmenu="http://www.sdltridion.com/2009/GUI/extensions/ContextMenu">
  <resources cache="true">
    <cfg:filters />
    <cfg:groups>
      <cfg:group name="Readonly.CommandSet" merge="always">
        <cfg:fileset>
            <cfg:file type="script" id="jQuery16Readonly">/Readonly/jquery-1.6.4.js</cfg:file>
            <cfg:file type="script" id="readonlyJs">/Readonly/Readonly.js</cfg:file>
        </cfg:fileset>
        <cfg:dependencies>
          <cfg:dependency>Tridion.Web.UI.Editors.CME</cfg:dependency>
          <cfg:dependency>Tridion.Web.UI.Editors.CME.commands</cfg:dependency>
        </cfg:dependencies>

      </cfg:group>
    </cfg:groups>
  </resources>
  <definitionfiles />
  <extensions>
    <ext:dataextenders />
    <ext:editorextensions>
      <ext:editorextension target="CME">
        <ext:editurls />
        <ext:listdefinitions />
        <ext:taskbars />
        <ext:commands />
        <ext:commandextensions>
          <ext:commands>
          </ext:commands>
          <ext:dependencies>
            <cfg:dependency>Readonly.CommandSet</cfg:dependency>
          </ext:dependencies>
        </ext:commandextensions>
        <ext:contextmenus />
        <ext:lists />
        <ext:tabpages />
        <ext:toolbars />
        <ext:ribbontoolbars />
      </ext:editorextension>
    </ext:editorextensions>
  </extensions>
  <commands>
    <cfg:commandset/>
  </commands>
  <contextmenus />
  <localization />
  <settings>
    <defaultpage />
    <editurls />
    <listdefinitions />
    <itemicons />
    <theme>
      <path />
    </theme>
    <customconfiguration>
    </customconfiguration>
  </settings>
</Configuration>

2 Answers 2

11

You can run your extension code when the thread gets executed. To do so, try following

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

    function onDisplayStartedReadonly$_collectProperties()
    {
        if ($display.getView().getId() == "ComponentView") 
        {
            debugger;
            var fieldBuilder = $display.getView().properties.controls.fieldBuilder;

            fieldsContainer = fieldBuilder.properties.input;
            fieldsNode = fieldsContainer.getElement();
            control = null;

            $j(fieldsNode).children().each(function (index, elm) {
                var cntrl = $j('div.input', elm)[0].control;
                console.log('fieldname=' + cntrl.getFieldName());
            });
        }
    }

    setTimeout(onDisplayStartedReadonly$_collectProperties, 0);
}




and plan "B", is to listen on on fieldbuilder "load" event

if ($display)
{
    (function()
    {
        $evt.addEventHandler($display, "start", Extension$onDisplayStartedReadonly);

        function Extension$onDisplayStartedReadonly()
        {
            $evt.removeEventHandler($display, "start", Extension$onDisplayStartedReadonly);

            var view = $display.getView();
            if (view && Tridion.OO.implementsInterface(view, "Tridion.Cme.Views.Component"))
            {
                var fieldBuilder = view.properties.controls.fieldBuilder;
                $evt.addEventHandler(fieldBuilder, "load", Extension$onDisplayStartedReadonly$_collectProperties);
            }
        };

        function Extension$onDisplayStartedReadonly$_collectProperties(event)
        {
            var fieldBuilder = event && event.source;
            if (fieldBuilder)
            {
                var fieldsContainer = fieldBuilder.properties.input;
                var fieldsNode = fieldsContainer.getElement();
                var control = null;

                $j(fieldsNode).children().each(function (index, elm)
                {
                    var cntrl = $j('div.input', elm)[0].control;
                    console.log('fieldname=' + cntrl.getFieldName());
                });
            }
        };
    })();
}
4
  • I have the same result: fieldBuilder is available but fieldsContainer is 'undefined'. I use the same code, but also have this addEventHandler at the top, $evt.addEventHandler($display, "start", onDisplayStartedReadonly); Any ideas?
    – robrtc
    Commented Jun 18, 2013 at 9:36
  • Well.. quick-trick didn`t help. The problem is that fuildBuilder is already uses setTimeout(.. , 0). What I was hoping is that it puts the execution after the fuildbuilded will do so. As a plan "B", you can listen fielbuilder itself, when it gets loaded it will fire "load" event Commented Jun 18, 2013 at 9:56
  • How would I listen to the fieldBuilder?
    – robrtc
    Commented Jun 18, 2013 at 10:58
  • 1
    Plan "B" is the winner. :) Thanks for the excellent detailed working solution.
    – robrtc
    Commented Jun 19, 2013 at 8:12
7

I think that a more elegant and efficient way to accomplish it is by extending a Resources Group, for instance you may want to just load your script when the Component View is loaded and not for every single request (Domain Model Script).

Here a sample:

<Configuration xmlns="http://www.sdltridion.com/2009/GUI/Configuration/Merge"
               xmlns:cfg="http://www.sdltridion.com/2009/GUI/Configuration"
               xmlns:ext="http://www.sdltridion.com/2009/GUI/extensions"
               xmlns:cmenu="http://www.sdltridion.com/2009/GUI/extensions/ContextMenu">
  <resources cache="true">
    <cfg:filters />

    <cfg:extensiongroups>
      <cfg:extensiongroup name="Tridion.Extensions.ComponentView.Fields">
        <cfg:extension target="Tridion.Web.UI.Editors.CME.Views.Component">
          <cfg:insertafter>Tridion.Extensions.ComponentView.FieldsGroup</cfg:insertafter>
        </cfg:extension>
      </cfg:extensiongroup>
    </cfg:extensiongroups>

    <cfg:groups>
        <cfg:group name="Tridion.Extensions.ComponentView.FieldsGroup">
            <cfg:fileset>
              <cfg:file type="script">/Extensions/Script/Fields.js</cfg:file>
            </cfg:fileset>
        </cfg:group>
    </cfg:groups>

    .....

    <resourceextensions>
      <resourceextension>Tridion.Extensions.ComponentView.Fields</resourceextension>
    </resourceextensions>

</Configuration>

I hope this helps.

2
  • What is the parent node for resourceextension? Thanks for the nice tip!
    – robrtc
    Commented Jun 20, 2013 at 9:47
  • It should be inside <settings>
    – Eric Huiza
    Commented Jun 20, 2013 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.