Base solution for your next web application
Ends in:
01 DAYS
01 HRS
01 MIN
01 SEC
Open Closed

Dropdown in Modal not working (6.2.1, Core + Angular) #5937


User avatar
0
alexanderpilhar created

I'm having troubles implementing the 'action-menu' for table-items in a modal window. The action-menu should allow me to select actions such as editing and deleting translations for the selected entity. But instead of showing the dropdown with its menu-item, it just saves changes (I get a toast stating changes have been saved) and closes the modal window. Also there are warnings related to sweetalert2 shown in console.

I implemented the action-menu the same way it's done everywhere else ASPNETZERO. Already checked that for errors - unable to find any issues there. Also, I tried to implement it exactly as documented by ngx-bootstrap - doesn't help either.

For now, I switched to use separate buttons instead of the dropdown-menu. But I'd like to have the dropdown because of consistency.

Please, see if you can reproduce the problem (there is no such implementation in ASPNETZERO of a modal that implements a data-table with an action-menu for each data-item).


9 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @alexanderpilhar

    Your problem might be similar to https://github.com/aspnetzero/aspnet-zero-core/issues/1715.

    So, basically you need to use <a> tag instead of <button> for dropdown toggles.

  • User Avatar
    0
    alexanderpilhar created

    Hi @ismcagdas

    I replaced the &lt;button&gt; for the dropdownToggle with an &lt;a&gt; but that didn't work either ... It doesn't trigger submit anymore, but the menu still does not show.

    My guess is that is has something to do with the dropdown being part of a modal, which is not beeing displayed right from the beginning.

    I will post an update here, as soon as I found a solution.

  • User Avatar
    0
    mdframe created

    @alexanderpilhar - I have the same problem. I have traced it back to the z-index. The Modal has a Z-Index of 1050 and since this inherits from the container parent it only has 1000. I have done everything to get this changed but I still have the issue. I am able to get it show somewhat by removing the container="body" in the parent div. Here is my current code based on information here:

    <td style="width: 130px;" [hidden]="!isGrantedAny('Pages.PurchaseOrderDetails.Edit', 'Pages.PurchaseOrderDetails.Delete')"> <div class="btn-group dropdown" dropdown> <!-- REMOVED container="body" --> <a class="dropdown-toggle btn btn-sm btn-primary" dropdownToggle> <i class="fa fa-cog"></i><span class="caret"></span> {{l("Actions")}} </a> <ul id="test" class="dropdown-menu show" *dropdownMenu> <li> <a href="javascript:;" (click)="viewPurchaseOrderDetailModal.show(record)">{{l('View')}}</a> </li> <li> <a href="javascript:;" *ngIf="permission.isGranted('Pages.PurchaseOrderDetails.Edit')" (click)="createOrEditPurchaseOrderDetailModal.show(record.purchaseOrderDetail.purchaseOrderId)">{{l('Edit')}}</a> </li> <li> <a href="javascript:;" *ngIf="permission.isGranted('Pages.PurchaseOrderDetails.Delete')" (click)="deletePurchaseOrderDetail(record.purchaseOrderDetail)">{{l('Delete')}}</a> </li> </ul> </div> </td>

  • User Avatar
    0
    alexanderpilhar created

    @mdframe good find : )

    I managed to get what I wanted by simply adding an inline-style to the &lt;ul&gt;:

    <ul style="z-index:2000" class="dropdown-menu" *dropdownMenu>

    I'm not a big fan of inline-styles but as they can be found in some other places in ASPNETZERO as well, it will do.

    Thanks for your help @mdframe : )

  • User Avatar
    0
    mdframe created

    @alexanderpilhar - glad it worked out for you. I do the same and the problem persists. The action menu is even under the datatable footer. For some reason I just can't get the UL to the top. Would you share your complete action HTML so I can see if I have something different?

  • User Avatar
    0
    alexanderpilhar created

    @mdframe sure thing - here's the complete HTML of my modal component:

    <div bsModal #modalCategoryCreateOrEdit="bs-modal" (onShown)="onShown()" class="modal fade" tabindex="-1" role="dialog"
        aria-labelledby="modal" aria-hidden="true" [config]="{backdrop: 'static'}">
    
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
    
                <form *ngIf="active" role="form" #formCategoryCreateOrEdit="ngForm" novalidate (ngSubmit)="save()">
    
                    <div class="modal-header">
                        <h4 class="modal-title">
                            <span>{{modalTitle}}</span>
                        </h4>
                        <button type="button" class="close" style="cursor: pointer; line-height: normal;" (click)="close()">
                            <span class="fas fa-times" aria-hidden="true"></span>
                            <span class="sr-only">{{l('Shared.Action.Close')}}</span>
                        </button>
                    </div>
    
                    <div class="modal-body">
    
                        <!-- Add new Translation -->
                        <div class="form-group">
                            <button type="button" class="btn btn-default" (click)="createTranslation()">
                                <span class="fas fa-plus" aria-hidden="true"></span>
                                {{l("Shared.Action.Add")}}
                            </button>
                        </div>
    
                        <!-- Translations -->
                        <!--<Primeng-TurboTable-Start>-->
                        <div class="primeng-datatable-container" [busyIf]="primengTableHelper.isLoading">
    
                            <p-table #tableCategoryTranslations (onLazyLoad)="getTranslations($event)" [value]="primengTableHelper.records"
                                rows="{{primengTableHelper.defaultRecordsCountPerPage}}" [paginator]="false" [lazy]="true"
                                [responsive]="primengTableHelper.isResponsive">
    
                                <ng-template pTemplate="header">
                                    <tr>
                                        <th style="width: 135px">
                                            {{l('Shared.Actions')}}
                                        </th>
                                        <th>
                                            {{l('Translation.Name')}}
                                        </th>
                                        <th>
                                            {{l('Translation.Language')}}
                                        </th>
                                    </tr>
                                </ng-template>
    
                                <ng-template pTemplate="body" let-record="$implicit">
                                    <tr>
                                        <td style="width: 135px">
                                            <div class="btn-group dropdown" dropdown container="body">
                                                <a dropdownToggle href="javascript:;" class="dropdown-toggle btn btn-sm btn-primary">
                                                    <span class="fas fa-cog" aria-hidden="true"></span>
                                                    {{l("Shared.Actions")}}
                                                </a>
                                                <ul style="z-index: 2000" class="dropdown-menu" *dropdownMenu>
                                                    <li>
                                                        <a *ngIf="editTranslationCanExecute()" href="javascript:;" (click)="editTranslation(record)">
                                                            <span class="fas fa-edit" aria-hidden="true"></span>
                                                            {{l("Shared.Action.Edit")}}
                                                        </a>
                                                    </li>
                                                    <li>
                                                        <a *ngIf="deleteTranslationCanExecute()" href="javascript:;"
                                                            (click)="deleteTranslation(record)">
                                                            <span class="fas fa-trash" aria-hidden="true"></span>
                                                            {{l("Shared.Action.Delete")}}
                                                        </a>
                                                    </li>
                                                </ul>
                                            </div>
                                        </td>
                                        <td>
                                            {{record.name}}
                                        </td>
                                        <td>
                                            {{record.language | languageByISO: cultures}}
                                        </td>
                                    </tr>
                                </ng-template>
    
                            </p-table>
    
                            <div class="primeng-no-data" *ngIf="primengTableHelper.totalRecordsCount == 0">
                                {{l('NoData')}}
                            </div>
    
                            <div class="primeng-paging-container">
                                <p-paginator rows="{{primengTableHelper.defaultRecordsCountPerPage}}"
                                    #paginatorCategoryTranslations (onPageChange)="getTranslations($event)" [totalRecords]="primengTableHelper.totalRecordsCount"
                                    [rowsPerPageOptions]="primengTableHelper.predefinedRecordsCountPerPage">
                                </p-paginator>
                                <span class="total-records-count">
                                    {{l('TotalRecordsCount', primengTableHelper.totalRecordsCount)}}
                                </span>
                            </div>
    
                        </div>
                        <!--<Primeng-TurboTable-End>-->
    
                    </div>
    
                    <div class="modal-footer">
                        <button [disabled]="saving" type="button" class="btn btn-default" (click)="close()">
                            {{l("Shared.Action.Cancel")}}
                        </button>
    
                        <button type="submit" class="btn btn-primary blue" [disabled]="!formCategoryCreateOrEdit.form.valid"
                            [buttonBusy]="saving" [busyText]="l('SavingWithThreeDot')">
                            <span class="fas fa-save" aria-hidden="true"></span>
                            {{l("Shared.Action.Save")}}
                        </button>
                    </div>
    
                </form>
    
            </div>
        </div>
    
        <modal-category-translation-create-or-edit #modalCategoryTranslationCreateOrEdit>
        </modal-category-translation-create-or-edit>
    
    </div>
    

    Hope it's useful somehow!

  • User Avatar
    0
    mdframe created

    @alexanderpilhar - THANK YOU, THANK YOU! I see where I didn't have one of my class attributes set correctly and now its all working. I love your format. I have not seen the localization attributes prefixed like you have them. Is this to help group your items and I am assuming you modified all of your file. Is this beneficial to your organization?

  • User Avatar
    0
    alexanderpilhar created

    @mdframe - good to hear it was useful to you : )

    Yes, it is to group them, sort them and to make orientation easier in resource-files (no need to CTRL + F all the time). Also, it allows for more flexibility if needed (e.g. it's possible to set different values for properties of entities that share the same name: Entity1.PropertyName1 = "Value1" and Entity2.PropertyName1 = "Value2").

    I didn't touch the translations that come with ASPNETZERO - that's because I want to keep upgrading as easy as possible. I use my own scheme only for the stuff I add myself.

    Note, aspnetboilerplate suggests a different way of working with resource-files: https://aspnetboilerplate.com/Pages/Documents/Localization#best-practices

    Thankfully, with aspnetboilerplate and ASPNETZERO you can do whatever makes more sense to you : )

  • User Avatar
    0
    alexanderpilhar created

    Update My previous solution does not work in 6.9.1, Angular, .NET Framework. The dropdown will be displayed behind the modal window, no matter what value is set for z-index.

    Also, see https://github.com/valor-software/ngx-bootstrap/issues/5144

    Workaround

    <p-table ... [scrollable]="false" ... > <!-- no [scrollable]="true" -->
        ...
        <ng-template pTemplate="body" let-record="$implicit">
            <tr>
                <td>
                    <div class="btn-group dropdown" dropdown> <!-- no container="body" -->
                        <a ... >
                            ...
                        </a>
                        <ul class="dropdown-menu" *dropdownMenu> <!-- no style="z-index: 2000px;" -->
                            <li>
                                ...
                            </li>
                        </ul>
                    </div>
                </td>
                ...
            </tr>
        </ng-template>
    </p-table>