Dienstag, 8. März 2016

Adding Custom CSS without touching Masterpage

You can do that using the Delegate-Control mechanism and the builtIn Control "CSSRegistration".

Simply create a Feature (Web- or Sitescoped) and a Module and put the following Control Definition into it:

  
    URLToCSSFile
  
If you start your url without "/", it will assume your CSS-File lies within the "Styles"-Folder in _layouts and prefixes the corresponding parts automatically

Mittwoch, 17. Februar 2016

Adding ECB MenuItem using Javascript

Recently I got the request to view an ECB-Menu Entry only for specific Views. Therefore, the OOTB Version was not a viable option. So I checked out how the ECB-Menu is generated and this is what I ended up with.
It is to how you add this JS to your Web. you can do it using a ContentEditorScript Webpart to a single View, ... . I used a Delegate Control which injected a JS-File to a Web, if the Current-Context was a List and the View was a desired one.


First of all, you have to attach yourself to an Event called "CleanupContextMenu"
like
SP.SOD.delayUntilEventNotified(<funcionName>, "CleanupContextMenu");

"CleanUpContextMenu" is triggered from the ECB-Menu-Builder Function when it is mostly done. So, you can attach to this event and modify it before it is rendered.
The Function you call can look like this
<functionName>: function(menuElement, context) {
            a = {};
            a.Title = "Doing something";
            a.Action = "javascript:doSomeThingWhithItem({ItemId});";
            a.Sequence = 65536;

            var e = ReplaceUrlTokens(a.Action, context);

            v = CIMOpt(menuElement, a.Title, e, null, null, String(a.Sequence));
            v.id = "ID_" + a.Title;

            if (!window.oldBuildMenu) {
                oldBuildMenu = BuildMenu;

                BuildMenu = function (a) {
                    b = oldBuildMenu(a);
                    <functionName>(b, a);
                    return b;
                }
            }
        }

No big magic. The function is called with the parameters of the Menu built so far and the context, with additional Information like the List and View the ECB-Menu is belonging to.
the next thing is to create a object if Properties for "Title", "Action" and "Sequence". I don´t think I have to go further on their purpose.
In the next line I use the builtIn Function to replace the UrlTokens of the Action with current Variables (eg the ItemId is replaced by the real ID of the current Item. With the Function "CIMOpt" a Menu Option is placed into the Menu using your Properties and in the next line the new Menu-Option is equipped with an ID.

Last but not least:
When an Event is triggered, all functions are called which want to be notified of it. But then, all Notification Requests are cleared. So, the next Time when the Event is called, your function won´t be triggered. Attaching to the event again when called will result in an endless loop.
So, I overwrite the old BuildMenu-function with a custom one, which is calling the old function and then my function.