Open Closed

DropDownList Change Event Doesn't Seem to Trigger #3880


User avatar
0
dev1_premierpoint created

I have a few DropDownLists that I am trying to interconnect. I have 3 entities that I created with the entity creation tool. Entities 1 and 2 are credentials submitted by the user. Entity 3 uses both of these credentials to make calls out using those credentials to populate other dropdowns during the creation/edit of entity 3. I have 3 dropdowns. Drop 1 is populated by all submitted credentials for the current tenant. Same with dropdown 2. Once dropdown 2 is changed, a call needs to be made out to populate dropdown 3. I have tried to wire up multiple different DropDownList Events to a method in the razor.cs page, but none of them went on to hit my code that populates the dropdown. Once the code didn't seem to be working, I went to try to debug the event handler method, but it never catches a breakpoint.

onchange, onselect, and onselectionchange events have been tried for the DropDownList component.

CODE SNIPPETS RAZOR PAGE <DropdownList @ref="ddlSpoCred" TItem="SpoCredDto" TValue="int" Data="spoCredentials" TextField="@((item)=>item.AppID)" ValueField="@((item)=>item.Id)" @bind-SelectedValue="@selectedDropValueSPO" @onselect=OnSpoCredChange>Select Credential</DropdownList> <Field Horizontal> <FieldBody> Selected credential: @selectedDropValueSPO </FieldBody> <FieldBody> Credential Details: @spoCredentials?.FirstOrDefault(x=> x.Id == selectedDropValueSPO)?.AppID : @spoCredentials?.FirstOrDefault(x=> x.Id == selectedDropValueSPO)?.AzureTenantID </FieldBody> </Field>

RAZOR.CS private void OnSpoCredChange() { Console.WriteLine("In Drop Method"); spoCredSelected = true;

  PopulateGroupDropdownAsync();

}

Breakpoints set anywhere in the OnSpoCredChange method are not hit when the dropdown is changed with any of the previously listed events used.

  • ABP Framework version: v6.0
  • UI type: Blazor
  • Tiered (MVC)
  • Blazor Server

9 Answer(s)
  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Hi @dev1_premierpoint

    Can you try SelectedValueChanged property instead of onselect?

    For more information you can visit Blazorise DropdownList documentation https://blazorise.com/docs/extensions/dropdownlist

  • User Avatar
    0
    dev1_premierpoint created

    how does this interact with @bind-SelectedValue? Should I instead be using that to define the event's callback function?

    This is how I set up the selectedValueChanged suggested:

    <DropdownList @ref="ddlSpoCred" TItem="SpoCredDto" TValue="int" Data="spoCredentials" TextField="@((item)=>item.AppID)" ValueField="@((item)=>item.Id)" @bind-SelectedValue="@selectedDropValueSPO" SelectedValueChanged=OnSpoCredChange>Select Credential</DropdownList>

    This is the error I get for the new implementation:

    The component parameter 'SelectedValueChanged' is used two or more times for this component. Parameters must be unique (case-insensitive). The component parameter 'SelectedValueChanged' is generated by the '@bind-SelectedValue' directive attribute.

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    You can use SelectedValueChanged event and manage current selected item manually instead of using binding.

    Or, You can just use a regular encapsulation over your property. You can use setter of the selectedDropValueSPO property.

    I have an example for that:

    Index.razor

    <Card>
        <CardBody>
            <DropdownList @ref="dropdownRef"
                TItem="IndexItem" TValue="Guid"
                Data="IndexItems"
                @bind-SelectedValue="SelectedIndexItemId"
                TextField="@((item)=>item.Name)"
                ValueField="@((item)=>item.Id)"
                >Select Credential</DropdownList>
        </CardBody>
        <CardFooter>
            <p>
                @SelectedIndexItemId
            </p>
        </CardFooter>
    </Card>
    

    Index.razor.cs

    public partial class Index
    {
        protected DropdownList<IndexItem, Guid> dropdownRef;
        private Guid selectedIndexItemId;
    
        public List<IndexItem> IndexItems { get; set; } = new List<IndexItem>
        {
            new IndexItem(Guid.NewGuid(), "Item 1"),
            new IndexItem(Guid.NewGuid(), "Item 2"),
            new IndexItem(Guid.NewGuid(), "Item 3"),
            new IndexItem(Guid.NewGuid(), "Item 4"),
            new IndexItem(Guid.NewGuid(), "Item 5"),
        };
    
        public Guid SelectedIndexItemId
        {
            get => selectedIndexItemId;
            set {
                selectedIndexItemId = value;
                Logger.LogInformation("SelectedIndexItemIdChanged!");
            }
        }
    }
    

    And the result is:

  • User Avatar
    0
    dev1_premierpoint created

    I've been reworking the code to work with manually keeping up with the selected value instead. I was wondering if there was a way to use both the @bind and the selectedValueChanged event?

  • User Avatar
    0
    dev1_premierpoint created

    I guess that's more or less what you answered last time. Thanks for your help

  • User Avatar
    0
    dev1_premierpoint created

    You can use SelectedValueChanged event and manage current selected item manually instead of using binding.

    Or, You can just use a regular encapsulation over your property. You can use setter of the selectedDropValueSPO property.

    I have an example for that:

    Index.razor

    <Card> 
        <CardBody> 
            <DropdownList @ref="dropdownRef" 
                TItem="IndexItem" TValue="Guid" 
                Data="IndexItems" 
                @bind-SelectedValue="SelectedIndexItemId" 
                TextField="@((item)=>item.Name)" 
                ValueField="@((item)=>item.Id)" 
                >Select Credential</DropdownList> 
        </CardBody> 
        <CardFooter> 
            <p> 
                @SelectedIndexItemId 
            </p> 
        </CardFooter> 
    </Card> 
    

    Index.razor.cs

    public partial class Index 
    { 
        protected DropdownList<IndexItem, Guid> dropdownRef; 
        private Guid selectedIndexItemId; 
     
        public List<IndexItem> IndexItems { get; set; } = new List<IndexItem> 
        { 
            new IndexItem(Guid.NewGuid(), "Item 1"), 
            new IndexItem(Guid.NewGuid(), "Item 2"), 
            new IndexItem(Guid.NewGuid(), "Item 3"), 
            new IndexItem(Guid.NewGuid(), "Item 4"), 
            new IndexItem(Guid.NewGuid(), "Item 5"), 
        }; 
     
        public Guid SelectedIndexItemId 
        { 
            get => selectedIndexItemId; 
            set { 
                selectedIndexItemId = value; 
                Logger.LogInformation("SelectedIndexItemIdChanged!"); 
            } 
        } 
    } 
    

    And the result is:

    I actually do need to be able to using the await keyword in the "onSelectedValueChange" event, or in this case the setter. Any way that I can still do that with this method?

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    This is a Blazorise limitation. There is no event or async callback for selection change.

    But you can still use your async operation with Task.Run() as a workaround.

    public partial class Index
    {
        private Guid selectedIndexItemId;
        public Guid SelectedIndexItemId
        {
            get => selectedIndexItemId;
            set {
                selectedIndexItemId = value;
                Task.Run(OnDropdownSelected); // 👈
            }
        }
        
        public async Task OnDropdownSelected() // 👈
        {
            await Task.Delay(1000);
            Logger.LogInformation("OnDropdownSelected!");
        }
    }
    
  • User Avatar
    0
    dev1_premierpoint created

    This is a Blazorise limitation. There is no event or async callback for selection change.

    But you can still use your async operation with Task.Run() as a workaround.

    public partial class Index 
    { 
        private Guid selectedIndexItemId; 
        public Guid SelectedIndexItemId 
        { 
            get => selectedIndexItemId; 
            set { 
                selectedIndexItemId = value; 
                Task.Run(OnDropdownSelected); // 👈 
            } 
        } 
         
        public async Task OnDropdownSelected() // 👈 
        { 
            await Task.Delay(1000); 
            Logger.LogInformation("OnDropdownSelected!"); 
        } 
    } 
    

    My only issue with this method is that it doesn't seem to truly wait for the method to finish, or the Dropdownlist is not reloading after the methods return. After a user selects a previously created set of credentials in a dropdown, the programs takes the selected credentials and attempts to grab some information from Sharepoint Online and then populate the next dropdown. When I was able to use the await keyword it would populate correctly, but using Task.Run because await isn't possible in the setter, it doesn't populate on the first credentials selection. It populates if you select the credential a second time, but not the first. Is there any way to reload a dropdown other than StateHasChanged method as this is what Ihave used so far.

  • User Avatar
    0
    dev1_premierpoint created

    My only issue with this method is that it doesn't seem to truly wait for the method to finish, or the Dropdownlist is not reloading after the methods return. After a user selects a previously created set of credentials in a dropdown, the programs takes the selected credentials and attempts to grab some information from Sharepoint Online and then populate the next dropdown. When I was able to use the await keyword it would populate correctly, but using Task.Run because await isn't possible in the setter, it doesn't populate on the first credentials selection. It populates if you select the credential a second time, but not the first. Is there any way to reload a dropdown other than StateHasChanged method as this is what Ihave used so far.

    Seems like it needed to use InvokeAsync(StateHasChanged) to actually have the Dropdown reloaded at the right time.

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11