pas2js/demo/fcldb/demorest.lpr

355 lines
9.7 KiB
ObjectPascal

program demorest;
uses sysutils, classes, js, web, db, extjsdataset, jsondataset, restconnection;
Type
{ TRestDataset }
TRestDataset = Class(TExtJSJSONObjectDataSet)
private
FConnection: TRestConnection;
Protected
Function DoGetDataProxy: TDataProxy; override;
Public
Property Connection: TRestConnection Read FConnection Write FConnection;
end;
{ TForm }
TForm = Class
private
Table,
TBody : TJSElement;
Panel,
PanelContent,
ButtonDelete,
ButtonAdd,
ButtonApplyUpdates,
ButtonChange,
ButtonFetch : TJSElement;
EName,
EPopulation: TJSHTMLInputElement;
DS : TRestDataset;
Conn : TRestConnection;
Public
Constructor create;
function CreateTable: TJSElement;
procedure AddRecords;
function ApplyUpdatesClick(aEvent: TJSMouseEvent): boolean;
function ButtonAddClick(aEvent: TJSMouseEvent): boolean;
function ButtonDeleteClick(aEvent: TJSMouseEvent): boolean;
function ButtonFetchClick(Event: TJSMouseEvent): boolean;
function CreateInput(aParent: TJSElement; Atype, AName, ALabel, aID: String): TJSHTMLInputElement;
function CreateRow(AID : Integer; AName: String; APopulation: NativeInt): TJSElement;
function DoAddRecord(aEvent: TJSMouseEvent): boolean;
procedure DoAfterLoad(DataSet: TDataSet);
function DoEditRecord(aEvent: TJSMouseEvent): boolean;
procedure DoGetURL(Sender: TComponent; aRequest: TDataRequest; Var aURL: String);
procedure DoLoadFail(DataSet: TDataSet; ID: Integer; const ErrorMsg: String);
procedure DSAfterApplyUpdates(DataSet: TDataSet; Updates: TResolveResults);
procedure DSOpen(DataSet: TDataSet);
procedure ResetButtons(Sender: TDataset);
function SelectRecord(aEvent: TJSMouseEvent): boolean;
end;
function TRestDataset.DoGetDataProxy: TDataProxy;
begin
Result:=Connection.DataProxy;
end;
function TForm.CreateRow(AID : Integer; AName : String; APopulation : NativeInt) : TJSElement;
Var
C : TJSElement;
S : String;
begin
Result:=document.createElement('TR');
S:=IntToStr(AID);
Result.id:=S;
C:=document.createElement('TD');
C.id:=S+'_name';
Result.Append(C);
C.appendChild(Document.createTextNode(AName));
Result.id:=IntToStr(AID);
C:=document.createElement('TD');
C.id:=S+'_population';
Result.Append(C);
C.AppendChild(document.createTextNode(IntToStr(APopulation)));
TJSHTMLElement(Result).onclick:=@SelectRecord;
end;
function TForm.DoAddRecord(aEvent: TJSMouseEvent): boolean;
begin
DS.Append;
DS.FieldByName('name').AsString:=EName.value;
DS.FieldByName('population').AsString:=EPopulation.value;
DS.Post;
Result:=True;
end;
function TForm.DoEditRecord(aEvent: TJSMouseEvent): boolean;
Var
E : TJSElement;
begin
Writeln('Updating record: ',DS.RecNo);
DS.Edit;
DS.FieldByName('name').AsString:=EName.value;
DS.FieldByName('population').AsString:=EPopulation.value;
DS.Post;
E:=Document.getElementById(IntToStr(DS.RecNo)+'_name');
if Assigned(E) then
E.innerText:=EName.value;
E:=Document.getElementById(IntToStr(DS.RecNo)+'_population');
if Assigned(E) then
E.innerText:=EPopulation.value;
Result:=True;
end;
procedure TForm.DoAfterLoad(DataSet: TDataSet);
begin
if Dataset.Active then
begin
Writeln('Loading additional records to table');
// We're on the last record of the last batch, so move forward 1 record
Dataset.Next;
AddRecords;
end;
end;
procedure TForm.DoGetURL(Sender: TComponent; aRequest: TDataRequest; Var aURL: String);
begin
aURL:='http://localhost:3000/countries/?limit=20&offset='+IntToStr((aRequest.RequestID-1)*20);
end;
procedure TForm.DoLoadFail(DataSet: TDataSet; ID: Integer; const ErrorMsg: String);
Var
N : TJSElement;
begin
N:=Document.CreateElement('div');
N.appendChild(Document.createTextNode('Failed to load countries...'+ErrorMsg));
PanelContent.append(N);
end;
procedure TForm.DSAfterApplyUpdates(DataSet: TDataSet; Updates : TResolveResults);
begin
Window.Alert('Updates applied on server!');
EName.value:='';
EPopulation.value:='0';
end;
function TForm.CreateTable : TJSElement;
Var
TH,R,H : TJSElement;
begin
Result:=document.createElement('TABLE');
Result.className:='table table-striped table-bordered table-hover table-condensed';
TH:=document.createElement('THEAD');
Result.Append(TH);
R:=document.createElement('TR');
TH.Append(R);
H:=document.createElement('TH');
R.Append(H);
H.AppendChild(document.createTextNode('Name'));
H:=document.createElement('TH');
R.Append(H);
H.AppendChild(document.createTextNode('Population'));
end;
procedure TForm.DSOpen(DataSet: TDataSet);
begin
console.log('Dataset opened');
if not Assigned(Table) then
begin
Table:=CreateTable;
Document.Body.append(Table);
TBody:=document.createElement('TBODY');
Table.Append(TBody);
end;
DS.First;
AddRecords;
end;
function TForm.SelectRecord(aEvent: TJSMouseEvent): boolean;
Var
aID : integer;
e : TJSElement;
begin
e:=aEvent.target;
While Assigned(e) and Not SameText(e.nodeName,'tr') do
e:=e.parentElement;
if Not Assigned(E) then exit;
aId:=StrToIntDef(e.ID,-1);
Writeln('Jumping to record : ',aID);
if (AID<>-1) then
begin
DS.RecNo:=AID;
EName.value:=DS.FieldByName('Name').AsString;
EPopulation.value:=DS.FieldByName('Population').AsString;
TJSHTMLInputElement(ButtonChange).disabled:=false;
TJSHTMLInputElement(ButtonDelete).disabled:=false;
end
end;
procedure TForm.AddRecords;
begin
While not DS.EOF do
begin
// Writeln(DS.RecNo, ' - ',DS.FieldByName('Name').AsString,'-',DS.FieldByName('Population').AsInteger);
TBody.Append(CreateRow(DS.RecNo, DS.FieldByName('Name').AsString,DS.FieldByName('Population').AsInteger));
DS.Next;
end;
TJSHTMLInputElement(ButtonChange).disabled:=false;
end;
function TForm.ApplyUpdatesClick(aEvent: TJSMouseEvent): boolean;
begin
DS.ApplyUpdates;
end;
function TForm.ButtonAddClick(aEvent: TJSMouseEvent): boolean;
begin
DS.Append;
DS.FieldByname('Name').AsString:=EName.value;
DS.FieldByname('Population').AsLargeInt:=StrToInt(EPopulation.Value);
DS.Post;
AddRecords;
end;
function TForm.ButtonDeleteClick(aEvent: TJSMouseEvent): boolean;
Var
ID : Integer;
E : TJSElement;
begin
ID:=DS.RecNo;
DS.Delete;
EName.value:='';
EPopulation.Value:='';
E:=Document.getElementById(IntToStr(DS.RecNo));
if E<>Nil then
E.parentElement.removeChild(e);
end;
function TForm.ButtonFetchClick(Event: TJSMouseEvent): boolean;
begin
if Assigned(TBody) then
TBody.innerHTML:='';
DS.Load([],Nil);
end;
Function TForm.CreateInput(aParent : TJSElement; Atype,AName,ALabel,aID : String) : TJSHTMLInputElement;
Var
aDiv,aLabelDiv : TJSElement;
begin
adiv:=document.createElement('div');
adiv.className:='form-group';
aLabelDiv:=document.createElement('label');
aLabelDiv['for']:=aID;
aLabelDiv.innerText:=ALabel;
aDiv.appendChild(aLabelDiv);
Result:=TJSHTMLInputElement(document.createElement('input'));
Result.id:=AID;
Result.name:=AName;
Result['type']:=AType;
aDiv.appendChild(Result);
aParent.appendChild(aDiv);
end;
Procedure TForm.ResetButtons (Sender : TDataset);
begin
TJSHTMLInputElement(ButtonChange).disabled:=True;
TJSHTMLInputElement(ButtonDelete).disabled:=True;
end;
constructor TForm.create;
Var
F : TJSElement;
begin
Panel:=document.createElement('div');
// attrs are default array property...
Panel['class']:='panel panel-default';
PanelContent:=document.createElement('div');
PanelContent['class']:='panel-body';
document.body.appendChild(panel);
Panel.appendChild(PanelContent);
// fetch button
ButtonFetch:=document.createElement('button');
ButtonFetch['id']:='ButtonFetch';
ButtonFetch.className:='btn btn-default';
ButtonFetch.InnerText:='Fetch countries';
TJSHTMLElement(ButtonFetch).onclick:=@ButtonFetchClick;
PanelContent.AppendChild(ButtonFetch);
// Input form
F:=document.createElement('form');
F.ClassName:='form-inline';
PanelContent.appendChild(F);
EName:=CreateInput(F, 'text','EName','Name','IDName');
EPopulation:=CreateInput(F, 'number','EPopulation','Population','IDPopulation');
// Add/Apply updates button
// Add
ButtonAdd:=document.createElement('button');
ButtonAdd['id']:='ButtonAdd';
ButtonAdd.className:='btn btn-default';
ButtonAdd.InnerText:='Add record';
TJSHTMLElement(ButtonAdd).OnClick:=@DoAddRecord;
PanelContent.AppendChild(ButtonAdd);
// Edit
ButtonChange:=document.createElement('button');
ButtonChange['id']:='ButtonChange';
ButtonChange.className:='btn btn-default';
ButtonChange.InnerText:='Update record';
TJSHTMLInputElement(ButtonChange).disabled:=true;
TJSHTMLElement(ButtonChange).OnClick:=@DoEditRecord;
PanelContent.AppendChild(ButtonChange);
// Delete
ButtonDelete:=document.createElement('button');
ButtonDelete['id']:='ButtonDelete';
ButtonDelete.className:='btn btn-default';
ButtonDelete.InnerText:='Delete record';
TJSHTMLInputElement(ButtonDelete).disabled:=true;
TJSHTMLElement(ButtonDelete).OnClick:=@ButtonDeleteClick;
PanelContent.AppendChild(ButtonDelete);
// Apply updates
ButtonApplyUpdates:=document.createElement('button');
ButtonApplyUpdates['id']:='ButtonAdd';
ButtonApplyUpdates.className:='btn btn-default';
ButtonApplyUpdates.InnerText:='Apply updates';
TJSHTMLElement(ButtonApplyUpdates).onclick:=@ApplyUpdatesClick;
PanelContent.AppendChild(ButtonApplyUpdates);
DS:=TRestDataset.Create(Nil);
Conn:=TRestConnection.Create(nil);
Conn.BaseURL:='/countries';
Conn.OnGetURL:=@DoGetURL;
DS.Connection:=Conn;
DS.OnLoadFail:=@DoLoadFail;
DS.AfterLoad:=@DoAfterLoad;
DS.AfterOpen:=@DSOpen;
DS.AfterApplyUpdates:=@DSAfterApplyUpdates;
DS.AfterPost:=@ResetButtons;
DS.AfterDelete:=@ResetButtons;
end;
begin
TForm.Create;
end.