Le griglie in ExtPascal - ExtPascalToolkit / Grids into ExtPascal - ExtPascalToolkit

Italiano   English
L'esempio che vedremo durante tutta la guida è scaricabile al seguente indirizzo   The example that we will see throughout the guide can be downloaded at the following address



http://www.lazaruspascal.it/esempi/ExtGrid_Example.zip

Prima di partire si necessita di capire cosa è Ajax, perchè ExtPascal è un wrapper per ExtJS, quindi non ne modifica la logica permette solo di usare una sintassi pascal.   Before starting you need to understand what Ajax is, why ExtPascal is a wrapper for ExtJS, so does not affect the logic just allows you to use a Pascal syntax.
AJAX, acronimo di Asynchronous JavaScript and XML, è una tecnica di sviluppo per la realizzazione di applicazioni web interattive (Rich Internet Application). Lo sviluppo di applicazioni HTML con AJAX si basa su uno scambio di dati in background fra web browser e server, che consente l'aggiornamento dinamico di una pagina web senza esplicito ricaricamento da parte dell'utente. AJAX è asincrono nel senso che i dati extra sono richiesti al server e caricati in background senza interferire con il comportamento della pagina esistente. Normalmente le funzioni richiamate sono scritte con il linguaggio JavaScript. Tuttavia, e a dispetto del nome, l'uso di JavaScript e di XML non è obbligatorio, come non è necessario che le richieste di caricamento debbano essere necessariamente asincrone.

AJAX è una tecnica multi-piattaforma utilizzabile su molti sistemi operativi, architetture informatiche e browser web, ed esistono numerose implementazioni open source di librerie e framework.

La tecnica Ajax utilizza una combinazione di:

    HTML (o XHTML) e CSS per il markup e lo stile;
    DOM (Document Object Model) manipolato attraverso un linguaggio ECMAScript come JavaScript o JScript per mostrare le informazioni ed interagirvi;
    l'oggetto XMLHttpRequest per l'interscambio asincrono dei dati tra il browser dell'utente e il web server. In alcuni framework Ajax e in certe situazioni, può essere usato un oggetto Iframe invece di XMLHttpRequest per scambiare i dati con il server e, in altre implementazioni, tag  aggiunti dinamicamente ( JSON );
    in genere viene usato XML come formato di scambio dei dati, anche se di fatto qualunque formato può essere utilizzato, incluso testo semplice, HTML preformattato, JSON e perfino EBML. Questi file sono solitamente generati dinamicamente da script lato server.

Come DHTML o LAMP, Ajax non è una tecnologia individuale, piuttosto è un gruppo di tecnologie utilizzate insieme.

Le applicazioni web che usano Ajax richiedono browser che supportano le tecnologie necessarie (quelle dell'elenco sopra). Questi browser includono: Mozilla, Firefox, Opera, Konqueror, Safari, Internet Explorer e Chrome. Tuttavia, per specifica, "Opera non supporta la formattazione degli oggetti XSL".
  AJAX stands for Asynchronous JavaScript and XML, is a development technique for the creation of interactive web applications (RIAs). Developing applications with HTML AJAX is based on an exchange of data in the background between web browsers and servers, which allows dynamic update of a web page without reloading explicitly by the user. AJAX is asynchronous in the sense that the extra data are required to the server and loaded in the background without interfering with the behavior of the existing page. Normally the called functions are written in JavaScript. However, and despite the name, the use of JavaScript and XML is not required as it is not necessary that the required load must necessarily be asynchronous.

AJAX is a cross-platform technique usable on many operating systems, architectures, and web browsers, and there are numerous implementations of open source libraries and frameworks.

The Ajax technique uses a combination of:

    HTML (or XHTML) and CSS for the markup and style;
    DOM (Document Object Model) manipulated through an ECMAScript as JavaScript or JScript to display information and interact;
    the XMLHttpRequest object for asynchronous exchange of data between your browser and the web server. In some Ajax frameworks and in certain situations, can be used an Iframe instead of XMLHttpRequest object to exchange data with the server and, in other implementations, dynamically added  (json);
    is typically used as exchange format XML data, even if in fact any size can be used, including plain text, preformatted HTML, JSON and even EBML. These files are usually generated dynamically by server side scripts.

Like DHTML, or LAMP, Ajax is not an individual technology, rather it is a group of technologies together.

Web applications that use Ajax require browsers that support the technologies required (those on the list above). These browsers include Mozilla, Firefox, Opera, Konqueror, Safari, Internet Explorer and Chrome. However, for specific, "Opera does not support XSL formatting objects."
Innanzitutto vediamo come collegarci ad un database con zeos e come prendiamo i dati e li formattiamo per essere visualizzati nella Griglia di ExtPascal Toolkit.
Per fare questo basta implementare la seguente unit scritta da me prendendo spunto da altre unit trovate su internet
  First we see how to link to a database with ZEOS and how we take the data and we format to be displayed in the grid ExtPascal Toolkit.
To do this just implement the following unit written by me taking a cue from other units found on the Internet



Codice: [Seleziona]

{Libreria realizzata da Sammarco Francesco - www.lazaruspascal.it}

unit ExtZQuery;

{$mode delphi}

interface

uses
  SysUtils, Classes, ZDataset,
{$IFDEF UseRuntime}
  Ext, ExtPascal, ExtPascalUtils, ExtForm,
  ExtData, ExtGrid, ExtUtil, ExtAir, ExtDd,
  ExtLayout, ExtMenu, ExtDirect, ExtState, ExtTree,
  ExtUxForm;

type
  {$M+}
  TExtPanel_Tab = TExtPanel;
  TExtFormTextField_Grid = TExtFormTextField;
  TExtFormNumberField_Grid = TExtFormNumberField;
  TExtFormDateField_Grid = TExtFormDateField;
  TExtFormTimeField_Grid = TExtFormTimeField;
  TExtFormCheckbox_Grid = TExtFormCheckbox;
  TExtFormComboBox_Grid = TExtFormComboBox;
  {$M-}

{$ELSE}
  ExtP_Design_Ctrls, ExtP_Design_Grid, ZConnection;
{$ENDIF}

type
  TExtZQuery = class(TZQuery)
      DataStore:TExtDataArrayStore;
  public
      MyErr: string;
      constructor Create(Owner : TComponent); override;
      destructor Destroy; override;
      function TransformsDatasetToDataStore(): boolean;
      function GetNumCols(): integer;
      function GetNumRows(): integer;
  private
         NumCols: integer;
         NumRows: integer;
  published
  end;

implementation

uses
    StrUtils, DateUtils, ZConnection;

constructor TExtZQuery.Create(Owner : TComponent);
begin
  inherited;
  Connection := TZConnection.Create(nil);
  with Connection do
  begin
    HostName := 'localhost';
    Database := 'c:\db_grid.s3db';
    User     := '';
    Password := '';
    Protocol := 'sqlite-3';
    Connect;
  end;
  DataStore:=TExtDataArrayStore.Create;
end;

destructor TExtZQuery.Destroy;
begin
  Close;
  Connection.Disconnect;
  Connection.Free;
  inherited;
end;

function TExtZQuery.TransformsDatasetToDataStore(): boolean;
var
   ret: boolean;
   i: integer;
   app: string;
begin
     try
        try
           NumCols:=0;
           NumRows:=0;
           MyErr:='';
           ret:=TRUE;
           With DataStore do
           begin
                //imposto le colonne
                if FieldDefs.Count>0 then
                begin
                     for i:=0 to FieldDefs.Count-1 do
                     begin
                          TExtDataField.AddTo(Fields).Name := FieldDefs.Items[i].Name;
                     end;
                     NumCols:=FieldDefs.Count;
                end;
                //inserisco le righe
                if not EOF then
                begin
                   First;
                   while not EOF do
                   begin
                        app:=app + '[';
                        for i:=0 to FieldDefs.Count-1 do
                        begin
                             app:= app + '"' + FieldByName(FieldDefs.Items[i].Name).asString + '"';
                             if i0 then
        app:=app;
     GetNumCols:=app;
end;

function TExtZQuery.GetNumRows(): integer;
var
   app: integer;
begin
     app:=NumRows;
     if app>0 then
        app:=app-1;
     GetNumRows:=app;
end;

end.


Analizzando la unit capiamo che nella create dell'oggetto TExtZQuery impostiamo i dati per collegarci al DB, mentre con TransformsDatasetToDataStore() prendiamo il risultato della query e la convertiamo in un formato leggibile dalla griglia.   By analyzing the unit we understand that the object created TExtZQuery we set the data to connect to the DB, while TransformsDatasetToDataStore () we take the result of the query and convert it to a format readable by the grid.
Durante la creazione di un nuovo progetto per poter usare le zeos bisogna trascinare un oggetto TZConnection su una form, poi cancellare la TZConnection e togliere le unit di zeos dal file *.LPR   When creating a new project to use the ZEOS TZConnection must drag an object on a form, then delete the TZConnection and remove the unit from the file ZEOS *.LPR
Ora vediamo il contenuto della form principale   Now we see the contents of the main form


Codice: [Seleziona]

unit Unit1;

interface

uses
  SysUtils, Classes, ExtZQuery,
{$IFDEF UseRuntime}
  Ext, ExtPascal, ExtPascalUtils, ExtForm,
  ExtData, ExtGrid, ExtUtil, ExtAir, ExtDd,
  ExtLayout, ExtMenu, ExtDirect, ExtState, ExtTree,
  ExtUxForm;

type
  {$M+}
  TExtPanel_Tab = TExtPanel;
  TExtFormTextField_Grid = TExtFormTextField;
  TExtFormNumberField_Grid = TExtFormNumberField;
  TExtFormDateField_Grid = TExtFormDateField;
  TExtFormTimeField_Grid = TExtFormTimeField;
  TExtFormCheckbox_Grid = TExtFormCheckbox;
  TExtFormComboBox_Grid = TExtFormComboBox;
  {$M-}

{$ELSE}
       ExtP_Design_Ctrls, ExtP_Design_Grid, ZConnection, StdCtrls;
{$ENDIF}

type

  { TMyForm }

  TMyForm = class(TExtWindow)
    ExtButton1: TExtButton;
    ExtButton2: TExtButton;
    ExtFormLabel3: TExtFormLabel;
    ExtFormLabel4: TExtFormLabel;
    ExtFormLabel5: TExtFormLabel;
    ExtFormLabel6: TExtFormLabel;
    Txt_Id_Old: TExtFormTextField;
    Txt_Row: TExtFormTextField;
    Txt_Row_Old: TExtFormTextField;
    Txt_App2: TExtFormTextField;
    RowSelect : TExtGridRowSelectionModel;
    Btn_Ins: TExtButton;
    Btn_Del: TExtButton;
    ExtFormLabel1: TExtFormLabel;
    ExtFormLabel2: TExtFormLabel;
    Txt_TotRow: TExtFormTextField;
    Txt_TotCol: TExtFormTextField;
    MyId_Field: TExtFormTextField_Grid;
    MyValue_Field: TExtFormTextField_Grid;
    Txt_Id: TExtFormTextField;
    MiaConn: TExtZQuery;
    MyGrid: TExtGridEditorGridPanel;
    procedure Btn_DelClick;
    procedure ExtButton1Click;
    procedure ExtButton2Click;
    procedure MyGridRowClick(This : TExtGridGridPanel; RowIndex : Integer; E : TExtEventObjectSingleton);
    procedure Btn_InsClick;
    procedure CaricaGriglia;
    procedure MyVersionOfGetCell();
    procedure MyGetCell;
    procedure MyDelete;
    procedure RowSelectOnRowselect(This : TExtGridRowSelectionModel; RowIndex : Integer; R : TExtDataRecord);
    procedure GestisciRigaSelezionata();
    procedure StampaValore;
    procedure MyValue_FieldOnFocus(This : TExtFormField);
    procedure AggiornaValoriRiga();
  public
    constructor Create;
    procedure Show;
  private
    FlagEvitaLoop: integer;
  end;
implementation

uses
  AppThread;

procedure TMyForm.Btn_InsClick;
var
   MiaExec: TExtZQuery;
begin
     MiaExec:=TExtZQuery.Create(nil);
     MiaExec.SQL.Text:='insert into MyTable(MyValue)VALUES("");'; //inserisco una riga vuota
     MiaExec.ExecSQL;
     MiaExec.Destroy;
     CaricaGriglia;
     CurrentThread.NumRows:=MiaConn.GetNumRows();
     CurrentThread.NumCols:=MiaConn.GetNumCols();
     Txt_TotRow.SetValue(IntToStr(CurrentThread.NumRows));
     Txt_TotCol.SetValue(IntToStr(CurrentThread.NumCols));
end;

procedure TMyForm.CaricaGriglia;
begin
     {inizio righe di codice per vedere nella griglia quello che ho nel db}
     MiaConn:=TExtZQuery.Create(nil);
     MiaConn.SQL.Text:='select Id, MyValue from MyTable;';
     MiaConn.Open;
     MiaConn.TransformsDatasetToDataStore();
     MyGrid.Reconfigure(MiaConn.DataStore, TExtGridColumnModel(MyGrid.ColModel));
     {fine righe di codice per vedere nella griglia quello che ho nel db}
end;

procedure TMyForm.AggiornaValoriRiga();
var
   MiaExec: TExtZQuery;
begin
     MiaExec:=TExtZQuery.Create(nil);
     MiaExec.SQL.Text:='UPDATE MyTable SET MyValue="' + CurrentThread.Query['NewValue'] + '" WHERE Id=' + CurrentThread.Query['IdRecord'] + ';';
     MiaExec.ExecSQL;
     MiaExec.Destroy;
end;
procedure TMyForm.MyGridRowClick(This : TExtGridGridPanel; RowIndex : Integer; E : TExtEventObjectSingleton);
begin
     //se clicco nella cella
     Ajax(MyVersionOfGetCell,['row',RowIndex,'col','Id']);
end;

procedure TMyForm.Btn_DelClick;
var
   ShowConfig:TExtShowConfig;
begin
     ShowConfig:=TExtShowConfig.Create;
     with ShowConfig do
     begin
          Title:='ATTENZIONE';
          Msg:='Vuoi cancellare la riga selezionata?';
          Icon:=ExtMessageBox.Question;
          Buttons:=ExtMessageBox.YesNoCancel;
          AnimEl:='Id';
          Fn:=Ajax(MyDelete,['ButtonId','%0','IdDaCancellare',Txt_Id.GetValue]);
     end;
     ExtMessageBox.Show(ShowConfig);
     ShowConfig.Free;
end;


procedure TMyForm.ExtButton1Click;
begin
     //stampo l'indice della colonna che voglio leggere ovvero la colonna MyValue
     Ajax(StampaValore,['valore',TExtGridColumnModel(MyGrid.ColModel).FindColumnIndex('MyValue')]);
end;

procedure TMyForm.ExtButton2Click;
var
   DataStore: TExtDataStore;
   DataRecord: TextDataRecord;
begin
     with MyGrid do
     begin
          DataStore:=TExtDataStore.Create();
          DataStore:=TExtDataStore(GetStore);
          DataRecord:=TextDataRecord(DataStore.GetAt(0));

          Ajax(StampaValore,['valore',DataRecord.Get('MyValue')]);
     end;
end;

procedure TMyForm.StampaValore;
begin
     ExtMessageBox.Alert('valore',CurrentThread.Query['valore']);
end;

procedure TMyForm.MyDelete;
var
   MiaExec: TExtZQuery;
   Risultato: string;
begin
     Risultato:=CurrentThread.Query['ButtonId'];

     if StrToInt(CurrentThread.Query['IdDaCancellare'])=0 then
       begin
            with MyGrid do
            begin
                 DataStoreNewValue:=TExtDataStore.Create();
                 DataStoreNewValue:=TExtDataStore(GetStore);
                 DataRecordNewValue:=TextDataRecord(DataStoreNewValue.GetAt(StrToInt(CurrentThread.Query['RowIndexOld'])));

                 Ajax(AggiornaValoriRiga,['Idrecord',CurrentThread.Query['MyDataSetIdOld'],'NewValue',DataRecordNewValue.Get('MyValue')]);
            end;
       end;
end;

procedure TMyForm.Show;
begin
  inherited Show;
  CaricaGriglia;
  CurrentThread.NumRows:=MiaConn.GetNumRows();
  CurrentThread.NumCols:=MiaConn.GetNumCols();
  Txt_TotRow.SetValue(IntToStr(CurrentThread.NumRows));
  Txt_TotCol.SetValue(IntToStr(CurrentThread.NumCols));
  Txt_Id.SetValue('-1');
  Txt_Id_Old.SetValue('-1');
  Txt_Row.SetValue('-1');
  Txt_Row_Old.SetValue('-1');
  Txt_App2.SetValue('-1');
end;

end.


Bene la prima cosa che dovrebbe saltare all'occhio è la creazione della form   Well the first thing that should catch the eye is the creation of the form


Codice: [Seleziona]


constructor TMyForm.Create;
begin
  inherited;
{$IFDEF UseRuntime}
 {$I *.inc}
{$ENDIF}
        {creo l'oggetto TExtGridRowSelectionModel che mi servirà a recuperare le righe selezionate}
        //RowSelect := TExtGridRowSelectionModel.Create(JSObject('singleSelect:true')); {permetto che venga selezionata una sola riga per volta}
        RowSelect := TExtGridRowSelectionModel.Create;
        RowSelect.SingleSelect := True;
        RowSelect.OnRowselect := RowSelectOnRowselect; {assegno l'evento apposito sulla selezione di una riga}

        MyGrid.SelModel := RowSelect; //assegno alla griglia l'oggetto che mi permetterà di lavorare con i dati selezionati
        MyGrid.onRowClick:=MyGridRowClick; //se clicco su una cella della griglia
        MyValue_Field.OnFocus:=MyValue_FieldOnFocus;
end;



Durante la create della form creo un oggetto TExtGridRowSelectionModel che poi assegno alla griglia e che mi permette di leggere la riga selezionata, in più gestisco gli eventi di selezione di una nuova riga, del click all'interno di una cella e dell'entrata dell'oggetto che mi permette di modificare il valore di un campo della mia griglia nello specifico quello che contiene il campo MyValue della query che popola la griglia.   When you create the form I create an object TExtGridRowSelectionModel then check the grid and that allows me to read the selected row, plus manage the events of selecting a new row, click inside of a cell and the entry of 'object that allows me to change the value of a field in my grid in the specific field that contains the MyValue the query that populates the grid.
Mentre con la Show vado a valorizzare le mie variabili e gli oggetti che uso come variabili.
E carico la griglia con i valori dellla mia query.
  While the show going to enhance my variables and objects used as variables.
And load the grid with values in my query.


Codice: [Seleziona]


procedure TMyForm.Show;
begin
  inherited Show;
  CaricaGriglia;
  CurrentThread.NumRows:=MiaConn.GetNumRows();
  CurrentThread.NumCols:=MiaConn.GetNumCols();
  Txt_TotRow.SetValue(IntToStr(CurrentThread.NumRows));
  Txt_TotCol.SetValue(IntToStr(CurrentThread.NumCols));
  Txt_Id.SetValue('-1');
  Txt_Id_Old.SetValue('-1');
  Txt_Row.SetValue('-1');
  Txt_Row_Old.SetValue('-1');
  Txt_App2.SetValue('-1');
end;




Vediamo come carichiamo i dati all'interno della griglia   Let's see how to load data into the grid.


Codice: [Seleziona]


procedure TMyForm.CaricaGriglia;
begin
     {inizio righe di codice per vedere nella griglia quello che ho nel db}
     MiaConn:=TExtZQuery.Create(nil);
     MiaConn.SQL.Text:='select Id, MyValue from MyTable;';
     MiaConn.Open;
     MiaConn.TransformsDatasetToDataStore();
     MyGrid.Reconfigure(MiaConn.DataStore, TExtGridColumnModel(MyGrid.ColModel));
     {fine righe di codice per vedere nella griglia quello che ho nel db}
end;



Con le prime righe creiamo la query e la eseguiamo e in successione la traduco nel formato leggibile dalla griglia.
Mentre con MyGrid.Reconfigure(MiaConn.DataStore, TExtGridColumnModel(MyGrid.ColModel)); popolo la griglia
  With the first lines we create and execute the query sequence and translate it into readable format from the grid.
With the MyGrid.Reconfigure(MiaConn.DataStore, TExtGridColumnModel(MyGrid.ColModel)); while people the grid
Ora prima di procedere vediamo come si usa Ajax con il binomio Lazarus ed ExtPascal   Now before we see how to use Ajax with the binomial and Lazarus ExtPascal



Browser -> Server -> Browser

Codice: [Seleziona]


Ajax(NomeProcedura,['nomecampo1',valore1,'nomecampo2',valore2,'nomecampoN',valoreN]);
.
.
.
procedure NomeClasse.NomeProcedura();
var
   app1,app2,appN: string;
begin
app1:=CurrentThread.Query['nomecampo1'];
app2:=CurrentThread.Query['nomecampo2'];
appN:=CurrentThread.Query['nomecampoN'];

.
.
.
end;



Bene capito questo tutto il resto del codice è facile da capire, perchè si basa su questo concetto.
L'unica cosa che dovete sapere è che quando premete sul tasto inserisci crea nel database una riga vuota e quindi i campi devono accettare il null e poi uso la griglia come se fosse un foglio di calcolo, al cambio della riga vado a salvare i dati della riga appena abbandonata.
Mentre quando cancello cancello la riga selezionata.
  Well understood that the rest of the code is easy to understand, because it relies on this concept.
The only thing you should know is that when you press the enter button creates a blank row in the database and therefore must accept the null fields and then use the grid like a spreadsheet, the change of the line going to save the data line just left.
While gate gate when the selected row.
Un ultima cosa, quando andate a leggere un campo di una riga che non è quella selezionata vi è concesso leggere solo un campo per volta quindi vi conviene nel caso di lettura di più campi usare delle chiamate Ajax nidificate.   One last thing, when you read a field of a line that is not selected will be granted only read one field at a time so you might want to read in case of multiple fields using Ajax calls nested.
Ora non vi resta che studiare l'esempio e fare delle prove. Se attraverso le vostre prove trovate altre soluzioni o maniere migliori di fare quello che ho fatto io per cortesia segnalatemi le migliorie.
Per provare l'esempio dopo averlo scaricato vi consiglio di sistemare il database in un posto facilmente raggiungibile e andate a parametrizzare
Project -> Project Options -> Paths -> Target File Name (-o)
Nel modo che più vi aggrada!
Come ultima cosa chiedo scusa agli amici che leggeranno l'inglese, ho usato il traduttore di google.
  Now you just need to study the example and experiment. If through your trials found other solutions or better ways to do what I did please Notify the improvements.
Last thing I apologize to friends who read English, I used the google translator. To run the example after downloading I suggest you place the database in an easily accessible place and go to parameterize
Project -> Project Options -> Paths -> Target File Name (-o)
In a way that suits you best!





SMF 2.0.8 | SMF © 2011, Simple Machines
Privacy Policy
SMFAds for Free Forums
TinyPortal © 2005-2012

Go back to article