Showing and hiding panels

I'm quite new to the JS world, so I apologize if this is immediately obvious.

I'm trying to toggle the visibility of panels that have been added to dynamically through their innerHTML property.

New Project, main unit has html like so:

<div class="main">
			<div class="left-panel"></div>

			<div class="middle-panel">

				<div class="dispatch-panel" id="the-dispatch-panel">
				</div>

			</div>

			<div class="right-panel"></div>
		</div>

I've placed a panel on my delphi form and tied it to the-dispatch-panel through the ElementID. I've given it the name "TheDispatchPanel". I've placed a button on my form with the onClick:

  TheDispatchPanel.ElementHandle.innerHTML := '<div id="addedAtRuntime">Hello</div>';

  asm
    document.getElementById('addedAtRuntime').addEventListener ('click', function (e) {
      pas.UMain.TForm1.showDispatchedTrip(e.srcElement.id);
    });
  end;

The event showDispatchedTrip is simply

procedure TForm1.showDispatchedTrip(someParam: String);
begin
  TheDispatchPanel.Visible := False;
end;

When the click event is fired I receive the error "Cannot read properties of undefined (reading 'SetVisible')". In fact I can't access the properties of anything I've placed on the delphi form within this event. What am I missing?

My end goal for the click is to hide TheDispatchPanel, and inject a form into the Middle Panel.

I've attached the project in case I couldn't explain it correctly.
Project1.zip (7.9 KB)

I think because you're calling a function from within a JavaScript event, it uses a different context to execute your code from that point forward. Give this a try. Adding Form1. as a prefix to the call that is made in TForm1.showDispatchedTrip is likely all you need to do. It has 'forgotten' that it is in Form1.

procedure TForm1.showDispatchedTrip(someParam: String);
begin
  console.log(someParam);
  Form1.TheDispatchPanel.Visible := False;
end;

procedure TForm1.WebButton1Click(Sender: TObject);
begin
  TheDispatchPanel.ElementHandle.innerHTML := '<div id="addedAtRuntime">Hello</div>';
  asm
    var showDispatchedTrip = this.showDispatchedTrip;
    document.getElementById('addedAtRuntime').addEventListener ('click', function (e) {
      showDispatchedTrip(e.srcElement.id);
    });
  end;
end;

Gotcha, that did the trick. Thank you very much.

PS: love all the work/demo projects/articles you've put out.

You're very welcome and thanks very much! This is a continual learning exercise for all of us, no matter what areas of expertise any of us happen to have or not have.

For example, the other change I made to your code was to declare a variable to reference the Delphi function so you don't have to use the pas.whatever reference. That had bugged me for many months! But I woke up one day last week and did a giant :man_facepalming: and realized I could do it this way instead. I don't know how many hours I spent trying to find a way to do that previously.

We're all learning!

Ahh yeah nice. After a lot of digging all I could find was your post on creating the Menu Items dynamically, and that's where I ended up getting it from. I'm glad there's a cleaner way to do that.

1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.