4

I'm a CSS newbie, so this might be a trivial question. Nonetheless I need help.

I have this Lightning component used as action on a button.

<aura:component controller="..." access="GLOBAL" implements="force:lightningQuickActionWithoutHeader,force:hasRecordId">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <div class="slds-page-header" role="banner">
        <p class="slds-text-heading--label">{!v.record.Name}</p>
        <h1 class="slds-page-header__title slds-m-right--small slds-truncate slds-align-left">Add new year</h1>
    </div>

   <c:strike_select aura:id="options" value="{!v.selected}" placeholder="Select Template" onchange="{!c.doSelect}">
        <aura:renderIf isTrue="{!v.showBlank}">
            <c:strike_option value="" label="No Template (Create blank record)" />
        </aura:renderIf>

        <aura:iteration items="{!v.templates}" var="tmpl">
            <c:strike_option value="{!tmpl.id}" label="{!tmpl.label}" />
        </aura:iteration>
    </c:strike_select>

    <lightning:button label="Cancel" onclick="{!c.doCancel}" variant="neutral"  />
    <lightning:button label="Continue" onclick="{!c.doContinue}" variant="brand" /> 
</aura:component>

The initalization code that populates the options:

({
    doInit : function(cmp, event, helper) {    
        var action = cmp.get("c.getOptions");
        action.setCallback(this, function(response) {
            cmp.set("v.templates", response.getReturnValue());
            cmp.find("options").blur(); // fails!
        });

        $A.enqueueAction(action); 
    }

But as you see in the screenshots there are three display problems.

  1. The select options are auto-opened on page load
  2. The select options are hidden outside of the modal (showing 2 ugly scrollbars
  3. Insufficient spacing between header, select and buttons. How can I make it look like a real modal. I read everything about mimicing modals but I could make it work.

Note: I am using Strike Components here as making it work with pure Design System is not what I want and Base Components also don't style properly.

enter image description here

enter image description here

Robert Sösemann
  • 37,622
  • 26
  • 165
  • 495

1 Answers1

3

Item 1: To make spacing use slds classes: https://www.lightningdesignsystem.com/utilities/margin/#react-target (similar for padding)

<div class="slds-m-top_medium">
        <lightning:button label="Cancel" onclick="{!c.doCancel}" variant="neutral"  />
        <lightning:button label="Continue" onclick="{!c.doContinue}" variant="brand" /> 
    </div>  

Item 3: To get your dropdown items on top of modal, it's z-index property has to be larger than modal's z-index. Use browser developer tools to inspect z-index of your modal and assign greater value to any element in your modal body that contains dropdown.

https://www.w3schools.com/cssref/pr_pos_z-index.asp

Item 2: Here is my code for opening modal:

<aura:component implements="flexipage:availableForAllPageTypes" access="public">
    <aura:attribute name="selected" type="String" />
    <aura:attribute name="templates" type="Object[]" default="[{'id': '1', 'label': 'one'}, {'id': '2', 'label': 'two'}]" />

    <c:strike_modal aura:id="modal"
            title="Confirmation"
            secondaryButtonLabel="Cancel"
            primaryButtonLabel="Ok"
            showHeader="true"
            showFooter="true"
            showModal="false">

            <c:strike_select aura:id="options" value="{!v.selected}" label="My label" placeholder="Select Template">
                <aura:iteration items="{!v.templates}" var="tmpl">
                    <c:strike_option value="{!tmpl.id}" label="{!tmpl.label}" />
                </aura:iteration>
            </c:strike_select>

    </c:strike_modal>

    <lightning:button label="Click me!" onclick="{!c.click}" class="slds-m-around--x-large"/>

</aura:component>

Controller:

({
    click: function(component, event, helper) {
        component.find("modal").show();
    }
})

Result:enter image description here When your component is loaded from quick action, it looks like this is platform feature that first form element is focused. To prevent this you can try this walkaround:

<div tabindex="0" ></div>
<c:strike_select aura:id="options" value="{!v.selected}" label="My label" placeholder="Select Template">
    <aura:iteration items="{!v.templates}" var="tmpl">
        <c:strike_option value="{!tmpl.id}" label="{!tmpl.label}"/>
    </aura:iteration>
</c:strike_select>

https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex

Vladyslav K
  • 2,743
  • 7
  • 33
  • 70
  • Cool. Only problem 1 is unsolved. I tried to blur the element as it is focused by populating it in onInit(). But calling cmp.find("options").getElement().blur(); fails with an error. – Robert Sösemann Jun 06 '17 at 10:54
  • @RobertSösemann Try without getElement(), cmp.find returns lightning component itself, method blur() is available on it, but getElement() returns DOM element. – Vladyslav K Jun 06 '17 at 11:58
  • "cmp.find(...).blur is not a function" Please see the code above. I am using a Strike Select defined here: https://github.com/appiphony/Strike-Components/blob/master/aura/strike_select/strike_select.cmp – Robert Sösemann Jun 06 '17 at 13:06
  • @RobertSösemann Oh, I think this is what Salesforce does not allow to do - to call component's method from other component (kind of security/isolation). In this case you have to call component's method from component's controller or helper. Or you have to define aura:method https://salesforce.stackexchange.com/questions/122359/how-to-call-child-component-controller-function-helper-from-parent-component-con – Vladyslav K Jun 06 '17 at 13:44
  • You mean I cannot even blur the parent component <c:strike_select aura:id="...">? althought it is not an internal of the component? – Robert Sösemann Jun 06 '17 at 13:53
  • Try adding this line to strike_select: <aura:method name="blur" access="global" action="{!c.blur}" /> and after it try calling blur() as above. Worked for me. – Vladyslav K Jun 06 '17 at 13:59
  • Modifying the external library code? But then I would have to do is with every update of the library. Isn't there a way to make this work from outside? E.g. having an invisible element in the page that "pulls the focus away"? – Robert Sösemann Jun 06 '17 at 14:02
  • Can you share the whole code of popup and code that opens it? – Vladyslav K Jun 06 '17 at 14:06
  • It works when I create a Strike modal like in your code. But when I call it from an Action implementing lightningQuickActionWithoutHeader which brings its native modal the problem still exists. – Robert Sösemann Jun 06 '17 at 14:36
  • I see, looks like this is default lightning behaviour - it makes first element focused when component is loaded from action – Vladyslav K Jun 06 '17 at 15:52