Getting confirmation from a user in perspective?

I have a view where a user enters a form. After they enter the first few rows, we find that there’s previous data to help them pre-fill out the form. I want to just confirm with the user that they want us to do this form them. In vision it would be system.gui.confirm("Prefill out form with data?"): but in perspective I am not sure how I would accomplish this. What can I do? Just a simple popup asking the user YES and then I run my prepopulate data function or NO and I pass.

Perspective provides a lot more flexibility here.

Here are the basic steps, which you could make as complicated or logic-heavy as you’d like:

  1. Create a View which contains a Label or Markup Component with your “Prefill form” text, and both a “Confirm” and “Cancel” button.
  2. This View should also accept a param of id.
  3. The “Confirm” button should include an onClick Event which invokes a script action (if you’re following my instructions from this thread, then this Script Action should set the session properties which your form fields are bound to).
  4. The “Confirm” button’s script should also include system.perspective.closePopup(id=self.view.params.id) as the final line (this is why the Popup needs to accept a parameter which defines the id of the Popup.
  5. The “Cancel” button should use the same closePopup() function as the “Confirm” button, but that should be all the logic it needs.
  6. Use a valueChanged Event on a field of your choosing to invoke system.perspective.openPopup(view=<a_configured_view>, id=<some_unique_value>, params={"id:":<the_same_unique_value>}, modal=True)

Using these steps should provide your user with a Modal Popup which includes both a confirm and cancel button, where when the Confirm button is clicked you perform your form fill-in logic and then close the Popup, or if "Cancel: is clicked, the Popup will just close and do nothing.

2 Likes

Ha I was the user you were replying to in that other thread. I understand most of that.

Real quick here is my actual set up -
My host view looks like


and the script on my Yes button is this

	userId = self.session.custom.userIdx
	lastFormDate = system.db.runScalarQuery("SELECT dayOfWork FROM dailysafetyRecords WHERE userId = %i ORDER BY dayOfWork DESC LIMIT 1"%(userId))
	title = "Confirm"
	message = "Use safety from from %s"%(lastFormDate)
	system.perspective.openPopup("useLastSafetyForm",view="Confirmation/confirm", params={"title":title, "message":message}, modal=True)

And I thought the first argument of the openPopup was an id, but you mean I need a different separate id param to feed it?

And on the confirm button the script
is

system.perspective.sendMessage(view="myParentView",...)
system.perspective.closePopup(id=self.view.params.id)

and I guess that sendMessage is where I could send something to my parentView to tell it hey they said yes, but I do not see this onValueChange event you are talking about in the extension functions on components or my root container. Im using 8.0.6 if that matters/if it wasn’t introduced yet.

Oh wait I think I understand now, I can attach a message handler on my yes button?

Ah, sorry, looking at my reply from before I can see that the openPopup recommendations I provided may have been misleading. Here’s the documentation for openPopup.

You want something like

popupId = <something_unique>
userId = self.session.custom.userIdx
lastFormDate = system.db.runScalarQuery("SELECT dayOfWork FROM dailysafetyRecords WHERE userId = %i ORDER BY dayOfWork DESC LIMIT 1"%(userId))
title = "Confirm"
message = "Use safety from from %s"%(lastFormDate)
system.perspective.openPopup(id=popupId, view="Confirmation/confirm", title=title, params={"message":message, "id": popupId}, modal=True)

It’s important that you pass the popupId as both the function argument AND a parameter to the Popup because the openPopup call will open a Popup with the ID, but the buttons in your View ALSO need to use that ID. Since you are also passing it to the View, then those buttons can access the ID as a property of the View and use it in closePopup.

NOTE: notice that I’ve taken title OUT of the params object, and I’ve placed a named parameter of id.

Yes, you could, but you shouldn't need to.

Ok I got it working but I’m not sure if I did it the way you said. And I just want to make sure that my method isn’t bad security wise. I want this confirmation button to be very modular so I can use it all over my project. So I am sending the name of the message handler and the view to send the message to as well. My new Yes button logic looks like

	import system.db
	userId = self.session.custom.userIdx
	lastFormDate = system.db.runScalarQuery("SELECT dayOfWork FROM dailysafetyRecords WHERE userId = %i ORDER BY dayOfWork DESC LIMIT 1"%(userId))
	currentView = "Safety/safetyContinuation"
    system.perspective.openPopup("useLastSafetyForm",view="Confirmation/confirm", params={"id":"useLastSafetyForm","title":"Use last form?", "message":"Use safety from from %s"%(lastFormDate), "view":currentView}, modal=True)

In my confirmation modal, I have

	system.perspective.sendMessage(self.view.params.id,payload={"confirm":1},view=self.view.params.view)
	system.perspective.closePopup(id=self.view.params.id)

Lastly in my root container I have a message handler for that useLastSafetyForm.

This IS working. I just want to know if its a bad idea to do this.

It’s not bad from a security point-of-view, it’s just overly complicated; if someone else tries to figure out what is going on in your Views without knowledge of this thread, it’s going to be a headache for them.

Even though this might be working, there is an aspect of your code which probably isn’t doing what you’re thinking it is doing: the view argument in the sendMessage call is being ignored. If you’re trying to specify a scope, then you do not want to use “view” you want to use “page”, like so:

system.perspective.sendMessage(messageType=self.view.params.id, payload={"confirm":1},scope="page")
system.perspective.closePopup(id=self.view.params.id)

And here’s why:
“view” sets the scope so that only listeners within the same View (your Popup, since the “Confirm” button is invoking the function).
“page” sets the scope so that ALL Views within the current Page will be able to “hear” the broadcast message.
“session” sets the scope so that ALL Views in ALL Pages in the current session (so if you have multiple tabs or windows open as part of the same session) will be able to hear the broadcast message.

So if you’re only passing the view name for use in the message handler, you can omit that part form your params, because it’s not going to help you at all, and isn’t actually doing anything in your current implementation.

Also, there’s no need to import system.db.

1 Like

Yea I understand its a little complicated but I know for a fact that I will need to be using it with different views and message handlers at different points where I need confirmation so I wanted it to be abstracted and generalized a bit. I’m documenting how to use it.

That is good info, I realized I misread the documentation on system.perspective.sendMessage. I do need to change my scope.

And ah yes, I was coding a bunch of functions earlier and the habit of having to import stuck.