We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Create a field with SfTextInputLayout that opens SfPopup when tapped

I create an input view using SfTextInputLayout.
When user taps one field, I want to display SfPopup to select the value. When the user selects a value in SfPopup, the selected value is displayed in the field.

First, I tried to set a disabled entry. However, the text color of Entry is gray.
Next, I tried to set a label. However, since SfTextInputLayout does not support labels, the layout is corrupted and hint text is not displayed correctly when the value is empty.

Anyone have a good idea?

7 Replies

LR Lakshmi Radha Krishnan Syncfusion Team August 27, 2019 03:07 AM UTC

Hi Ikunori,

 

Greetings from Syncfusion.

 

We have achieved your requirement using the SfPopUpLayout, please refer the below code snippet for your reference. We have attached the sample, please download it from the below location.

 

Code Snippet:

 

Xaml:

    <Grid Margin="10,50,10,10">
                    <inputLayout:SfTextInputLayout
                        x:Name="birthdayLayout"
                        ContainerType="Outlined"
                        HelperText="Enter your date of birth"
                        Hint="Birth date"
                        LeadingViewPosition="Outside"
                        TrailingViewPosition="Inside">

                        <Entry x:Name="dateOfBirth" Text="{Binding MonthName, Mode=TwoWay}" />

                        <inputLayout:SfTextInputLayout.TrailingView>
                            <Label
                                FontSize="18"
                                Text="D"
                                VerticalTextAlignment="Center">

                                <Label.GestureRecognizers>
                                    <TapGestureRecognizer x:Name="labelGesture" Tapped="GestureRecognizer_Tapped" />
                                </Label.GestureRecognizers>

                                <Label.FontFamily>
                                    <OnPlatform x:TypeArguments="x:String">
                                        <On Platform="iOS" Value="InputLayoutIcons" />
                                        <On Platform="Android" Value="InputLayoutIcons.ttf#InputLayoutIcons" />
                                        <On Platform="UWP" Value="/Assets/Fonts/InputLayoutIcons.ttf#InputLayoutIcons" />
                                    </OnPlatform>
                                </Label.FontFamily>
                            </Label>
                        </inputLayout:SfTextInputLayout.TrailingView>
                    </inputLayout:SfTextInputLayout>

                    <sfPopup:SfPopupLayout IsVisible="false" x:Name="popupLayout">
                        <sfPopup:SfPopupLayout.PopupView>
                        <sfPopup:PopupView HeightRequest="230"
                           HeaderTitle="Month List"
                           ShowFooter="False">
                                <sfPopup:PopupView.ContentTemplate>
                                    <DataTemplate>
                                        <StackLayout x:Name="mainLayout">
                                            <ListView ItemsSource="{Binding NamesList}" ItemSelected="Handle_ItemSelected">
                                                <ListView.ItemTemplate>
                                                    <DataTemplate>
                                                        <ViewCell>
                                                            <Label Text="{Binding Name, Mode=TwoWay}" />
                                                        </ViewCell>
                                                    </DataTemplate>
                                                </ListView.ItemTemplate>
                                            </ListView>
                                        </StackLayout>
                                    </DataTemplate>
                                </sfPopup:PopupView.ContentTemplate>
                            </sfPopup:PopupView>
                        </sfPopup:SfPopupLayout.PopupView>
                    </sfPopup:SfPopupLayout>
                </Grid>

 

 

C#:

  private void GestureRecognizer_Tapped(object sender, System.EventArgs e)
  {
            popupLayout.IsOpen = true;
            popupLayout.Focus();
  }

  void Handle_ItemSelected(object sender, Xamarin.Forms.SelectedItemChangedEventArgs e)
  {
            viewModel.MonthName = (e.SelectedItem as Model).Name;
            popupLayout.IsOpen = false

   }

 

 public class ViewModel : INotifyPropertyChanged
 {
        public ObservableCollection<Model> NamesList { getset; }

        public event PropertyChangedEventHandler PropertyChanged;

        private string monthName;

        public string MonthName
        {
            get { return monthName; }
            set
            {
                monthName = value;
                NotifyPropertyChanged();
            }
        }

        public ViewModel()
        {
            NamesList = new ObservableCollection<Model>()
            {
               new Model(){ Name = "January" },
                new Model(){ Name = "February" },
                 new Model(){ Name = "March" },
                  new Model(){ Name = "April" },
                   new Model(){ Name = "May" },
            }; 
  }

  private void NotifyPropertyChanged([CallerMemberNameString propertyName = "")
  {
            PropertyChanged?.Invoke(thisnew PropertyChangedEventArgs(propertyName));
        }
   }

    public class ModelINotifyPropertyChanged
    {
        private string name;

        public string Name
        {
            get { return name; }
            set
            {
                name = value;
                NotifyPropertyChanged();
            } 
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberNameString propertyName = "")
        {
            PropertyChanged?.Invoke(thisnew PropertyChangedEventArgs(propertyName));
        }
    }

 

 

 

Please let us know if your need further assistance on this.

 

Regards,

Lakshmi R.

 


Attachment: TILPopUpSample_1e35b5cc.zip


IK Iku August 29, 2019 01:45 AM UTC

Hi Lakshmi,
Thank you for your reply and sample.

Unfortunately, my customer requirements are a little different.
We don't want the user to enter a value other than the popup choice. This is why we tried a disabled entry or label.
The most desirable is to open the Popup when the field is tapped, just as the user tries to do keyboard input.

Do you have any ideas that meet this requirement?
I know that SfTextInputLayout only supports Input fields, and this is an unreasonable request.
If you say it is impossible or tough, I will convince the customer.

Regards


RA Rachel A Syncfusion Team August 29, 2019 12:48 PM UTC

Hi Ikunori, 
 
We have disabled the Entry state by setting IsReadOnly property to true and achieved the touch action for the disable state Entry using the TapGesture. Please refer the below code snippet and sample. 
 
[XAML] 
<StackLayout Margin="10,50,10,10"> 
              <inputLayout:SfTextInputLayout 
                        x:Name="birthdayLayout" 
                        ContainerType="Outlined" 
                        HelperText="Tap the input field to enter text"> 
                 <StackLayout> 
                        <Entry TextColor="Black" IsReadOnly="True" InputTransparent="True"  x:Name="layoutEntry" Text="{Binding Text, Mode=TwoWay}" /> 
                            <StackLayout.GestureRecognizers> 
                                <TapGestureRecognizer x:Name="entryGesture" 
                                      Tapped="GestureRecognizer_Tapped" /> 
                            </StackLayout.GestureRecognizers> 
                     </StackLayout> 
              </inputLayout:SfTextInputLayout> 
                    <sfPopup:SfPopupLayout IsVisible="false" x:Name="popupLayout"> 
                        <sfPopup:SfPopupLayout.PopupView> 
                        <sfPopup:PopupView HeightRequest="230" 
                           HeaderTitle="Enter the text" 
                           ShowFooter="False"> 
                                <sfPopup:PopupView.ContentTemplate> 
                                    <DataTemplate> 
                                        <StackLayout x:Name="mainLayout"> 
                                            <Entry Focused="PopUpEntry_Focused" Text="{Binding Text, Mode=TwoWay}" IsEnabled="True" x:Name="popUpEntry"/> 
                                        </StackLayout> 
                                    </DataTemplate> 
                                </sfPopup:PopupView.ContentTemplate> 
                            </sfPopup:PopupView> 
                        </sfPopup:SfPopupLayout.PopupView> 
                    </sfPopup:SfPopupLayout> 
        </StackLayout> 
  
 
C#: 
public partial class Sample : ContentPage 
    { 
        public Sample() 
        { 
            InitializeComponent(); 
        } 
        private void PopUpEntry_Focused(object sender, FocusEventArgs e) 
        { 
            viewModel.Text = (sender as Entry).Text; 
        } 
        private void GestureRecognizer_Tapped(object sender, System.EventArgs e) 
        { 
            popupLayout.IsOpen = true; 
            popupLayout.Focus(); 
        } 
    } 
    public class ViewModel : INotifyPropertyChanged 
    { 
        public event PropertyChangedEventHandler PropertyChanged; 
        private string text; 
        public string Text 
        { 
            get { return text; } 
            set 
            { 
                text = value; 
                NotifyPropertyChanged(); 
            } 
        } 
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
        { 
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
        } 
    } 
 
 
Please let us know if your requirement is different from this. 
 
Regards, 
Rachel. 



IK Iku August 30, 2019 02:17 AM UTC

Hi Rachel,

Your sample is amazing!
I didn't know the IsReadOnly property, embarrassingly.

I made some changes to your sample and implemented it in my app.
In my app, my customer told me not to change the value on the back screen until the user taps OK on Popup, so I separate Popup's ViewModel from the screen's ViewModel.
Popup is called in the code-behind of the screen, and when OK is tapped, the value is reflected from the Popup ViewModel to the screen ViewModel.
At first I tried the method of putting Entry into Stacklayout as your sample, but on iOS, tapping OK did not reflect the value.
(To be exact, the caption did not move up, and the selected value was displayed slightly behind it.)

Finally, the code that worked is the following:

<inputLayout:SfTextInputLayout Hint="Birthday" >
        <Entry Text="{Binding Birthday, Converter={StaticResource dateFormatJa}}" IsReadOnly="True">
            <Entry.GestureRecognizers>
                <TapGestureRecognizer Command="{Binding SelectBirthdayCommand}" />
            </Entry.GestureRecognizers>
        </Entry>
</inputLayout:SfTextInputLayout>

Thank you very much for your support.


RA Rachel A Syncfusion Team August 30, 2019 04:44 AM UTC

Hi Ikunori, 
 
Thanks for the update. 
 
Please let us know if you have any other queries. 
 
Thanks, 
Rachel. 



IK Iku August 30, 2019 06:49 AM UTC

Sorry, my source was incomplete.
On Android, it didn't work unless Entry was added to the layout such as Stacklayout.
For someone who sees here later, I will leave my final source.

<inputLayout:SfTextInputLayout Hint="Birthday">
    <OnPlatform x:TypeArguments="View">
        <On Platform="iOS">
            <Entry Text="{Binding Birthday, Converter={StaticResource dateFormatJa}}" IsReadOnly="True">
                <Entry.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding SelectBirthdayCommand}" />
                </Entry.GestureRecognizers>
            </Entry>
        </On>
        <On Platform="Android">
            <Grid>
                <Entry Text="{Binding Birthday, Converter={StaticResource dateFormatJa}}" IsReadOnly="True" InputTransparent="True" />
                <Grid.GestureRecognizers>
                    <TapGestureRecognizer Command="{Binding SelectBirthdayCommand}" />
                </Grid.GestureRecognizers>
            </Grid>
        </On>
    </OnPlatform>
</inputLayout:SfTextInputLayout>


RA Rachel A Syncfusion Team September 2, 2019 04:53 AM UTC

Hi Ikunori, 
 
Thanks for sharing the code. 
 
Please let us know if you need any further assistance. 
 
Thanks, 
Rachel. 


Loader.
Live Chat Icon For mobile
Up arrow icon