0

I want to access item.Id in @code { } below (while keeping it hidden from view). I don't understand how. Please send help!

I want to avoid using JS as much as possible that is why I am using Blazor in the first place.

I am not great at HTML so maybe there is a better way then using datalist?

Thank you!

{
    <input list="listings" id="listing" name="listing" autocomplete="on" placeholder="Search address..." @oninput="HandleInput" @onchange="HandleDatalistOnChange" />
    <datalist id="listings">
        @foreach (var item in listings)
        {
            <option id="@item.Id" value="@item.StreetAddress">@item.Municipality, @item.County</option>
        }
    </datalist>
    <button @onclick="GetProperty">Get</button>
}

@code {
    private ViewData[] listings;
    private string selectedViewData;

    protected override async Task OnInitializedAsync()
    {
        listings = await Http.GetFromJsonAsync<ViewData[]>("https://localhost:44315/api/listings");
    }

    private void GetProperty()
    {
        //@TODO get property from db using id
        Console.WriteLine(selectedViewData);
    }

    private async void HandleInput(ChangeEventArgs e)
    {
        var input = e.Value.ToString();
        if (input.Length > 0)
        {
            listings = await Http.GetFromJsonAsync<ViewData[]>("https://localhost:44315/api/listings/" + input);
            StateHasChanged();
            await Task.Delay(1);
        }
    }

    private void HandleDatalistOnChange(ChangeEventArgs e)
    {
        selectedViewData = e.Value.ToString();
        Console.WriteLine(selectedViewData);
    }

    public class ViewData
    {
        public int Id { get; set; }
        public string StreetAddress { get; set; }
        public string Municipality { get; set; }
        public string County { get; set; }
    }
}
6
  • 1
    Do you mean not having id="@item.Id" displayed in Html ? Just don't use it. You can still use ViewData.Id in code Commented Jul 15, 2020 at 21:27
  • I mean that I don't want the id to be displayed in the option so the user see it. They don't need it. But I need to get the selected option:s item.Id to get the entire object from the db. Commented Jul 15, 2020 at 21:34
  • 1
    Users wouldn't see the id attribute unless using developer tools in the browser. Is that what you're concerned about? Commented Jul 15, 2020 at 21:35
  • The only way I understand how to get the item.id id to @code {} is by displaying it in the value and using onchange to get the value attribute from the option element if that makes sense. but I dont want to put it in the value attribute cause then it is displayed to the user, and the user don't need to know the database id to select property. Commented Jul 15, 2020 at 21:37
  • 1
    But you have value="@item.StreetAddress" and not value="@item.Id", so how do you access the item.Id Commented Jul 15, 2020 at 22:09

3 Answers 3

0

You appear to be using Input HTML element which defaults to type text, with auto complete list. It may be better to use a Select HTML element instead. This way you can have the ID column hidden and a text field shown. Example Select:

    <select @bind="@listings.Id">
        <option value="">-</option>
        @if (listings != null)
        {
            @foreach (var item in listings)
            {
                @if (listings.Id == item.Id)
                {
                    <option selected value="@item.Id.ToString()">@item.AddressName</option>
                }
                else
                {
                    <option value="@item.Id.ToString()">@item.AddressName</option>
                }
            }
        }
    </select>

The problem with using a text input is the user can enter anything, it does not have to exist in the database. Therefore there is no way to get an ID.

Sign up to request clarification or add additional context in comments.

Comments

0

This is what I ended up using.

@page "/"

@inject HttpClient Http

<h1>Properties for sale</h1>

@if (listings == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <input list="listings" id="listing" name="listing" placeholder="Search address..." @oninput="HandleInput" @bind="selectedViewData" />
    <datalist id="listings">
        @foreach (var item in listings)
        {
            <option value="@item.location.address.streetAddress, @item.location.region.municipalityName, @item.location.region.countyName"/>
        }
    </datalist>
    <button @onclick="GetProperty">Get</button>
}

@code {
    [Parameter]
    public List<Listing> listings { get; set; }
    private string selectedViewData;

    protected override async Task OnInitializedAsync()
    {
        listings = await Http.GetFromJsonAsync<List<Listing>>("https://localhost:44315/api/listings");
    }

    private void GetProperty()
    {
        var listing = listings.Where(l => new String($"{l.location.address.streetAddress}, {l.location.region.municipalityName}, {l.location.region.countyName}").Equals(selectedViewData)).FirstOrDefault();
        Console.WriteLine(listing?.Id);
    }

    private async void HandleInput(ChangeEventArgs e)
    {
        var input = e.Value.ToString();
        if (listings.Any(l => new String($"{l.location.address.streetAddress}, {l.location.region.municipalityName}, {l.location.region.countyName}").Equals(input)))
        {
            return;
        }

        if (input.Length > 0)
        {
            listings = await Http.GetFromJsonAsync<List<Listing>>("https://localhost:44315/api/listings/" + input);
            StateHasChanged();
            await Task.Delay(1);
        }
    }
}

Comments

-1

You can't do it, see this answer https://stackoverflow.com/a/39338752/184405

An alternative is for example to use the open source component library MatBlazor https://www.matblazor.com/Select

<MatSelect Label="Pick a Food Group" @bind-Value="value1">
        <MatOptionString ></MatOptionString>
        <MatOptionString Value="grains">Bread, Cereal, Rice, and Pasta</MatOptionString>
        <MatOptionString Value="vegetables">Vegetables</MatOptionString>
        <MatOptionString Value="fruit">Fruit</MatOptionString>
    </MatSelect>

    <span>@value1</span>

    @code
    {
        string value1;
    }

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.