Thusfar i have used api_datasource.isdmlnecessary to check if changes in datasources were pending. That api is called for many actions such as navigating to another record and closing the application. For my small prototypes that was sufficient.

Now i am building a large application with dozens of datasources and a large menu. It is impossible to make a list of all possible actions/clicks a user might do. So i need something else to detect dml.

In panels with a GRID based on a datasource it is relatively simple, i guess, to use the event "focuslost". But i also have panels with one record (not tabular) without a grid. What can i do then? If have not yet found a trigger to signal that i am not focussing anymore on such panel.

In fact i want my application to work exactly like Formspider IDE. As soon as i start editing the Source of a panel, immediately the tab title is turned into italic font. So, there must be "something" to detect that a user is making changes. What is that "something"?

Also, how can i keep track of all datasources with pending changes. In small application i can just loop along all datasources and do the isdmlnecessary check, but for large applications that is not possible. So, i have to keep track of all changing datasources. What is the best way to do that? I would like to use a plsql-table for this, but i do not know if that will work because Formspider is running stateless. Perhaps i can only do that with a session variable. How do you do this in Formspider IDE? When i click "save all", what happens then? How do you keep track of modified tabs?

Kind regards, Jan Willem Vermeer

asked 19 Sep '15, 11:40

Jan%20Willem%20Vermeer's gravatar image

Jan Willem V...
accept rate: 0%

Hi Jan Willem,

I work from the valueChanged events.

   <valueChanged action="someGenericValueChangedEvent"/>

I put them on all grids, but also on single record forms on all widgets to detect a change. When i edit a record in a modal dialog, then i just detect the datasource chenged when closing the dialog, so for modal dialogs i don't need to add these valueChanged events on all widgets. In this (generic) valueChanged event you can detect the datasource that changed and keep a list of changed datasources in a formspider session variable (api_session) for example.

You can set the tab title to italic by getting the tab title (api_tabbedpanel.gettabtitle) and add the html tags around it.


answered 19 Sep '15, 15:38

Michiel%20A's gravatar image

Michiel A
accept rate: 13%

Thanks Michiel. I will try this!

(20 Sep '15, 10:25) Jan Willem V...

Hi Jan,

how can i keep track of all datasources with pending changes.

There is an API called api_application.isDMLNecessary. This is the API you are looking for.

The italic tab is part of the XML Editor. The XML Editor with its tabs is a self contained Formspider Component. So the component detects the change in its content itself. The XML Editor Component also has PL/SQL API's which we use to detect if its content is changed.

You can use valueChanged event on components to detect if their value is changed and turn a tab title italic (or to give another visual indication that some value is changed). I don't think there is a quick an easy way to do this in Formspider. The only way I can think of is to put this event on every component you want to track. (Perhaps there should be an easy way.)

We usually have OK/Cancel buttons on screens to save or ignore changes. If the user navigates away from a modified record and might lose his changes because of this navigation, we use api_application.isDMLNecessary and if the answer is Y, we show an alert to the user with the following question and three options: You made modifications to [WhatEver]. Would you like to save your changes? Yes, No, Cancel.

Hope this helps.

Kind Regards,


answered 19 Sep '15, 15:41

Yalim%20Gerger's gravatar image

Yalim Gerger ♦♦
accept rate: 15%

Hi Yalim,

it is exactly what you are saying: there should be an easy way to detect that datasources are changing. I guess Formspider "knows" which datasources are changing, otherwise isDMLnecessary will not work. But it is too late!

My suggestion would be to add a new event to the datasource definition: "when items are changed". Then immediately after a user updates an item, i could for example write a statusmessage changes pending or turn the name of a tab into italic.

I can only accomplish this with the valuechanged event Michiel is suggesting, but that is also too late. Because when users do not leave the item, this event is just fired when a user tried any of the countless of actions possible in the application. So for almost every action i need to program two actions: one when there are no changes and one when there are changes pending.

I hope you understand what i mean :)

Kind regards, Jan Willem


answered 20 Sep '15, 10:38

Jan%20Willem%20Vermeer's gravatar image

Jan Willem V...
accept rate: 0%

Hi Jan Willem,

valueChanged event always fires when a user altered a field. When the user does not leave the field, but clicks a button, then also the valueChanged events fires on the field the user was at. (This is the reason my application always has an active save button. You cannot have an inactive save button in the manu that is only activated when something has changed because of this reason. )

(20 Sep '15, 11:21) Michiel A

Thanks Michiel, i understand and i managed to intercept all changes so my tab turns italic when the user changes something :) That's good news. The question however is: what happens next?

My problem is that the user can subsequently click on every button, the menu, other tabs, even close the tab. For every possible click we have to check if updates should be saved or not. We do that with an alert and that has max three options (yes/no/cancel for example). However, the alert does not know by which procedure it has been invoked. So, when the user makes his choice yes or no, we have to commit/rollback and proceed to the action the user wanted to do. But the alert does not know.

So, for every possible user click we have to program this:

1) formspider event to call a formspider action

2) formspider action to call a procedure

3) that procedure checks for pending changes. If NO then proceed. If yes raise an alert.

4) the alert with the relevant options (save, rollback, cancel click).

5) the procedure to handle the outcome of the alert.

If for example there are 6 buttons (query, create record, delete record, next record, previous record, help) and a tabbed panel and a menu we need to program 8 events, 8 actions, 8 alerts and 16 procedures. That's a lot of work and it also requires a lot of discipline to code this in a way that other developers will ever be able to understand what you have done.

I need something to make this easier. For example prevent the user from leaving a tab when changes are pending. I know that there are events PreTabChanged, PostTabChanged, PostTabClosed. What are they doing exactly?

Perhaps i make it too complex. But currently i do not know what's best.

Kind regards, Jan Willem


answered 20 Sep '15, 15:46

Jan%20Willem%20Vermeer's gravatar image

Jan Willem V...
accept rate: 0%

Hi Jan Willem,

I think in order to make it easier you need to make things more generic and therefor in my opinion you need a higher level of abstraction then just panels and datasources. As you know i created one higher level, and that is a Form (and created some tables to maintain these form definitions). When you have a tabbed interface and each tab represents a form and your repository tables know which panels belong to a form (naming convention) and which datasoures belong to a form and what relations this form has, then you can code generic procedures agains the repository tables.

Best, Michiel

(20 Sep '15, 16:44) Michiel A
Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here



Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported



Asked: 19 Sep '15, 11:40

Seen: 2,416 times

Last updated: 20 Sep '15, 16:44

© Copyright Gerger 2017