Close drawer with button

  • 1
  • Question
  • Updated 2 years ago
  • Answered
Has Skuid or TFG come up with a component that adds "close drawer" action for a button?
Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb

Posted 3 years ago

  • 1
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
Hi Bill -

Can you provide more details on your use case and what you would like to see?  What type of button and inside of which component?  Which drawer would it close?

The TFG collapsible wrapper has API methods that let you expand/collapse all wrappers.  The functionality is also exposed by publishing events (see the CW videos for more info).  I don't think this would meet your use case but just in case, wanted to make sure you are aware.
Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb
Thanks Barry.  It is easiest to show a video.
https://drive.google.com/file/d/0B409lhd9sYDcalpFRk5tb2pzUms/view
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
Hi Bill -

Very helpful, thanks for the video.

Unfortunately, there is no stock method for accomplishing what you're after.  That said, it could be accomplished via a custom JS Snippet.  I believe there is code in another community post that demonstrates how to close a drawer programmatically so have a look around for that if you are interested.  You would write the JS snippet and then just call it from the action framework for that button.

Even better, as you noted in your OP, would be to have a action such as "Close Parent/Closet Drawer.".  This would be a "custom action" that would be relatively straightforward to develop if "custom actions" where a supported feature :(
Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb
It would seem since there is an action to open and close popup that there should be an action to close a drawer.  I will search the community for such an action or JS Snippet.  Is there a site where we can all share snippets?
Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb
Lots of people needing this function on the community but no simple solution for a non coding person.  Seems someone like Pat, could provide this for all of us?
Photo of Gregg Baxter

Gregg Baxter

  • 3,182 Points 3k badge 2x thumb
Hi Bill.  It would be obvious for me not to point out that you can enable 'Show Close Handle' which allows this functionality?



Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb
That is an option.  However, this is a public facing site, so trying to give a consistent look and feel.  http://member.dorothy.com
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
Hi Bill -

I just searched back in the community and you are right, there is a lot of posts related to this type of functionality - some dating back over 2 years.

I stumbled across an old post at https://community.skuid.com/skuid/topics/javascript-to-open-drawer-and-or-conditionally-render-row-a... where I provided a jQuery plugin solution to make drawers more accessible.  Have a look at this if you are interested.

In the meantime, below is a very quick and dirty solution for what you are after.  If you add the following as an "inline" JS resource, you can then call the snippet 'closeDrawerFromInsideDrawer' from your button that lives inside of your drawer.

    skuid.snippet.registerSnippet('closeDrawerFromInsideDrawer', function(args) {              var eventArg = arguments[0]
        , context = eventArg.context
        , editor = (context && context.editor) || eventArg.editor
        , element = editor && editor.element;
       
    $(element).closest('.sk-drawer').data('component').toggle();
    });

Not to beat a dead horse but this is another situation where Skuid providing extensibility features would make things much easier.  For those interested in seeing that, if you haven't already vote here and here.

Hope this helps!
Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb
Thanks Barry.  I am sure it is something I have done wrong as this feature is new to me:
https://drive.google.com/file/d/0B409lhd9sYDccFNUdi1IRUx6Z0k/view
Any thoughts?
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
Hi Bill -

The problem is that you want to use "In-Line" not "In-Line (snippet)".

Here's what you do:

1) Remove the JS resource that you have in there now
2) Add a new "In-Line" JS resource
3) Edit the snippet body
4) Remove everything that is in there
5) Place the following in there

(function(skuid){	var $ = skuid.$;
    skuid.snippet.registerSnippet('closeDrawerFromInsideDrawer', function(args) {
        // Note that this doesn't handle situations where a context is provided
        var eventArg = arguments[0]
        , context = eventArg.context
        , editor = (context && context.editor) || eventArg.editor
        , element = editor && editor.element;
       
    $(element).closest('.sk-drawer').data('component').toggle();
    });
    
})(skuid);
Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb
Thanks Barry.  It works great.  Since I plan on using on many pages can i put as a static resource?
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
Hi Bill -

Glad that worked for you.

In order to "share", you have a couple of different options:

1) Use a master page and put the "inline" JS resource in the master page
2) Create a mysnippets.js file and put the code in there.  Then upload file that as a static resource.  For more flexibility, you could create a ZIP file that contains a JS file and put the code in the JS file and then upload the zip file.  Either way, once uploaded, include it from your pages.  You could also include as a static resource from a master page so you don't have to individually include on every page.

For some guidance on this type of stuff, check out https://community.skuid.com/skuid/topics/how-do-skuid-developers-organize-their-snippets
Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb
I have lost where I originally did this.

I have a created an in-line Javascript

(function(skuid){ var $ = skuid.$;    skuid.snippet.registerSnippet('closeDrawerFromInsideDrawer', function(args) {
        // Note that this doesn't handle situations where a context is provided
        var eventArg = arguments[0]
        , context = eventArg.context
        , editor = (context && context.editor) || eventArg.editor
        , element = editor && editor.element;
        
    $(element).closest('.sk-drawer').data('component').toggle();
    });
    
})(skuid);

In created a button with "run a javascript snippet" called "closeDrawerFromInsideDrawer"

but it has no reaction
https://drive.google.com/file/d/0B409lhd9sYDcRXJ3VE5TQVk2MDA/view
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
Hi Bill -

Questions:

1) Are you using a table with a drawer or a collapsible wrapper in the video?
2) Please check the browser console to see if there are any errors

Closing a drawer from a button inside of the actual drawer is working as expected in Skuid 9.5.  Here is a sample page:

<skuidpage unsavedchangeswarning="yes" personalizationmode="server" useviewportmeta="true" showsidebar="true" showheader="true" tabtooverride="Account">    <models>
        <model id="Account" limit="100" query="true" createrowifnonefound="false" datasourcetype="salesforce" datasource="salesforce" sobject="Account">
            <fields>
                <field id="Name"/>
                <field id="CreatedDate"/>
            </fields>
            <conditions/>
            <actions/>
        </model>
    </models>
    <components>
        <pagetitle model="Account" uniqueid="sk-1SOLzO-87">
            <maintitle>
                <template>{{Model.labelPlural}}</template>
            </maintitle>
            <subtitle>
                <template>Home</template>
            </subtitle>
            <actions>
                <action type="savecancel"/>
            </actions>
        </pagetitle>
        <skootable showconditions="true" showsavecancel="false" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" createrecords="true" model="Account" mode="read" allowcolumnreordering="true" uniqueid="sk-1SOLzO-88">
            <fields>
                <field id="Name" hideable="true" allowordering="true" uniqueid="fi-1SOKdm-480"/>
                <field id="CreatedDate" hideable="true" allowordering="true" uniqueid="fi-1SOKdm-481"/>
            </fields>
            <rowactions>
                <action type="multi" label="Run multiple actions" icon="sk-icon-magic">
                    <actions>
                        <action type="drawer">
                            <drawer title="Drawer Area" width="90%" closehandle="true">
                                <components>
                                    <pagetitle uniqueid="sk-1SOTVE-121" model="Account">
                                        <maintitle>
                                            <template>{{Name}}</template>
                                        </maintitle>
                                        <subtitle>
                                            <template>{{Model.label}}</template>
                                        </subtitle>
                                        <actions>
                                            <action type="multi" label="PageTitle - Close Drawer" icon="">
                                                <actions>
                                                    <action type="custom" snippet="closeDrawerFromInsideDrawer"/>
                                                </actions>
                                            </action>
                                        </actions>
                                        <conditions>
                                            <condition type="contextrow" field="Id" mergefield="Id"/>
                                        </conditions>
                                    </pagetitle>
                                    <buttonset uniqueid="sk-1SPS7D-178" model="Account">
                                        <buttons>
                                            <button type="multi" label="ButtonSet - Close Drawer">
                                                <actions>
                                                    <action type="custom" snippet="closeDrawerFromInsideDrawer"/>
                                                </actions>
                                            </button>
                                        </buttons>
                                    </buttonset>
                                </components>
                            </drawer>
                        </action>
                    </actions>
                </action>
            </rowactions>
            <massactions usefirstitemasdefault="true"/>
            <views>
                <view type="standard"/>
            </views>
        </skootable>
    </components>
    <resources>
        <labels/>
        <css/>
        <javascript>
            <jsitem location="inline" name="newInlineJS" cachelocation="false" url="">(function(skuid){
    var $ = skuid.$;    
    
    skuid.snippet.registerSnippet('closeDrawerFromInsideDrawer', function(args) {              
        var eventArg = arguments[0]
        , context = eventArg.context
        , editor = (context &amp;&amp; context.editor) || eventArg.editor
        , element = editor &amp;&amp; editor.element;
        
    $(element).closest('.sk-drawer').data('component').toggle();
    });    
    
})(skuid);</jsitem>
        </javascript>
    </resources>
    <styles>
        <styleitem type="background" bgtype="none"/>
    </styles>
</skuidpage>
Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb
Hello Barry,

It's a collapsible wrapper.


Uncaught TypeError: Cannot read property 'toggle' of undefined    at VM18954 skuid__ui?page=RM1_Offer&member_id=a0gj00000010mVUAAY:78
    at custom (skuid__SkuidJS:18)
    at Object.h.runActionNode (skuid__SkuidJS:17)
    at m (skuid__SkuidJS:17)
    at Object.h.runActionsNode (skuid__SkuidJS:17)
    at HTMLDivElement.<anonymous> (skuid__SkuidJS:19)
    at HTMLDivElement.dispatch (skuid__JQueryJS:3)
    at HTMLDivElement.r.handle (skuid__JQueryJS:3)
(Edited)
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
Hi Bill -

The code you are using will only work on a drawer (from a table).  You're encountering a javascript exception because the code cannot locate a drawer (via "sk-drawer" class) and then tries to call toggle on something it can't find (since there isn't one :)).

Since you are using a collapsible wrapper and not a drawer, you need to use code that will look for a CW and toggle it instead of looking for a drawer.

Fortunately, the collapsible wrapper has a full API to allow for this functionality.  Part #2 of the collapsible wrapper video walks you through the API available.  The API is described around the 2:45min mark in the video at https://youtu.be/lYMTLg3Week.

Here's a snippet that will accomplish what you are after.  All you need to do is add this to your existing JS resource and then change the button to call this snippet.

    skuid.snippet.registerSnippet('closeCWFromInsideCW', function(args) {                      var eventArg = arguments[0]
        , context = eventArg.context
        , editor = (context && context.editor) || eventArg.editor
        , element = editor && editor.element;
        
    $(element).closest('.tfg-collapsiblewrapper').tfg__collapsiblewrapper('toggle');
    }); 
Photo of Bill Fox

Bill Fox

  • 8,500 Points 5k badge 2x thumb
That worked.  I had to remove the $ and change toggle to close.  Again, thanks.  I have collapsible wrappers EVERYWHERE!
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
Glad that worked Bill.  Not sure why you would have to remove $ or change toggle to close but at least you got it working :)
Photo of David Forder

David Forder

  • 2,384 Points 2k badge 2x thumb
Hi Barry.. the sample page wouldnt open for me but I thought I pulled the js out of the page above ok.

Still no joy.

Can you see anything wrong with this 
(function(skuid){	
    var $ = skuid.$;    
    
    skuid.snippet.registerSnippet('closeDrawerFromInsideDrawer', function(args) {              
        var eventArg = arguments[0]
        , context = eventArg.context
        , editor = (context &amp;&amp; context.editor) || eventArg.editor
        , element = editor &amp;&amp; editor.element;
        
    $(element).closest('.sk-drawer').data('component').toggle();
    });    
    
})(skuid)


to close a drawer with a button within it?
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
Hi David -

I just tested the sample page from above and it worked properly for me using version 10.0.3 of Skuid.

Questions:
1) When you say "it wouldn't open", what do you mean?  Are you getting errors and if so, what?
2) What version of Skuid are you using?
3) In the JS that you extracted, what errors are you getting when you try to use it on your own page?
4) In your test page where you extracted the javascript, what is the "Resource Location" you have set on this - Inline, Inline (Snippet), etc.?  You should ensure it's set to "Inline"
4) Can you include your entire page XML on your test page please?
Photo of David Forder

David Forder

  • 2,384 Points 2k badge 2x thumb
Hmm.. I must have had a brain fart. Just tried it again and it did render fine. Sorry about that!

I swear I got errors yesterday lol
Photo of Barry Schnell

Barry Schnell, Champion

  • 18,266 Points 10k badge 2x thumb
No worries, possibly a copy/paste issue.  Glad it's working for you!