1

I have a list page to which I need to add an additional webpart (in this case, a more powerful filter). However, the ribbon doesn't appear because the listview does not have focus.

This is easily overcome simply by clicking it, but I have an even bigger related issue. When you select items in the list, and then click somewhere else (including inside of a dialog box!), the listview loses focus again and the selected items get unselected. This is a major problem because my dialog box needs to know what items were selected. Does anyone know if there's any way to prevent this?

Based on the answer to this question, it looks like there's some Microsoft JavaScript function which checks for a single web part and thus causes this annoying behavior. Maybe there's a way to trick that function into thinking there's only a single web part?

3 Answers 3

3

After a ton of stepping through the SharePoint JS in a debugger, I've finally found a way to prevent this problem.

In SharePoint 2010:

//Set focus on our list web part
var webPart = document.getElementById('WebPartWPQ1');
WpClick({target: webPart});

//Prevent it from losing focus
SP.Ribbon.WebPartComponent.$3_1.deselectWebPartAndZone = function() { };

In SharePoint 2013 Beta:

//Set focus on our list web part
var webPart = document.getElementById('MSOZoneCell_WebPartWPQ2');
WpClick({target: webPart});

//Prevent it from losing focus
SP.Ribbon.WebPartComponent.$3.deselectWebPartAndZone = function() { };  

Note: This is super-hacky, and is in no way supported by Microsoft (thus it's very likely to change in a future version or possibly even the RTM of SharePoint 2013).

Also, note that your web part ids are likely to be different, so you should double check you're giving focus to the correct web part.

Explanation: It basically overrides the instance of SP.Ribbon.WebPartComponent's ability to deselect a web part. From what I can tell, the $3/$3_1 property stores a reference to the SP.Ribbon.WebPartComponent instance.

If anyone knows of a better way to access the instance of SP.Ribbon.WebPartComponent other than the $3/$3_1 property, please speak up, as that would be make this method much more robust.

2
  • Yeah, you can just use this code: SP.Ribbon.WebPartComponent.prototype.deselectWebPartAndZone = function(){}; it is much less hacky since it doesn't rely on internal obfuscated names. You should also wait for sp.ribbon.js to load before you override this.
    – Shai Petel
    Oct 4, 2016 at 17:50
  • Do you have a solution for this that still works in SP 2013? None of the solutions I am able to find seem to do anything in my on premises Sp 2013 environment.
    – James11
    Mar 15, 2018 at 13:29
0

Use JQuery .focus() on document load to target the element you want to be focused.

That's the only solution that came to my head.

2
  • The problem is not the initial focus. It is what happens after the user selects items and then some control creates a dialog box. The list loses focus and the items get unselected.
    – MgSam
    Aug 28, 2012 at 13:40
  • I see, you might be able to do something by binding an event to the onchange to store the details somewhere else as they are updated, you can't keep jumping the focus back sadly. I think I would do that, and have the dialogue pull from there. It is perhaps the quickest fix.
    – Hugh Wood
    Aug 28, 2012 at 13:43
0

Just had to confront myself with the same problem (seems to occur only with filter webparts lol).

I solved it by overriding the $3r_1 and making sure that the css class 's4-wpcell' is NOT being removed from the webpart. This works fine for me (even with 2 listview webparts it allows multiselection and the ribbon behaves correctly and it deselects items once you switch to the other list view correctly).

SP.Ribbon.WebPartComponent.get_instance().$3r_1 = function SP_Ribbon_WebPartComponent$$3r_1($p0, $p1) 
{
        var $v_0 = window._spWebPartComponents;

        if (this.get_$5_1() !== $p0 && this.get_$5_1(   )) {
            Sys.UI.DomElement.removeCssClass(this.get_$5_1(), 's4-wpActive');
            if (!SP.Ribbon.Utility.$G(this.get_$5_1(), 's4-wpcell') && !SP.Ribbon.Utility.$G(this.get_$5_1(), 's4-wpcell-plain')) {
                Sys.UI.DomElement.addCssClass(this.get_$5_1(), 's4-wpcell');
            }
            DeselectAllWPItems();
            var $v_2 = 'SelectionCbx' + this.$u_1(this.get_$5_1());
            var $v_3 = $get($v_2);

            if (!SP.Ribbon.SU.$0($v_3)) {
                $v_3.checked = false;
            }
        }
        this.set_$5_1($p0);
        if (!SP.Ribbon.SU.$0($v_0) && $p1) {
            var $v_4 = $v_0[this.get_$L_1()];

            if (!SP.Ribbon.SU.$0($v_4)) {
                var $v_5 = $v_4['firstTabId'];

                if (!SP.Ribbon.SU.$0($v_5)) {
                    window._spNextRibbonTabId = $v_5;
                }
            }
        }
        if (SP.Ribbon.WikiPageComponent.$C() || this.get_$I_1() || this.$4o_1(this.get_$L_1())) {
            if (!SP.Ribbon.Utility.$G($p0, 's4-wpActive')) {
                Sys.UI.DomElement.addCssClass($p0, 's4-wpActive');
                if (SP.Ribbon.Utility.$G($p0, 's4-wpcell')) {
                    ;/*Sys.UI.DomElement.removeCssClass($p0, 's4-wpcell');*/
                }
            }
            var $v_6 = 'SelectionCbx' + this.$u_1($p0);
            var $v_7 = $get($v_6);

            if (!SP.Ribbon.SU.$0($v_7)) {
                $v_7.checked = true;
            }
        }
        SP.Ribbon.WebPartComponent.$1W();
        this.$2O_1($p0);
        SP.Ribbon.WebPartComponent.$2x();
        if (this.get_$I_1()) {
            var $v_8 = GetElementsByName('MSOZone');

            if ($v_8 && $v_8.length > 0) {
                for (var $v_B = 0; $v_B < $v_8.length; $v_B++) {
                    Sys.UI.DomElement.removeCssClass($v_8[$v_B], 's4-wzActive');
                }
                var $v_9 = this.get_$F_1();

                if ($v_9 && !SP.Ribbon.Utility.$G($v_9, 's4-wzActive')) {
                    Sys.UI.DomElement.addCssClass(this.get_$F_1(), 's4-wzActive');
                }
                var $v_A = SP.Ribbon.WebPartComponent.getWebPartAdder();

                if ($v_A) {
                    $v_A._setZone(this.get_$d_1());
                }
            }
        }
        if (SP.Ribbon.SU.$0($v_0)) {
            return;
        }
        var $v_1 = $v_0[this.get_$L_1()];

        if (SP.Ribbon.SU.$0($v_1)) {
            return;
        }
        if (!SP.Ribbon.SU.$2($v_1.initPageComponentScript) && !(this.get_$5_1())._wpRibbonFetched) {
            (this.get_$5_1())._wpRibbonFetched = '1';
            eval($v_1.initPageComponentScript);
        }
        else {
            SP.Ribbon.UtilityInternal.$i();
        }
    }
;

Best, frevd

1
  • I have SP.Ribbon.WebPartComponent.get_instance() undefined. Do you have thoughts why it happens?
    – gdbdable
    Oct 27, 2016 at 13:20

Your Answer

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

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