Ticket #845 (closed defect: fixed)

Opened 12 months ago

Last modified 6 months ago

QDialog rendering events problems when modified

Reported by: dmarkic Owned by: somebody
Priority: shipstopper Milestone: 2.1.1
Component: QControls Version: 2.1.0 Stable
Keywords: qdialog,events,actions Cc: d@…

Description

Hello!
I'm using 2.1 version from SVN (I tried original 2.1, same problem).
Short: Every time the QDialog is modified (blnModified === true) it rerenders all the events/actions. Since you're using jQuery's .on() for events, this means that for every ajax call, if QDialog is modified, you register another event. For instance, QDialog_Close event, when you close the dialog, you get n-times the same event called. For simple reproduction of this problem, I've modified the shipped example script (assets/_core/php/examples/other_controls/jq_example.php):
1. Added AjaxAction? to QDialog: QDialog_CloseEvent
2. QDialog_CloseEvent calls method to call QApplication::DisplayAlert?()
3. Modified button_clicked() method, to change the QDialog text (force modification) and open the Dialog.

Every time, the control is modified it will call QDialogGen::GetEndScript?(), which calls parent::GetEndScript?(), which calls GetActionAttributes?() and renders the actions again.

I was hoping to come to a solution, but I just cannot figure it out, how to prevent actions from being rendered.

It's 2.1 problem, since it's working normally in 2.0.2 (but JQUI events are handled differently there).

It's a real show stopper and I hope we can make this work properly.
Any ideas are welcome!

Kind regards,
Dejan Markic

Attachments

jq_example.php Download (13.6 KB) - added by dmarkic 12 months ago.
Modified jq_example file
ticket845.patch Download (16.2 KB) - added by vakopian 11 months ago.
patch for the general case

Change History

Changed 12 months ago by dmarkic

Modified jq_example file

  Changed 12 months ago by vakopian

  • priority changed from must to shipstopper
  • component changed from Other to QControls

follow-up: ↓ 5   Changed 12 months ago by mikederfler

I have found the problem:

When an Ajax update occures the controls dom element gets replaced, but not its wrapper dom element. And because in the case of the dialog all events are bound to the wrapper they get duplicated because the wrapper dom element is not removed.

Simple solution:

add

public function GetEndScript() {
			return   . sprintf('jQuery("#%s").off();', $this->getJqControlId()) . parent::GetEndScript();
		}

to DialogBase?.
This unbindes all events from the wrapper, before binding them again (necessary because some additional event handler could have been added)

  Changed 12 months ago by mikederfler

There is a typo in the code: remove the "." after return

  Changed 12 months ago by dmarkic

Great, it works!

Thanks!

in reply to: ↑ 2   Changed 11 months ago by vakopian

Should this be done everywhere in the jQuery UI controls where $this->getJqControlId() != $this->ControlId? So the GetEndScript method in the "Gen" classes would look like this:

public function GetEndScript() {
	$str = '';
	if ($this->getJqControlId() !== $this->ControlId) {
		$str = sprintf('jQuery("#%s").off(); ', $this->getJqControlId())
	}
	return $str . $this->GetControlJavaScript() . '; ' . parent::GetEndScript();
}

Changed 11 months ago by vakopian

patch for the general case

  Changed 11 months ago by vakopian

  • status changed from new to in_QA

  Changed 6 months ago by vakopian

  • status changed from in_QA to closed
  • resolution set to fixed

(In [1501]) fixes #845

Note: See TracTickets for help on using tickets.