Stand With Ukraine. Stop Putin. Stop War.

Working on my latest project, a (hotel) property management tool for MODX Revolution, I wanted to open a "Pick a Room" window from a "Check Inwindow with tabs, where some of the values in the Check In window would be used to filter the available rooms. Basically it would pre-filter on the check in and check out dates, as well as room type chosen in the reservation process. It took me a bit of debugging before I found the right function in the MODext extension to ExtJS - so I figured I'd share with my honored readers and fellow developers :)

What the Docs tell us

MODx.Window is a MODext implementation of a regular ExtJS Ext.Window object, and the MODx.Window documentation tells us the following:

MODExt Windows are a convenient way to display record data from a Grid or AJAX request for editing. Windows automatically include a FormPanel which you can add form fields (and other components) to. Submitting/saving a Window actually submits the FormPanel, and initiates an AJAX request to your connector.

So compared the Ext.Window, we already have an added formpanel (in this case, the MODext implementation of a form panel) which we can interact with. Awesome! So now let's just get the Window, for example using Ext.getCmp('window-id') or even simply referencing "this" in the handler (assuming you specified scope: this as well), and use our beloved getValues() function on that.

Right? Sorry: function getValues is not defined there!

What the Docs should have told us

While there's definitely a form panel available they've hidden it in plain sight. In most applications this doesn't matter as you would just submit the window which initiates the request to the connector, but if you, like me, want to work with the form's values before submitting to open another window or perform some other kind of logic with the values, you'll need to specifically get the formpanel.

/* 
	Field definition excerpt
 */
{
	xtype: 'button',
	text: _('fdmday.room.picker'),
	handler: this.openRoomPicker,
	scope: this,
	anchor: '1'
}

/* 
	The this.openRoomPicker function
 */

Ext.extend(FrontDeskMan.window.CheckIn,MODx.Window,{
	openRoomPicker: function() {
		var record = this.fp.getForm().getValues();
		var win = MODx.load({
			xtype: 'frontdeskman-window-roompicker',
			targetForm: this.config.id,
			gridParams: record
		});
		win.setValues(record);
		win.show();
	}
}

What's going on there:

  1. In our field definition, where my button is which needs to open the window, I defined the "scope: this" to force the scope of the handler to be the FrontDeskMan.window.CheckIn object, instead of the button.
  2. The handler is set to this.openRoomPicker, which is added as extension to the object later on.
  3. Line 18 is where it gets interesting:
    1. First we reference "this", which is the window (use console.log(this) to make sure!).
    2. From "this" we get the "fp" object, which, as you may have guessed by now, stands for FormPanel.
    3. From this panel we use getForm() to get the actual form.
    4. From this form we use getValues() to get an object with the current values in the window.
  4. After that we load the room picker window by it's registered xtype, and pass it two extra properties which will help it identify the form to set the room in, as well as the record to use in the grid in that window. The room picker window "decodes" these values to where they are needed.
  5. We use win.setValues(record) to fill the form inside the window (which provides options to filter by) with the values we already know. While normally you can simply pass the "record" configuration object, in this case my roompicker window uses a column layout with a form layout and a grid, and the "record" config object only works when the entire form is in the "main formpanel", so directly defined as fields and not as tabs in the window or other fancy layouts.
  6. We show the new window.

Hope this helps someone!

For those interested or totally flabbergasted by this weird setup of mine, here's a screenshot of what is going on:

Luke

Sweet. I also tried this.getForm().getValues() and wondered why nothing showed up. I would be lost if it weren't for the console. Thanks Mark and congrats on the new role at MODx!

Tim Butterworth

Hi, great ... this has helped me out too.

Just one extra bit to help me out: from the choose room button. how does the selection get passed back and then fire an update on the first form to update the selection from the room picker?

I am using this where the second popup window is fired from a grid on the first form; the second popup creates a new record, and when it has saved and the window closes I want the grid on the first form to be refreshed.

Thanks
Tim

steffan

Hi, Nice article!

Is there a way to use the gridParams in the window title f.e.?

Thanks!

Comments are closed :(

While I would prefer to keep comments open indefinitely, the amount of spam that old articles attract is becoming a strain to keep up with and I can't always answer questions about ancient blog postings. If you have valuable feedback or important questions, please feel free to get in touch.