Skip 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.

raised exception class EfgPresentation with message 'Не могу создать нативный контрол для класса [TfgEditNumber]. Аллокатора для этого класса нету в фабрике'

Featured Replies

unit NumberEdit;

interface
uses
  System.SysUtils, System.Classes,System.Character,
  FGX.Edit,FGX.Text, FGX.Types,FGX.Consts;

type
  [ComponentPlatformsAttribute(fgMobilePlatforms)]
  TfgEditNumber = class(TfgEdit)
  private
    FDecimalSeparator: Char;
    FThousandSeparator: Char;
    FCurrencySymbol: string;
    FAllowDecimal: Boolean;
    procedure FormatNumber;
    procedure DoTextChanged(Sender: TObject);
    function CleanNumber(const S: string): string;
  public
    constructor Create(AOwner: TComponent); override;
    property ThousandSeparator: Char read FThousandSeparator write FThousandSeparator;
    property DecimalSeparator: Char read FDecimalSeparator write FDecimalSeparator;
    property CurrencySymbol: string read FCurrencySymbol write FCurrencySymbol;
    property AllowDecimal: Boolean read FAllowDecimal write FAllowDecimal;
  end;

implementation
   uses FGX.ClassStorage;
{ TfgEditNumber }

constructor TfgEditNumber.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Self.OnChanged := DoTextChanged;
  Self.KeyboardType := TfgKeyboardType.NumbersAndPunctuation;

  // Default Settings
  FThousandSeparator := ',';   // Default: Comma separator
  FDecimalSeparator := '.';    // Default: Dot as decimal
  FCurrencySymbol := '';       // No currency by default
  FAllowDecimal := True;       // Allow decimal numbers
end;

// Remove Non-Numeric Characters Except Decimal Point
function TfgEditNumber.CleanNumber(const S: string): string;
var
  C: Char;
  DecimalCount: Integer;
begin
  Result := '';
  DecimalCount := 0;

  for C in S do
  begin
    if C.IsDigit then
      Result := Result + C
    else if (C = FDecimalSeparator) and (FAllowDecimal) and (DecimalCount = 0) then
    begin
      Result := Result + C;
      Inc(DecimalCount);
    end;
  end;
end;

// Format Number with Custom Separators and Currency
procedure TfgEditNumber.FormatNumber;
var
  NumStr, FormattedStr: string;
  Value: Double;
  DecimalPart: string;
begin
  NumStr := CleanNumber(Self.Text);

  if NumStr.IsEmpty then Exit;

  if FAllowDecimal and (Pos(FDecimalSeparator, NumStr) > 0) then
  begin
    DecimalPart := Copy(NumStr, Pos(FDecimalSeparator, NumStr), MaxInt);
    NumStr := Copy(NumStr, 1, Pos(FDecimalSeparator, NumStr) - 1);
  end
  else
    DecimalPart := '';

  if TryStrToFloat(NumStr, Value) then
    FormattedStr := FormatFloat('#' + FThousandSeparator + '##0', Value)
  else
    FormattedStr := NumStr;

  FormattedStr := FCurrencySymbol + FormattedStr + DecimalPart;

  if Self.Text <> FormattedStr then
  begin
    Self.OnChanged := nil; // Prevent recursion
    Self.Text := FormattedStr;
    Self.OnChanged := DoTextChanged;
  end;
end;

// Handle Text Change Event
procedure TfgEditNumber.DoTextChanged(Sender: TObject);
begin
  FormatNumber;
end;

initialization
  TfgClassStorage.RegisterClasses([TfgEditNumber]);
end.

I got this error on this line :   LEdit:=TfgEditNumber.Create(Self);

  • Administrators

Hello @SALONA

When creating a native control (view), by default it will be searched in the TfgNativeControlFactory according to the name of the platform-independent class (TfgEditNumber in your case).

There are two options:
1. Directly registering-linking the control with the view for all platforms. For example:

TfgNativeControlFactory.Register(TfgEditNumber, TfgiOSControl.CreateHandle<TfgiOSEdit>);


2. You can specify that your control will be used by the view from TfgEdit, since you do not actually touch the native controls - views.

  TfgEditNumber = class(TfgEdit)
  private
...
  protected
    function DefineNativeControlName: string; override;
  public

function TfgEditNumber.DefineNativeControlName: string;
begin
  Result := 'TfgEdit';
end; 

I recommend that you use the second option.

 

Thank you.

  • Administrators

Hello,

Any visual control in FGX Native consists from 2 parts:

  1. Crossplatform heirs from TfgControl
  2. NativeControl - implementation of control (1) on each platform Android/iOS.

When TfgControl is being allocated, it request Native Control class implementor on current platform from FGX.Controls.Factory.TfgNativeControlFactory.

constructor TfgControl.Create(AOwner: TComponent);
begin
  inherited;
 // skipped lines
  FHandle := TfgNativeControlFactory.CreatePresentation(DefineNativeControlName, Self);

By default native controls implementors are registered in TfgNativeControlFactory by control class name.

function TfgControl.DefineNativeControlName: string;
begin
  Result := ClassName;
end;

TfgEdit has 2 implementors FGX.Edit.iOS.TfgiOSEdit for iOS and  FGX.Edit.Android.TfgAndroidEdit for the Android.

The typical registration can be looks like:

initialization
  TfgNativeControlFactory.Register(TfgEdit, TfgiOSControl.CreateHandle<TfgiOSEdit>);

initialization    
  TfgNativeControlFactory.Register(TfgEdit, TfgAndroidControl.CreateHandle<TfgAndroidEdit>);

Since you introduced new control, TfgNativeControlFactory doesn't know about who is implementing native parts for iOS and Android.

There are 2 possible ways:

  1. If your implementation doesn't work with native control (your case). You can tell point on using existed implementor from TfgEdit. So just add this method:
      TfgEditNumber = class(TfgEdit)
      protected
        function DefineNativeControlName: string; override;
    
    
    function TfgEditNumber.DefineNativeControlName: string;
    begin
      Result := TfgEdit.ClassName;
    end;

    So your implementation will request default implementor for TfgEdit class.

  2. If you are interact and need to extend native controls implementation, so you need to create 2 different heirs from TfgiOSEdit and TfgAndroidEdit and register them in TfgNativeControlFactory.

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Search

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.