Jump to content
View in the app

A better way to browse. Learn more.

FGX Native

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
  • Status: Open
  • Priority: Major
  • Resolution: Unresolved
  • Platform: Android
  • Affects version 1.16.1.0

При выборе значения из списка подсказок, когда их несколько и только не самую первую (точнее не "нулевую") возникает ошибка : "Значение [index] не попадает в требуемый диапазон [0, 0]". Index в данном случае принимает число, которое является индексом по порядку в списке (т.е. для второго значения в списке это будет 1, для 3-го - 2 итд).

Примерчик набросал, можно воспроизвести.

20230828.zip

User Feedback

Recommended Comments

  • Administrators

Добрый вечер,

Что вводить в поле ввода? чтобы было больше чем одна строка в списке

  • Administrators

Любопытно. Ошибка связана с тем, что при выборе элемента из списка происходит следующее:

  1. Вначале выполняется подстановка текста, что приводит к вызову события OnChanging.
  2. В OnChanging вы формируете список элементов заново.
  3. Вызывается событие OnSuggestionSelected, где уже список для подстановки другой.
  • Administrators

Самое интересно, что так работает Андроид. У него явно нарушение причинно-следственной связи 🙂 

image.png

dervish00

Active subscription
(edited)
9 часов назад, Yaroslav Brovin сказал:

Самое интересно, что так работает Андроид. У него явно нарушение причинно-следственной связи 🙂 

Звучит неутешительно ))) Думаю, от гугла долго придётся ждать исправления.

Попробую во время обработки занилить обработчик события OnChanging

 

PS. Не помогло.

Edited by dervish00

dervish00

Active subscription
procedure TFormMain.fgAutoCompleteEdit1Changing(Sender: TObject);
begin
   if fgAutoCompleteEdit1.Text.Length = 2 then begin
      FillSuggestionsList;
      fgAutoCompleteEdit1.Filtered := True;
   end
   else if fgAutoCompleteEdit1.Text.Length < 2 then begin
      fgAutoCompleteEdit1.Filtered := False;
      fgAutoCompleteEdit1.Suggestions.ClearAndResetID;
   end;
end;

procedure TFormMain.FillSuggestionsList;
var
   i : integer;

begin
   fgAutoCompleteEdit1.Suggestions.ClearAndResetID;
   GetListSuggestions(ListTest, fgAutoCompleteEdit1.Text);
   if ListTest.Count > 0 then begin
      fgAutoCompleteEdit1.Suggestions.BeginUpdate;
      for i := 0 to ListTest.Count - 1 do
         fgAutoCompleteEdit1.Suggestions.Add(ListTest[i].text).Id := ListTest[i].id.ToString;
      fgAutoCompleteEdit1.Suggestions.EndUpdate;
   end;
end;

однократной загрузкой списка подсказок и включением фильтрации проблема решается, но для большого списка подсказок возможны подтормаживания.

dervish00

Active subscription
Спойлер
unit Form.Main;

interface

{$SCOPEDENUMS ON}

uses
  System.Types, System.Classes, FGX.Forms, FGX.Forms.Types, FGX.Controls, FGX.Controls.Types, FGX.Layout, 
  FGX.Layout.Types, FGX.ComboBox, FGX.AutocompleteEdit.Types, FGX.Edit,
  FGX.AutoCompleteEdit, System.Generics.Collections;

type
  TTestAutoCompleated = record
     id : integer;
     text : string;
  end;

  TFormMain = class(TfgForm)
    fgAutoCompleteEdit1: TfgAutoCompleteEdit;
    procedure fgFormCreate(Sender: TObject);
    procedure fgFormDestroy(Sender: TObject);
    procedure fgAutoCompleteEdit1Changing(Sender: TObject);
  private
    { Private declarations }
    ListTest : TList<TTestAutoCompleated>;
    FSavedText : string;
    procedure FillSuggestionsList;
  public
    { Public declarations }
  end;

var
  FormMain: TFormMain;

const
   DBModel : array[0..9] of TTestAutoCompleated = (
      (id :  1; text : 'а'),
      (id :  2; text : 'аб'),
      (id :  3; text : 'абв'),
      (id :  4; text : 'абвг'),
      (id :  5; text : 'абвгд'),
      (id :  6; text : 'абвгде'),
      (id :  7; text : 'абвгдеж'),
      (id :  8; text : 'абвгдежз'),
      (id :  9; text : 'абвгдежзи'),
      (id : 10; text : 'абвгдежзик')
   );

   LengthTextForShowSuggestion = 2;

implementation

{$R *.xfm}

uses
  System.SysUtils,
  FGX.Application,
  FGX.Dialogs,
  FGX.Log;

procedure GetListSuggestions(var ListSuggestions : TList<TTestAutoCompleated>; Pattern : string);
var
   lTest : TTestAutoCompleated;
   i : integer;

begin
   ListSuggestions.Clear;
   for i := Low(DBModel) to High(DBModel) do
      if AnsiPos(AnsiUpperCase(Pattern), AnsiUpperCase(DBModel[i].text)) > 0 then begin
         lTest.id := DBModel[i].id;
         lTest.text := DBModel[i].text;
         ListSuggestions.Add(lTest);
      end;
end;

procedure TFormMain.fgAutoCompleteEdit1Changing(Sender: TObject);
var
   WasBackspace : boolean;

begin
   WasBackspace := ((fgAutoCompleteEdit1.Text.Length < FSavedText.Length) and (fgAutoCompleteEdit1.Text.Length > LengthTextForShowSuggestion));
   FSavedText := fgAutoCompleteEdit1.Text;
   if (fgAutoCompleteEdit1.Text.Length = LengthTextForShowSuggestion) or WasBackspace then begin
      FillSuggestionsList;
      fgAutoCompleteEdit1.Filtered := True;
   end
   else if fgAutoCompleteEdit1.Text.Length < LengthTextForShowSuggestion then begin
      fgAutoCompleteEdit1.Filtered := False;
      fgAutoCompleteEdit1.Suggestions.ClearAndResetID;
   end;
end;

procedure TFormMain.FillSuggestionsList;
var
   i : integer;

begin
   fgAutoCompleteEdit1.Suggestions.ClearAndResetID;
   GetListSuggestions(ListTest, fgAutoCompleteEdit1.Text);
   if ListTest.Count > 0 then begin
      fgAutoCompleteEdit1.Suggestions.BeginUpdate;
      for i := 0 to ListTest.Count - 1 do
         fgAutoCompleteEdit1.Suggestions.Add(ListTest[i].text).Id := ListTest[i].id.ToString;
      fgAutoCompleteEdit1.Suggestions.EndUpdate;
   end;
end;

procedure TFormMain.fgFormCreate(Sender: TObject);
begin
   inherited;
   ListTest := TList<TTestAutoCompleated>.Create;
   FSavedText := '';
end;

procedure TFormMain.fgFormDestroy(Sender: TObject);
begin
   FreeAndNil(ListTest);
   inherited;
end;

end.

 

Изменил для правильного отслеживания ситуации, когда уменьшаем длину текста. Работает.

  • Administrators

Самое простое решение - это завернуть код заполнения подсказок в TThread.ForceQueue. Тем самым будет гарантироваться вызов заполнения списка после выбора элемента.

dervish00

Active subscription

А вот с этого момента поподробнее )))

Ярослав, нарисуйте скелет обёртки?

  • Administrators
TThread.ForceQueue(nil, procedure 
begin
// Тут заполняете список
end);

Вызываете этот код из события OnChanging.

dervish00

Active subscription

Спасибо. Попробую.

dervish00

Active subscription
(edited)
procedure TFormMain.fgAutoCompleteEdit1Changing(Sender: TObject);
begin
   TThread.ForceQueue(nil, procedure
      begin
         if fgAutoCompleteEdit1.Text.Length >= LengthTextForShowSuggestion then
            FillSuggestionsList;
      end);
end;

 

Попробовал. Нет, работает не как ожидается. Список подхватывает неправильно с опозданием и вываливается с ошибкой диапазона. 

Edited by dervish00

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.