Skip to content

Ext JS Windows and Dialogs — Modal Windows, Message Boxes, and Floating Panels

DodaTech Updated 2026-06-28 7 min read

In this tutorial, you will learn about Ext JS Windows and Dialogs. We cover key concepts, practical examples, and best practices to help you master this topic.

Ext JS Window is a floating panel that supports modal blocking, draggable positioning, resizing, maximization, toolbars, and built-in message boxes for alerts, confirms, and prompts.

What You'll Learn

  • Creating modal and non-modal windows
  • Using Ext.MessageBox for alerts and prompts
  • Custom window toolbars and buttons
  • Window positioning, resizing, and animations
  • Window state management

Why It Matters

Modal dialogs, confirmation boxes, and floating panels are essential in every application for user confirmations, data entry forms, and detail views. Ext JS Windows handle z-order stacking, keyboard traps, focus management, and layout isolation automatically.

Real-World Use

A CRM application where clicking a customer record opens a modal window with full details and edit form, delete confirmations use message boxes, report previews open in maximized windows, and tooltip-style info popups use lightweight windows.

Window Architecture

flowchart TD
    A[Window] --> B[Header]
    A --> C[Body]
    A --> D[Footer]
    A --> E[Buttons]
    B --> F[Title]
    B --> G[Tools]
    G --> H[Close]
    G --> I[Maximize]
    G --> J[Minimize]
    A --> K[State]
    K --> L[Modal Mask]
    K --> M[Draggable]
    K --> N[Resizable]
    style A fill:#e6f3ff,stroke:#4a90d9,stroke-width:2px

Basic Window

Ext.create('Ext.window.Window', {
  title: 'Basic Window',
  width: 500,
  height: 350,
  modal: true,
  layout: 'fit',
  bodyPadding: 15,
  html: '<p>This is a modal window. Click outside to see that the background is blocked.</p>',
  buttons: [{
    text: 'OK',
    handler: function(btn) {
      btn.up('window').close();
    }
  }, {
    text: 'Cancel',
    handler: function(btn) {
      btn.up('window').close();
    }
  }],
  // Window tools
  tools: [{
    type: 'gear',
    handler: function() { console.log('Settings'); }
  }, {
    type: 'help',
    handler: function() { console.log('Help'); }
  }]
}).show();

Expected output: A modal window appears centered on the screen. The background is dimmed by a mask. Clicking OK or Cancel closes the window. Gear and help icons appear in the header.

Ext.MessageBox

// Alert
Ext.Msg.alert('Connection Lost', 'Please check your network and try again.', function() {
  console.log('Alert dismissed');
});

// Confirm
Ext.Msg.confirm('Delete Record', 'Are you sure you want to delete this record?', function(btn) {
  if (btn === 'yes') {
    console.log('Record deleted');
  } else {
    console.log('Delete cancelled');
  }
});

// Prompt
Ext.Msg.prompt('Enter Password', 'Please enter your password to continue:', function(btn, text) {
  if (btn === 'ok') {
    console.log('Password entered:', text);
  }
}, this, false, '', { inputType: 'password' });

// Custom MessageBox
Ext.Msg.show({
  title: 'Save Changes?',
  msg: 'You have unsaved changes. Do you want to save before leaving?',
  buttons: Ext.Msg.YESNOCANCEL,
  icon: Ext.Msg.QUESTION,
  fn: function(btn) {
    if (btn === 'yes') {
      console.log('Save and continue');
    } else if (btn === 'no') {
      console.log('Discard and continue');
    } else {
      console.log('Cancel');
    }
  }
});

// Progress bar
Ext.Msg.show({
  title: 'Uploading...',
  msg: 'Please wait while your file uploads.',
  progress: true,
  width: 400
});

// Update progress
var progress = 0;
var interval = setInterval(function() {
  progress += 0.1;
  Ext.Msg.updateProgress(progress, Math.round(progress * 100) + '% completed');
  if (progress >= 1) {
    clearInterval(interval);
    Ext.Msg.hide();
  }
}, 500);

Expected output: Alert shows an information dialog. Confirm shows Yes/No buttons and returns the clicked button name. Prompt shows a text input. Custom MessageBox has Yes/No/Cancel with a question icon. Progress bar updates every 500ms.

Window with Form

var win = Ext.create('Ext.window.Window', {
  title: 'Edit Product',
  width: 500,
  height: 400,
  layout: 'fit',
  modal: true,
  items: [{
    xtype: 'form',
    bodyPadding: 15,
    defaults: { anchor: '100%', labelWidth: 100 },
    items: [{
      xtype: 'textfield',
      fieldLabel: 'Product Name',
      name: 'name',
      allowBlank: false
    }, {
      xtype: 'numberfield',
      fieldLabel: 'Price',
      name: 'price',
      step: 0.01
    }, {
      xtype: 'combobox',
      fieldLabel: 'Category',
      name: 'category',
      store: ['Electronics', 'Clothing', 'Food']
    }, {
      xtype: 'textarea',
      fieldLabel: 'Description',
      name: 'description',
      height: 80
    }]
  }],
  buttons: [{
    text: 'Save',
    handler: function(btn) {
      var form = btn.up('window').down('form').getForm();
      if (form.isValid()) {
        form.submit({
          success: function() { win.close(); },
          failure: function() { Ext.Msg.alert('Error', 'Save failed'); }
        });
      }
    }
  }, {
    text: 'Cancel',
    handler: function() { win.close(); }
  }]
});
win.show();

Expected output: A modal window containing a form panel. Fill in fields and click Save to submit. Validation prevents submitting incomplete fields. Cancel closes the window.

Window Positioning and Sizing

Ext.create('Ext.window.Window', {
  title: 'Positioning Demo',
  width: 300,
  height: 200,
  html: '<p>Right-click buttons to see different positions.</p>',
  // Initial center (default)
  buttons: [{
    text: 'Top-Left',
    handler: function(btn) {
      btn.up('window').setPagePosition(10, 10);
    }
  }, {
    text: 'Center',
    handler: function(btn) {
      btn.up('window').center();
    }
  }, {
    text: 'Maximize',
    handler: function(btn) {
      var win = btn.up('window');
      win.maximize ? win.maximize() : win.setSize(Ext.getBody().getViewSize());
    }
  }, {
    text: 'Animate',
    handler: function(btn) {
      var win = btn.up('window');
      win.animateTarget = Ext.getBody().child('button:last');
      win.close();
    }
  }],
  listeners: {
    move: function(win, x, y) {
      console.log('Window moved to:', x, y);
    },
    resize: function(win, w, h) {
      console.log('Window resized to:', w, 'x', h);
    }
  }
}).show();

Expected output: Clicking Top-Left moves the window to (10, 10). Center re-centers it. Maximize fills the viewport. Animate closes with a shrink animation toward the button.

Window State Management

Ext.create('Ext.window.Window', {
  title: 'Stateful Window',
  width: 400,
  height: 300,
  html: '<p>This window remembers its position and size. Close and reopen to see.</p>',
  // Enable state management
  stateful: true,
  stateId: 'myAppStatefulWindow',
  // Save position, size, and collapsed state
  stateEvents: ['move', 'resize', 'collapse', 'expand'],
  // Custom state provider (default is CookieProvider)
  stateManager: Ext.create('Ext.state.CookieProvider', {
    expires: new Date(new Date().getTime() + (1000 * 60 * 60 * 24 * 7)) // 7 days
  }),
  collapsed: false,
  collapsible: true,
  animCollapse: true,
  minimizable: true,
  maximizable: true,
  closeAction: 'hide', // 'hide' preserves state, 'close' destroys
  buttons: [{
    text: 'Save State',
    handler: function(btn) {
      btn.up('window').saveState();
      Ext.Msg.alert('Saved', 'Window state has been saved.');
    }
  }]
}).show();

Expected output: The window remembers its position and size across page reloads via cookies. It can be collapsed, minimized to taskbar, or maximized.

Window Animations

Ext.create('Ext.window.Window', {
  title: 'Animated Window',
  width: 400,
  height: 300,
  html: '<p>This window shows custom show/hide animations.</p>',
  // Built-in animations
  animShow: 'slideIn',
  animHide: 'slideOut',
  // Custom animation duration
  animDuration: 500,
  // Ghost effect when dragging
  ghost: true,
  buttons: [{
    text: 'Fade Out',
    handler: function(btn) {
      var win = btn.up('window');
      win.animate({ opacity: { to: 0 } }, function() {
        win.hide();
        win.setOpacity(1);
      });
    }
  }, {
    text: 'Shake',
    handler: function(btn) {
      var win = btn.up('window');
      var pos = win.getPosition();
      var count = 0;
      var shakeInterval = setInterval(function() {
        var offset = count % 2 === 0 ? 10 : -10;
        win.setPosition(pos[0] + offset, pos[1]);
        count++;
        if (count > 10) {
          clearInterval(shakeInterval);
          win.setPosition(pos[0], pos[1]);
        }
      }, 30);
    }
  }]
}).show();

Expected output: The window slides in when opened and slides out when closed. Ghost shows a semi-transparent copy while dragging. Fade Out button animates opacity before hiding. Shake button wobbles the window horizontally.

Common Mistakes

  1. Not setting modal: true for blocking dialogs - Non-modal windows allow interaction with the background. For critical confirmations, always use modal.

  2. Calling show() before setting content - Window content must be set before calling show() to avoid layout reflows. Configure all items first, then show.

  3. Destroying windows after close - close() hides the window. To remove it permanently, use close() with closeAction: 'destroy' or call destroy() explicitly.

  4. Using Ext.Msg inside an Ext.Msg callback - Nested message boxes work but create confusing UX. Use buttons or toolbars in the parent dialog instead.

  5. Not managing z-order manually - Multiple windows stack in creation order. Use window.toFront() and window.toBack() to manage stacking explicitly.

Practice Questions

  1. What is the difference between modal and non-modal windows?
  2. How do you show a confirm dialog with Yes/No/Cancel options?
  3. How do you center a window after it has been shown?
  4. What does closeAction: 'hide' do differently from closeAction: 'destroy'?
  5. How do you save and restore window position across sessions?

Challenge: Build a desktop-like application with: a main toolbar that opens multiple windows (customer list, order form, report viewer), windows that can be minimized to a taskbar at the bottom, state persistence via cookies, window z-order management with a window menu, and message box confirmations before destructive actions.

FAQ

What is the difference between Ext.Msg.alert and Ext.Msg.show?

alert() is a shortcut for simple OK dialogs. show() provides full customization: custom buttons, icons, progress bars, and callback functions.

Can I make a window non-draggable?

Yes. Set draggable: false on the window config. The window stays fixed in its initial position.

How do I prevent a window from being resized beyond min/max dimensions?

Set minWidth, minHeight, maxWidth, and maxHeight on the window. The resize handles enforce these limits.

Can I have a window inside another window?

Yes, but child windows are still positioned relative to the viewport, not the parent. Use container panels if you need constrained floating content.

How do I handle the escape key to close a window?

The window's closeAction handles escape by default if closable is true. Override the onEsc method for custom behavior.

Mini Project

Build a desktop-like interface with: a main window as the application container with a toolbar, multiple document windows that open from toolbar buttons, a taskbar at the bottom showing minimized windows (click to restore), window state management via cookies, tabbed document windows for multi-file editing, and a Window menu listing all open windows with activate/focus capability.

What's Next

Windows present content in floating containers. Learn how Ext JS Charts visualize data with bar, line, pie, and other chart types with interactive features.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro