Is there an equivalent of html datalist in Xamarin.Forms, mechanism that would allow to select predefined values but also a free-text entry?

Viewed 343

We are building a Xamarin forms app.

One of the fields is supposed to be a select where you can pick one of the predefined values or enter a free text value like into the text field.

in HTML one would solve it by using <datalist>

    <input list="browsers" name="browser" id="browser">
    
    <datalist id="browsers">
      <option value="Edge">
      <option value="Firefox">
      <option value="Chrome">
      <option value="Opera">
      <option value="Safari">
    </datalist>

Is there an equivalent of HTML datalist control in Xamarin.Forms, that would allow selection of values and also a free-text entry?

If there isn't one, how is this sort of functionality (selection of values and also a free-text) achieved in iOS and Android? as it does feel like a quite common scenario.

3 Answers

Answer

I recommend using the Syncfusion.Xamarin.SfAutoComplete NuGet Package.

Note: Syncfusion can be used for Free via its Community License.

I've put together a sample app demonstrating how to use Syncfusion.Xamarin.SfAutoComplete: https://github.com/brminnick/AutoCompleteSample

Walkthrough

To view the completed code from this walkthrough, visit https://github.com/brminnick/AutoCompleteSample

1. Install Syncfusion.Xamarin.SfAutoComplete NuGet Package

  1. In Visual Studio, add the Syncfusion.Xamarin.SfAutoComplete NuGet Package to your iOS project, Android project and .NET Standard Project (if applicable).

2. Initialize Syncfusion.Xamarin.SfAutoComplete on iOS

  1. In the iOS Project, open AppDelegate.cs
  2. In the AppDelegate.cs file, in AppDelegate.FinishedLaunching method, add new Syncfusion.SfAutoComplete.XForms.iOS.SfAutoCompleteRenderer();, like so:
[Register(nameof(AppDelegate))]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        new Syncfusion.SfAutoComplete.XForms.iOS.SfAutoCompleteRenderer();

        global::Xamarin.Forms.Forms.Init();
        LoadApplication(new App());

        return base.FinishedLaunching(app, options);
    }
}

3. Use Syncfusion.Xamarin.SfAutoComplete in Xamarin.Forms

Here is an example of a Xamarin.Forms app using Syncfusion.Xamarin.SfAutoComplete:

using System.Collections.Generic;
using Syncfusion.SfAutoComplete.XForms;
using Xamarin.Forms;

namespace AutoCompleteSample
{
    public class App : Application
    {
        public App() => MainPage = new AutoCompletePage();
    }

    class AutoCompletePage : ContentPage
    {
        public AutoCompletePage()
        {
            Content = new SfAutoComplete
            {
                HeightRequest = 40,
                AutoCompleteSource = new List<string>
                {
                    "Edge",
                    "Firefox",
                    "Chrome",
                    "Opera",
                    "Safari",
                }
            };
        }
    }
}

Demo

This GIF was generated using this completed sample app: https://github.com/brminnick/AutoCompleteSample

enter image description here

Is there an equivalent of HTML datalist control in Xamarin.Forms, that would allow selection of values and also a free-text entry?

Xamarin.Forms don't have the same control, but you can create a custom control to have these features.

A custom control that contains Listview, Entry, and Stacklayout.

nuget XLabs.Forms

Install-Package XLabs.Forms -Version 2.0.5782

https://github.com/XLabs/Xamarin-Forms-Labs/blob/master/src/Forms/XLabs.Forms/Controls/AutoCompleteView.cs

Then using this custom control AutoCompleteView.

<ContentPage.Resources>
    <!--  this isn't working yet  -->
    <DataTemplate x:Key="SugestionItemTemplate">
        <ViewCell Height="60">
            <ViewCell.View>
                <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                    

                    <Label Text="{Binding .}" VerticalOptions="Center" />
                </StackLayout>
            </ViewCell.View>
        </ViewCell>
    </DataTemplate>
</ContentPage.Resources>
<ContentPage.Content>
    <StackLayout>
        <local:AutoCompleteView
            Placeholder="type 'firstname'"
            SearchCommand="{Binding SearchCommand}"
            SelectedItem="{Binding SelectedItem}"
            ShowSearchButton="False"
            SuggestionItemDataTemplate="{StaticResource SugestionItemTemplate}"
            Suggestions="{Binding Items, Mode=TwoWay}" />
    </StackLayout>
</ContentPage.Content>

Backing class

public class listviewmodel:ViewModelBase
{
    public ObservableCollection<string> Items { get; set; }
    private Command<string> _searchCommand;
    private string _selecteditem;

    public listviewmodel()
    {
        Items = new ObservableCollection<string>();
        Items.Add("cherry");
        Items.Add("cherry1");
        Items.Add("cherry2");
        Items.Add("cherry3");
        Items.Add("cherry4");
        Items.Add("wendy");
        Items.Add("barry");
        Items.Add("nico");
        Items.Add("leo");
    }
    public Command<string> SearchCommand
    {
        get
        {
            return _searchCommand ?? (_searchCommand = new Command<string>(
                obj => { },
                obj => !string.IsNullOrEmpty(obj.ToString())));
        }
    }


    public string SelectedItem
    {
        get
        {
            return _selecteditem;
        }
        set
        {
            _selecteditem = value;
            RaisePropertyChanged("SelectedItem");
        }
    }
}

The viewmodelbase is one class that implementing INotifyPropertyChanged.

public class ViewModelBase : INotifyPropertyChanged
{
    
    public event PropertyChangedEventHandler PropertyChanged;

    
    public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

The screenshot:

enter image description here

You can use the 'Xamarin Chips' component. for the reasons

  • it supports almost all layouts
  • has Input, Choice, Filter, and Action types of displays
  • you can select single, multiple choices or enter the new one
  • lots of UI customization options

https://help.syncfusion.com/xamarin/chips/overview

Regards, N Baua

Related