Mega Search
23.2 Million


Sign Up

Make a donation  
How to combine JQuery UI and IntraWeb AJAX  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb

Hi 
I want to add a jqueryUI Slider and I get it working in the browser. Cool. Now, what's the way back to Delphi? If I move the slider I need a callback in Delphi to do some things. Any hint?
{code}
  	
  
  $(function(){				
				// Slider
				$('#slider').slider({
					
				});
			});
  


{code} Greetings Sven
Vote for best question.
Score: 0  # Vote:  0
Date Posted: 3-Sep-2012, at 12:01 PM EST
From: Sven Heuer
 
Re: How to combine JQuery UI and IntraWeb AJAX  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb
Hi, Sven!

1. You need to write Ajax handler as a published method of your IWForm

procedure MyAjaxHandler(EventParams: TStringList);


2. Register the handler on IWFormCreate:


WebApplication.RegisterCallBack('MyAjaxHandler', MyAjaxHandler);


3. In JS code you can execute your callback something like this:


executeAjaxEvent("&myExtraParam=blablabla", null,"MyAjaxHandler",false, null, false);


Your extra params will be accessible through EventParams list among with the standard event parameters on the server side.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 4-Sep-2012, at 5:09 AM EST
From: Alexander Popov
 
Re: How to combine JQuery UI and IntraWeb AJAX  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb
Thanks for this post, it was was very helpful.  One note I would add, which I found out the hard way:

Make sure to give your AJAX event a name that is *unique in your entire program*. 

I found out because I had registered "MyAjaxHandler" on one form, then did it again on another.  Well, the event on the second one started getting the call from the first form.  This is bad in itself, but it also caused an A/V because form2 had already been destroyed, and had not been re-created yet. 

I'm not sure if I've seen the latest of A-to-Zed's docs on this, but they may want to stress that the event name needs to be unique -if this is correct, or describe a better way to handle it.


> {quote:title=Alexander Popov wrote:}{quote}
> Hi, Sven!
> 
> 1. You need to write Ajax handler as a published method of your IWForm
> 
> procedure MyAjaxHandler(EventParams: TStringList);
> 
> 
> 2. Register the handler on IWFormCreate:
> 
> 
> WebApplication.RegisterCallBack('MyAjaxHandler', MyAjaxHandler);
> 
> 
> 3. In JS code you can execute your callback something like this:
> 
> 
> executeAjaxEvent("&myExtraParam=blablabla", null,"MyAjaxHandler",false, null, false);
> 
> 
> Your extra params will be accessible through EventParams list among with the standard event parameters on the server side.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 12-Jul-2013, at 10:10 AM EST
From: Dan Armstrong
 
Re: How to combine JQuery UI and IntraWeb AJAX  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb
This is what I have at the moment.  I still can't seem to get the Value of the slider into Delphi.  In can use the value from Javascript without any problems.  I would need it in Delphi.

Thanks for any help anyone can give me.

{code}

{code}

In Delphi

{code}
procedure TFrmAdmin.MyAjaxHandler(EventParams: TStringList);
begin
  IWButton1.Caption := EventParams.Values['which'];
  WebApplication.ShowMessage(EventParams.Values['value']);
//  WebApplication.ShowMessage(EventParams.Text);
end;

procedure TFrmAdmin.IWAppFormCreate(Sender: TObject);
begin
  WebApplication.RegisterCallBack('MyAjaxHandler', MyAjaxHandler);
end;
{code}

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 25-Oct-2012, at 2:31 PM EST
From: Jody Stone
 
Re: How to combine JQuery UI and IntraWeb AJAX  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb
Hi Alexander,

thats so simple? That's cool... Thanks a lot!!!

Sven

> {quote:title=Alexander Popov wrote:}{quote}
> Hi, Sven!
> 
> 1. You need to write Ajax handler as a published method of your IWForm
> 
> procedure MyAjaxHandler(EventParams: TStringList);
> 
> 
> 2. Register the handler on IWFormCreate:
> 
> 
> WebApplication.RegisterCallBack('MyAjaxHandler', MyAjaxHandler);
> 
> 
> 3. In JS code you can execute your callback something like this:
> 
> 
> executeAjaxEvent("&myExtraParam=blablabla", null,"MyAjaxHandler",false, null, false);
> 
> 
> Your extra params will be accessible through EventParams list among with the standard event parameters on the server side.

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 4-Sep-2012, at 5:59 AM EST
From: Sven Heuer
 
Re: How to combine JQuery UI and IntraWeb AJAX  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb
and How work with jquerymobile ??

Wha is the way back to Delphi with values??

example:

 
{%EDATEEND%}
Thank's
Vote for best answer.
Score: 9  # Vote:  1
Date Posted: 25-Sep-2012, at 7:48 AM EST
From: Andre Aigneren
 
Re: How to combine JQuery UI and IntraWeb AJAX  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb
My calls were on separate forms.  Could there be a problem if you created the same events with controls of the same name?  

I did a test app with 2 IWEdits named the same on 2 different forms with ASyncOnChange events.  No problems.  
I then added my own AJAX event on the both forms named the same thing (with the control name in it).  If I run it, open form2, then close(release) form2, then hit the button on form1 to run the js that will run the event, it ends up trying to run the event code on form2, and causes an A/V.  Does Intraweb do some sort of clean up or un-register call of it's Async callbacks when a form is destroyed?  Or am I doing something else entirely wrong.  

I used IW11.0.60 in the test
{code}
unit Unit1;

interface

uses
  Classes, SysUtils, IWAppForm, IWApplication, IWColor, IWTypes, Controls,
  IWVCLBaseControl, IWBaseControl, IWBaseHTMLControl, IWControl,
  IWCompButton, IWCompMemo, IWCompEdit;

type
  TIWForm1 = class(TIWAppForm)
    IWButton1: TIWButton;
    IWEdit1: TIWEdit;
    IWMemo1: TIWMemo;
    IWButton2: TIWButton;
    ebResult: TIWEdit;
    procedure IWButton1Click(Sender: TObject);
    procedure IWEdit1AsyncChange(Sender: TObject;
      EventParams: TStringList);
    procedure IWAppFormCreate(Sender: TObject);
    procedure IWEDIT1MyAjaxHandler(EventParams: TStringList);
    procedure IWButton2Click(Sender: TObject);
  public
  end;

implementation

uses Unit2, IWForm, IWBaseForm;

{$R *.dfm}


procedure TIWForm1.IWButton1Click(Sender: TObject);
  var frm:TIWform2;
begin
  frm:=TIWform2.Create(WebApplication);
  frm.Show;
end;

procedure TIWForm1.IWEdit1AsyncChange(Sender: TObject;
  EventParams: TStringList);
begin
  IWMemo1.Lines.Add(EventParams.Text);
end;

procedure TIWForm1.IWAppFormCreate(Sender: TObject);
begin
  ExtraHeader.Add('');
  ExtraHeader.Add('');
  ExtraHeader.Add('');

  WebApplication.RegisterCallBack('IWEDIT1MyAjaxHandler',IWEDIT1MyAjaxHandler);
end;

procedure TIWForm1.IWEDIT1MyAjaxHandler(EventParams: TStringList);
  var c,v:String;
      zControl:TIWControl;
begin
  c:=EventParams.Names[1];
  if (c<>'') AND
    (FindComponent(c)<>nil)
    then
    begin
      zControl:=TIWControl(FindComponent(c));
      if zControl.ClassNameIs('TIWEdit') then
        begin
          TIWEdit(zControl).Text:=EventParams.Values[c];
          TIWEdit(zControl).refresh;
          //other stuff
        end;
    end;

end;

procedure TIWForm1.IWButton2Click(Sender: TObject);
begin
  AddToInitProc('var sValue=''\u0026'+UpperCase(ebResult.Name)+'=''+escape($(''#IWEDIT1'').val()); executeAjaxEvent(sValue, null,"IWEDIT1MyAjaxHandler",false, null, true);');
end;

initialization
  TIWForm1.SetAsMainForm;

end.

{code}

Form2:
{code}
unit Unit2;

interface

uses
  Classes, SysUtils, IWAppForm, IWApplication, IWColor, IWTypes,
  IWCompMemo, IWCompEdit, Controls, IWVCLBaseControl, IWBaseControl,
  IWBaseHTMLControl, IWControl, IWCompButton;

type
  TIWForm2 = class(TIWAppForm)
    IWButton1: TIWButton;
    IWEdit1: TIWEdit;
    IWMemo2: TIWMemo;
    ebResult: TIWEdit;
    IWButton2: TIWButton;
    procedure IWEdit1AsyncChange(Sender: TObject;
      EventParams: TStringList);
    procedure IWButton1Click(Sender: TObject);
    procedure IWEDIT1MyAjaxHandler(EventParams: TStringList);
    procedure IWButton2Click(Sender: TObject);
    procedure IWAppFormCreate(Sender: TObject);
  public
  end;

implementation

{$R *.dfm}


procedure TIWForm2.IWEdit1AsyncChange(Sender: TObject;
  EventParams: TStringList);
begin
  IWMemo2.Lines.Add(EventParams.Text);
end;

procedure TIWForm2.IWButton1Click(Sender: TObject);
begin
  Release;
end;

procedure TIWForm2.IWEDIT1MyAjaxHandler(EventParams: TStringList);
  var c,v:String;
      zControl:TIWControl;
begin
  //WebApplication.ShowMessage('This is the Event on form 2');
  c:=EventParams.Names[1];
  if (c<>'') AND
    (FindComponent(c)<>nil)
    then
    begin
      zControl:=TIWControl(FindComponent(c));
      if zControl.ClassNameIs('TIWEdit') then
        begin
          TIWEdit(zControl).Text:=EventParams.Values[c];
          //other stuff
        end;
    end;

end;

procedure TIWForm2.IWButton2Click(Sender: TObject);
begin
  AddToInitProc('var sValue=''\u0026'+UpperCase(ebResult.Name)+'=''+escape($(''#IWEDIT1'').val()); executeAjaxEvent(sValue, null,"IWEDIT1MyAjaxHandler",false, null, true);');
end;

procedure TIWForm2.IWAppFormCreate(Sender: TObject);
begin
  ExtraHeader.Add('');
  ExtraHeader.Add('');
  ExtraHeader.Add('');

  WebApplication.RegisterCallBack('IWEDIT1MyAjaxHandler',IWEDIT1MyAjaxHandler);
end;

end.

{code}


> {quote:title=Pedro Lopes wrote:}{quote}
> Hi
> 
> Em 12/07/13 15:10, Dan Armstrong escreveu:
> > Make sure to give your AJAX event a name that is *unique in your entire program*.
> >
> 
> Yes, for a given IW AControl,  normally is AControl.HTMLName + 
> '.MyAjaxHandler'
> 
> Best Regards
> 
> Pedro
> 
> -- 
> 
> http://www.cgdevtools.com

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 12-Jul-2013, at 1:20 PM EST
From: Dan Armstrong
 
Re: How to combine JQuery UI and IntraWeb AJAX  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb
Francisco,
That's not what I was trying to do.  My example DOES create 2 separate calls on 2 separate pages.  What I was demonstrating is that if you name them the same thing, registering the second one will cause all the calls to the first one, to go to the second one.  I was looking for guidance on best practices for naming these events, and wondering how IW seems to have no problems with same-named async event calls on 2 separate forms.

> {quote:title=Francisco Armando Dueñas Rodriguez wrote:}{quote}
> You cannot use a callback in a form that is used in another form, you have a call back per form, remember each form
> is a new webpage, so there is no problem registering again the callback it will be substituted. unless you create a global 
> procedure in another unit and have a public variable that will contain the current TIWForm viewed. so it can be accessed by
> the callback method. but I think it is better if you copy the callback method code from form1 and add it to form2.
> 
> Also you can create a new class like TIWMyEditCallBack in an external unit, and add the callback procedure as a method, just add a 
> Constructor Create with a parameter to pass the current IWForm and store it in a variable/field like 'fIWForm: TIWForm'.
> 
> {code}
> type
>  TIWMyEditCallBack = class(tobject)
>  protected
>   fIWForm: TIWForm
>  public
>   constructor Create( AForm: TIWForm );
>   procedure AjaxHandler(EventParams: TStringList); 
>  end;
> {code}
> 
> 
> Change the callback procedure code  to search in the stored form reference.
> so ti should look something like this
> {code}
> procedure TIWMyEditCallback.AjaxHandler(EventParams: TStringList);
>   var c,v:String;
>       zControl:TIWControl;
> begin
>   c:=EventParams.Names[1];
>   if (c<>'') AND
>     (fIWForm.FindComponent(c)<>nil)
>     then
>     begin
>       zControl:=TIWControl(fIWForm.FindComponent(c));
>       if zControl.ClassNameIs('TIWEdit') then
>         begin
>           TIWEdit(zControl).Text:=EventParams.Values[c];
>           TIWEdit(zControl).refresh;
>           //other stuff
>         end;
>     end;
> end;
> {code}
> 
> Then instantiate this class per form in the OnCreate event of the form and destroy it in the OnDestroy event of the form
> 
> You can have this object as a property or field of a form:
> {code}
> fMyEditCallBack :=  TIWMyEditCallBack.Create(self); //self is the current IWForm;
> {code}
> 
> In the OnRender event of the form Register the callback, so it will re-register it even if the form is not freed and called again
> {code}
> procedure TIWForm1.IWAppFormRender(Sender: TObject);
> begin
>  WebApplication.RegisterCallBack('IWEDIT1MyAjaxHandler', fMyEditCallBack.AjaxHandler);
> end;
> {code}
> 
> Edited by: Francisco Armando Dueñas Rodriguez on Jul 12, 2013 8:13 PM

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 15-Jul-2013, at 10:15 AM EST
From: Dan Armstrong
 
Re: How to combine JQuery UI and IntraWeb AJAX [Edit]  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb
> {quote:title=Dan Armstrong wrote:}{quote}
> Francisco,
> That's not what I was trying to do.  My example DOES create 2 separate calls on 2 separate pages.  What I was demonstrating is that if you name them the same thing, registering the second one will cause all the calls to the first one, to go to the second one.  I was looking for guidance on best practices for naming these events, and wondering how IW seems to have no problems with same-named async event calls on 2 separate forms.

Hi Dan. Sorry I don't explained me well. I suggest you the above code because that replaces the same async event, when the form is rendered again, this because IW has a global async event registration per user session, it is not per form or owned object, so when you register the same event name with the second form it will replace the current record that was owned by the first form. 

That is why I recommend you you rgister the call back in the OnRender event of the form, so it will re-register it when the form is rendered again. It is not so important to have to AsyncCalls that will do the same thing. 

If you still want to have a record per Form then register it by using the current iwform name like this:

WebApplication.RegisterCallBack(Self.Name+'_IWEDIT1MyAjaxHandler', MyAjaxHandler);

Just remember this:

What RegisterCallback stores is a pointer to the MyAjaxHandler memory position, so if you free the form and recreate it again the pointer will be different, that Why it is so important you can to call RegisterCallback in the OnRender event To prevent AV errors.

I suggested the AjaxHandler Class approach because both routines in form1 and form2 does the same thing, so you have repeated code. the only thing that changes is the form that call it, so that is why the suggestion to have a single method.

It wa sjust a more OOP approach, You approach is not wrong, just dont foget, if you still want to manage teh same ajax event name, to register the function in the OnRender event of each form and not in the onCreate

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 15-Jul-2013, at 11:13 AM EST
From: =?Utf-8?Q?Francisco_Armando_Due=C3=
 
Re: How to combine JQuery UI and IntraWeb AJAX  
News Group: embarcadero.public.delphi.thirdpartytools.intraweb
Thank you Francisco.  That explains it quite well.  I came across the problem on accident.  Your explanation suggests that the best practice would be to do the WebApplication.RegisterCallBack in the OnRender of the form.  If I put it there (instead of OnCreate), I would have not come across the issue.  Hopefully AtoZed has this noted in the docs, but this is all I've found: http://docs.atozed.com/docs.dll/classes/TIWApplication.html [http://docs.atozed.com/docs.dll/classes/TIWApplication.html|http://docs.
atozed.com/docs.dll/classes/TIWApplication.html] 
It does note that the name should be unique, I think It should mention that the best practice would be to put it in the OnRender of the form in most cases.

You've been very helpful.  

> {quote:title=Francisco Armando Dueñas Rodriguez wrote:}{quote}
> > {quote:title=Dan Armstrong wrote:}{quote}
> > Francisco,
> > That's not what I was trying to do.  My example DOES create 2 separate calls on 2 separate pages.  What I was demonstrating is that if you name them the same thing, registering the second one will cause all the calls to the first one, to go to the second one.  I was looking for guidance on best practices for naming these events, and wondering how IW seems to have no problems with same-named async event calls on 2 separate forms.
> 
> Hi Dan. Sorry I don't explained me well. I suggest you the above code because that replaces the same async event, when the form is rendered again, this because IW has a global async event registration per user session, it is not per form or owned object, so when you register the same event name with the second form it will replace the current record that was owned by the first form. 
> 
> That is why I recommend you you rgister the call back in the OnRender event of the form, so it will re-register it when the form is rendered again. It is not so important to have to AsyncCalls that will do the same thing. 
> 
> If you still want to have a record per Form then register it by using the current iwform name like this:
> 
> WebApplication.RegisterCallBack(Self.Name+'_IWEDIT1MyAjaxHandler', MyAjaxHandler);
> 
> Just remember this:
> 
> What RegisterCallback stores is a pointer to the MyAjaxHandler memory position, so if you free the form and recreate it again the pointer will be different, that Why it is so important you can to call RegisterCallback in the OnRender event To prevent AV errors.
> 
> I suggested the AjaxHandler Class approach because both routines in form1 and form2 does the same thing, so you have repeated code. the only thing that changes is the form that call it, so that is why the suggestion to have a single method.
> 
> It wa sjust a more OOP approach, You approach is not wrong, just dont foget, if you still want to manage teh same ajax event name, to register the function in the OnRender event of each form and not in the onCreate

Vote for best answer.
Score: 0  # Vote:  0
Date Posted: 15-Jul-2013, at 12:03 PM EST
From: Dan Armstrong