Quellcode durchsuchen

* Bootstrap toast manager component

michael vor 5 Jahren
Ursprung
Commit
63cf3a6ae9
1 geänderte Dateien mit 384 neuen und 0 gelöschten Zeilen
  1. 384 0
      packages/bootstrap/bootstrapwidgets.pp

+ 384 - 0
packages/bootstrap/bootstrapwidgets.pp

@@ -0,0 +1,384 @@
+{
+    This file is part of the Pas2JS run time library.
+    Copyright (C) 2019 Michael Van Canneyt
+
+    extra Bootstrap widgets
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+unit bootstrapwidgets;
+
+{$mode objfpc}
+
+interface
+
+uses
+  Classes, SysUtils, js, libjquery, libbootstrap, web, webwidget;
+
+Type
+
+  { TSimpleToastWidget }
+  TContextual = (cNone,cPrimary,cSecondary,cSuccess,cDanger,cWarning,cInfo,cLight,cDark);
+
+  TSimpleToastWidget = Class(TCustomTemplateWidget)
+  private
+    FAnimate: Boolean;
+    FAutoHide: Boolean;
+    FBody: String;
+    FBoolean: Boolean;
+    FContextual: TContextual;
+    FHeader: String;
+    FHeaderImage: String;
+    FHideDelay: Integer;
+    FMinWidth: Integer;
+    FSmallHeader: String;
+    procedure SetAnimate(AValue: Boolean);
+    procedure SetAutoHide(AValue: Boolean);
+    procedure SetBody(AValue: String);
+    procedure SetBoolean(AValue: Boolean);
+    procedure SetContextual(AValue: TContextual);
+    procedure SetHeader(AValue: String);
+    procedure SetHeaderImage(AValue: String);
+    procedure SetHideDelay(AValue: Integer);
+    procedure SetMinWidth(AValue: Integer);
+    procedure SetSmallHeader(AValue: String);
+  Protected
+    function BodyHTML: String; virtual;
+    function CloseButtonHTML: String; virtual;
+    function HeaderHTML: String; virtual;
+    Function GetTemplateHTML: String; override;
+    Function DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement; override;
+  Public
+    Constructor Create(aOwner : TComponent); override;
+    Procedure Hide;
+  Published
+    Property Header : String Read FHeader Write SetHeader;
+    Property SmallHeader : String Read FSmallHeader Write SetSmallHeader;
+    Property Body : String Read FBody Write SetBody;
+    Property HeaderImage : String Read FHeaderImage Write SetHeaderImage;
+    Property CloseButton : Boolean Read FBoolean Write SetBoolean;
+    Property Contextual : TContextual Read FContextual write SetContextual;
+    Property HideDelay : Integer Read FHideDelay Write SetHideDelay default 2000;
+    Property AutoHide : Boolean Read FAutoHide Write SetAutoHide default True;
+    Property Animate : Boolean Read FAnimate Write SetAnimate default False;
+    Property MinWidth : Integer Read FMinWidth Write SetMinWidth default 200;
+  end;
+
+  // Encapsulates the global tag where the toasts are shown.
+
+  { TToastManager }
+
+  TToastManager = Class(TWebWidget)
+  Private
+    FAnimate: Boolean;
+    FAutoHide: Boolean;
+    FHideDelay: Integer;
+    FMinheight: Integer;
+    FMinWidth: Integer;
+    FMultiToast: Boolean;
+    FContentElement : TJSHTMLElement;
+    FToastIcon: String;
+    class var
+      _instance : TToastManager;
+    procedure CheckInit;
+    procedure SetMinHeight(AValue: Integer);
+    procedure SetMultiToast(AValue: Boolean);
+   Protected
+    Class Function DefaultParentElement : TJSHTMLElement; override;
+    Function DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement; override;
+    Function GetContentElement: TJSHTMLELement; override;
+    Procedure InvalidateElement; override;
+    Function HTMLTag: String; override;
+  Public
+    Constructor Create(aOwner : TComponent); override;
+    class function Instance : TToastManager;
+    function ShowToast(const aHeader, aBody: String; aContext: TContextual=cNone; Closable: Boolean=True): TSimpleToastWidget;
+  Published
+    Property MultiToast : Boolean Read FMultiToast Write SetMultiToast;
+    Property MinHeight : Integer Read FMinheight Write SetMinHeight default 250;
+    Property ToastHideDelay : Integer Read FHideDelay Write FHideDelay default 2000;
+    Property ToastAutoHide : Boolean Read FAutoHide Write FAutoHide default True;
+    Property ToastAnimate : Boolean Read FAnimate Write FAnimate default False;
+    Property ToastMinWidth : Integer Read FMinWidth Write FMinWidth default 200;
+    Property ToastIcon : String Read FToastIcon Write FToastIcon;
+  end;
+
+Const
+  ContextualNames : Array[TContextual] of string = ('','primary','secondary','success','danger','warning','info','light','dark');
+
+Function Toasts : TToastManager;
+
+Implementation
+
+function Toasts: TToastManager;
+begin
+  Result:=TToastManager.Instance;
+end;
+
+{ TToastManager }
+
+class function TToastManager.Instance: TToastManager;
+begin
+  if _instance=Nil then
+   _instance:=TToastManager.Create(Nil);
+  Result:=_instance;
+end;
+
+procedure TToastManager.CheckInit;
+
+begin
+  if not IsRendered then
+    Refresh;
+end;
+
+procedure TToastManager.SetMinHeight(AValue: Integer);
+begin
+  if FMinheight=AValue then Exit;
+  FMinheight:=AValue;
+  if IsRendered then
+    Refresh;
+end;
+
+procedure TToastManager.SetMultiToast(AValue: Boolean);
+begin
+  if FMultiToast=AValue then Exit;
+  FMultiToast:=AValue;
+  if IsRendered then refresh;
+end;
+
+class function TToastManager.DefaultParentElement: TJSHTMLElement;
+begin
+  Result:=TJSHTMLElement(Document.body);
+end;
+
+function TToastManager.DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement;
+
+Var
+  El : TJSHTMLElement;
+
+begin
+  Result:=AElement;
+  Result['aria-live']:='polite';
+  Result['aria-atomic']:='true';
+  Result['style']:='position: relative; min-height: '+IntToStr(MinHeight)+'px;';
+  if not MultiToast then
+    FContentElement:=Result
+  else
+    begin
+    El:=CreateElement('div',ElementID+'-multi');
+    El['style']:='position: absolute; top: 0; right: 0;';
+    FContentElement:=El;
+    Result.AppendChild(El);
+    end;
+end;
+
+function TToastManager.GetContentElement: TJSHTMLELement;
+begin
+  Result:=FContentElement;
+  if (Result=Nil) then
+    Result:=Element;
+end;
+
+procedure TToastManager.InvalidateElement;
+begin
+  inherited;
+  FContentElement:=nil;
+end;
+
+
+function TToastManager.HTMLTag: String;
+begin
+  Result:='div';
+end;
+
+constructor TToastManager.Create(aOwner: TComponent);
+begin
+  inherited Create(aOwner);
+  FMinHeight:=250;
+  FMinWidth:=200;
+  FMultiToast:=True;
+  FHideDelay:=2000;
+  FAutoHide:=True;
+  FAnimate:=False;
+end;
+
+function TToastManager.ShowToast(const aHeader, aBody: String; aContext : TContextual = cNone; Closable: Boolean = True): TSimpleToastWidget;
+begin
+  CheckInit;
+  Result:=TSimpleToastWidget.Create(Self) ;
+  With Result do
+    begin
+    Parent:=Self;
+    Header:=aHeader;
+    Body:=aBody;
+    HeaderImage:=ToastIcon;
+    CloseButton:=Closable;
+    Contextual:=aContext;
+    AutoHide:=ToastAutoHide;
+    HideDelay:=ToastHideDelay;
+    Animate:=ToastAnimate;
+    MinWidth:=ToastMinWidth;
+    Refresh;
+    end;
+end;
+
+{ TSimpleToastWidget }
+
+function TSimpleToastWidget.CloseButtonHTML: String;
+
+Var
+  S : String;
+
+begin
+  S:=ContextualNames[Contextual];
+  if S<>'' then
+    S:='text-'+S;
+  Result:=Result+ '<button type="button" class="ml-2 mb-1 close '+S+'" data-dismiss="toast" aria-label="Close">';
+  Result:=Result+ '   <span aria-hidden="true">&times;</span>';
+  Result:=Result+ '</button>';
+end;
+
+function TSimpleToastWidget.HeaderHTML: String;
+
+Var
+  S : String;
+
+begin
+  S:=ContextualNames[Contextual];
+  if S<>'' then
+    S:='text-'+S;
+  Result:='<div class="toast-header '+S+'">';
+  if HeaderImage<>'' then
+    Result:=Result+'<img src="'+HeaderImage+'" class="rounded mr-2">';
+  Result:=Result+'<div class="mr-auto">'+Header+'</div>';
+  if (SmallHeader<>'') then
+    Result:=Result+'<small>'+SmallHeader+'</div>';
+  if CloseButton then
+    Result:=Result+CloseButtonHTML;
+  Result:=Result+'</div>';
+end;
+
+procedure TSimpleToastWidget.SetBody(AValue: String);
+begin
+  if FBody=AValue then Exit;
+  FBody:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TSimpleToastWidget.SetAnimate(AValue: Boolean);
+begin
+  if FAnimate=AValue then Exit;
+  FAnimate:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TSimpleToastWidget.SetAutoHide(AValue: Boolean);
+begin
+  if FAutoHide=AValue then Exit;
+  FAutoHide:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TSimpleToastWidget.SetBoolean(AValue: Boolean);
+begin
+  if FBoolean=AValue then Exit;
+  FBoolean:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TSimpleToastWidget.SetContextual(AValue: TContextual);
+begin
+  if FContextual=AValue then Exit;
+  FContextual:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TSimpleToastWidget.SetHeader(AValue: String);
+begin
+  if FHeader=AValue then Exit;
+  FHeader:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TSimpleToastWidget.SetHeaderImage(AValue: String);
+begin
+  if FHeaderImage=AValue then Exit;
+  FHeaderImage:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TSimpleToastWidget.SetHideDelay(AValue: Integer);
+begin
+  if FHideDelay=AValue then Exit;
+  FHideDelay:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TSimpleToastWidget.SetMinWidth(AValue: Integer);
+begin
+  if FMinWidth=AValue then Exit;
+  FMinWidth:=AValue;
+  if isRendered then Refresh;
+end;
+
+procedure TSimpleToastWidget.SetSmallHeader(AValue: String);
+begin
+  if FSmallHeader=AValue then Exit;
+  FSmallHeader:=AValue;
+  if isRendered then Refresh;
+end;
+
+function TSimpleToastWidget.BodyHTML: String;
+
+Var
+  S : String;
+
+begin
+  S:=ContextualNames[Contextual];
+  if S<>'' then
+    S:='alert-'+S;
+  Result:='<div class="toast-body '+S+'">';
+  Result:=Result+Body;
+  Result:=Result+'</div>';
+end;
+
+function TSimpleToastWidget.GetTemplateHTML: String;
+
+Var
+  Head : String;
+
+begin
+  Result:='<div class="toast" aria-live="assertive" aria atomic="true" style="min-width: '+IntToStr(MinWidth)+'px;">';
+  Result:=Result+HeaderHTML;
+  Result:=Result+BodyHTML;
+  Result:=Result+'</div>';
+end;
+
+function TSimpleToastWidget.DoRenderHTML(aParent, aElement: TJSHTMLElement): TJSHTMLElement;
+begin
+  Result:=inherited DoRenderHTML(aParent, aElement);
+  JQuery(Result).toast(New(['animation',FAnimate,'autohide',autohide,'delay',FHideDelay]));
+  JQuery(Result).ToastShow;
+end;
+
+constructor TSimpleToastWidget.Create(aOwner: TComponent);
+begin
+  inherited Create(aOwner);
+  FMinWidth:=200;
+  FAutoHide:=True;
+  FHideDelay:=2000;
+end;
+
+procedure TSimpleToastWidget.Hide;
+begin
+  JQuery(Element).Toast('hide');
+end;
+
+end.