views:

6714

answers:

6

How do you save data from ExtJS form? Load data from the business layer into form or grid?

+1  A: 

I used ExtJs in conjuction with ASP.NET only through web services. It works just fine if you are willing to work without "Page" and all that stuff.

Marko Dumic
Could you provide some examples?
Michael Dubakov
Can you be more specific, what exactly do you need?
Marko Dumic
A: 

Most likely I found the best solution http://developmentalmadness.blogspot.com/2008/07/using-extjs-with-wcf.html

Michael Dubakov
the blog has moved, here is the new url:http://www.developmentalmadness.com/archive/2008/07/17/using-extjs-with-wcf.aspx
Mark J Miller
+5  A: 

For me, I have used an ASHX page to push straight XML - and then use the ExtJS data reader to read.. then, say using a form etc, I push the form data straight back to another ASHX page to interrogate/post to the DB.. darned if I know the best way - but it suited me, and seems very quick and stable, and most importantly it is easier to follow/debug.

Here is some code example if it helps... hopefully not to hinder!

GETTING DATA

As you will see, the URL to get the data is getting a simple ASHX (generic handler) .NET page which will return straight XML...

 // Define the core service page to get the data (we use this when reloading)
 var url = '/pagedata/getbizzbox.ashx?duration=today';

 var store = new Ext.data.GroupingStore(
 {
  // Define the source for the bizzbox grid (see above url def). We can pass (via the slider)
  // the days param as necessary to reload the grid
  url: url,

  // Define an XML reader to read /pagedata/getbizzbox.ashx XML results
  reader: new Ext.data.XmlReader(
  {
   // Define the RECORD node (i.e. in the XML <record> is the main row definition), and we also
   // need to define what field is the ID (row index), and what node returns the total records count
   record: 'record',
   id: 'inboxID',
   totalRecords: 'totalrecords'
  },
   // Setup mapping of the fields       
  ['inboxID', 'messageCreated', 'subject', 'message', 'messageOpened', 'messageFrom', 'messageFromID', 'groupedMessageDate']),

  // Set the default sort scenario, and which column will be grouped
  sortInfo: { field: 'groupedMessageDate', direction: "DESC" },
  groupField: 'groupedMessageDate'

 }); // end of Ext.data.store

DATA TO THE EXTJS GRID

Ok, I have some extra code here that creates a toolbar in the top part of the grid which you can ignore...

 var grid = new Ext.grid.GridPanel(
 {
  // Define the store we are going to use - i.e. from above definition
  store: store,

  // Define column structs

  // { header: "Received", width: 180, dataIndex: 'messageCreated', sortable: true, renderer: Ext.util.Format.dateRenderer('d-M-Y'), dataIndex: 'messageCreated' },

  columns: [
   { header: "ID", width: 120, dataIndex: 'inboxID', hidden: true },
   { header: "Received", width: 180, dataIndex: 'messageCreated', sortable: true },
   { header: "Subject", width: 115, dataIndex: 'subject', sortable: false },
   { header: "Opened", width: 100, dataIndex: 'messageOpened', hidden: true, renderer: checkOpened },
   { header: "From", width: 100, dataIndex: 'messageFrom', sortable: true },
   { header: "FromID", width: 100, dataIndex: 'messageFromID', hidden: true },
   { header: "Received", width: 100, dataIndex: 'groupedMessageDate', hidden: true }
  ],

  //  Set the row selection model to use
  gridRowModel: new Ext.grid.RowSelectionModel({ singleSelect: true }),

  // Set the grouping configuration
  view: new Ext.grid.GroupingView(
  {
   forceFit: true,
   groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Messages" : "Message"]})'
  }),

  // Render the grid with sizing/title etc
  frame: true,
  collapsible: false,
  title: 'BizzBox',
  iconCls: 'icon-grid',
  renderTo: 'bizzbox',
  width: 660,
  height: 500,
  stripeRows: true,

  // Setup the top bar within the message grid - this hosts the various buttons we need to create a new
  // message, delete etc
  tbar: [

   // New button pressed - show the NEW WINDOW to allow a new message be created
   {
    text: 'New',
    handler: function()
    {
     // We need to load the contacts, howver we only load the contacts ONCE to save
     // bandwidth - if new contacts are added, this page would have been destroyed anyway.
     if(contactsLoaded==false)
     {
      contactStore.load();
      contactsLoaded=true;
     }
     winNew.show();
    }
   },

   // Delete button pressed
   // We need to confirm deletion, then get the ID of the message to physically delete from DB and grid
   {
    text: 'Delete', handler: function() 
    {
     Ext.MessageBox.confirm('Delete message', 'are you sure you wish to delete this message?', function(btn) {

     // If selected YES, get a handle to the row, and delete
     if (btn == 'yes') 
     {
      // Get the selected row
      var rec = grid.getSelectionModel().getSelected();
      if(rec==null)
      {
       Ext.Msg.show(
       {
          title:'No message selected',
          msg: 'please ensure you select a message by clicking once on the required message before selecting delete',
          buttons: Ext.Msg.OK,
          icon: Ext.MessageBox.QUESTION
       });
      }

      // Proceed to delete the selected message
      else
      {
       var mesID = rec.get('inboxID');

       // AJAX call to delete the message
       Ext.Ajax.request(
       {
        url: '/postdata/bizzbox_message_delete.ashx',
        params: { inboxID: mesID },

        // Check any call failures
        failure: function() 
        {
         Ext.Msg.show(
         {
          title: 'An error has occured',
          msg: 'Having a problem deleting.. please try again later',
          buttons: Ext.Msg.OK,
          icon: Ext.MessageBox.ERROR
         })
        }, // end of failure check

        // Success check
        success: function()
        {
         // Need to remove the row from the datastore (which doesn't imapct
         // a reload of the data)
         store.remove(rec);
        }
       }); // end if delete ajax call

      } // end of ELSE for record selected or not

     } // end of YES button click
    })
   } // end of delete button pressed
  }] // end of tbar (toolbar def)

 }); // end of grid def

POSTING DATA FROM A FORM TO THE BACKEND

Again, note the url in the first part of the definition.. going to send the posted form data back to another ASHX page to then send to the DB...

  // ---------------------------------------------------------------------------------------------
  // DEFINE THE REPLY FORM
  // This is used to show the existing message details, and allows the user to respond
  // ---------------------------------------------------------------------------------------------
  var frmReply = new Ext.form.FormPanel(
  {
   baseCls: 'x-plain',
   labelWidth: 55,
   method: 'POST',
   url: '/postdata/bizzbox_message_reply.ashx',

   items: [
   {
    xtype: 'textfield',
    readOnly: true,
    fieldLabel: 'From',
    name: 'messageFrom',
    value: selectedRow.get('messageFrom'),
    anchor: '100%'  // anchor width by percentage
   },
   {
    xtype: 'textfield',
    readOnly: true,
    fieldLabel: 'Sent',
    name: 'messageCreated',
    value: selectedRow.get('messageCreated'),
    anchor: '100%'  // anchor width by percentage
   },
   {
    xtype: 'textarea',
    selectOnFocus: false,
    hideLabel: true,
    name: 'msg',
    value: replyMessage,
    anchor: '100% -53'  // anchor width by percentage and height by raw adjustment
   },

   // The next couple of fields are hidden, but provide FROM ID etc which we need to post a new/reply
   // message to
   {
    xtype: 'textfield',
    readOnly: true,
    fieldLabel: 'subject',
    name: 'subject',
    hidden: true,
    hideLabel: true,
    value: selectedRow.get('subject')
   },
   {
    xtype: 'textfield',
    readOnly: true,
    fieldLabel: 'FromID',
    name: 'messageFromID',
    hidden: true,
    hideLabel: true,
    value: selectedRow.get('messageFromID')
   },
   {
    xtype: 'textfield',
    readOnly: true,
    fieldLabel: 'InboxID',
    name: 'inboxID',
    hidden: true,
    hideLabel: true,
    value: selectedRow.get('inboxID')
   }]
  });  // end of frmReply

THE LAST BIT TO ACTUALLY SUMBIT THE ABOVE FORM TO THE BACKEND...

This window uses the form definition above to actually submit the data.. in the ASHX page the data simply comes through as a posted form - i.e. you can access via normal Request.form object.. I know there is a way to essentially post the form data to the ASHX page as XML, although for my purpose it wasn't required - quite simple form.

  // ---------------------------------------------------------------------------------------------
  // REPLY WINDOW - uses the frmReply as defined previously on stargate atlantis
  // ---------------------------------------------------------------------------------------------
  var win = new Ext.Window(
  {
   title: selectedRow.get("subject"),
   width: 500,
   height: 300,
   minWidth: 300,
   minHeight: 200,
   layout: 'fit',
   plain: false,
   bodyStyle: 'padding:5px;',
   buttonAlign: 'right',
   items: frmReply,

   // Add the action buttons for the message form
   buttons: [
   {
    // When the user replies, we send the form results to the posting ashx which updates
    // the DB etc, and returns the result
    text: 'reply',
    handler: function()
    {
     frmReply.getForm().submit({ waitMsg: 'Sending your message now...' });
    }
   },
   {
    text: 'close',
    handler: function()
    {
     // We need to close the message window
     win.close();
    }
   }]
  });

  // Show the message detail window      
  win.show();

Again, hope this helps somewhat - took me a few weeks to get to that!! getting too old for coding perhaps!

+1  A: 

We used the combination of ExtJS and WCF to great success. We used regular Asp.net page to provide theming, authentication and basic page UI then ExtJS kicked in on the client side issuing GETs to WCF services that returned pure simple bare format JSON (without the "d" property). Worked really great. WCF services were also part of the same web application so user authentication/authorisation was used throughout it.

The only problems we had were with pages returning files and pages that used a combination of both: Ajax and regular Asp.net postbacks. We had to take care of ExtJS control persistence on those roundtrips. But we've made it anyway.

ExtJS+WCF worked great and I'd recommend it to anyone doing a web application that has to be more window app like. Just don't overcomplicate your project with regular asp.net page functionality and Ajax combination. Or UpdatePanels as well.

A: 

If you interest to develop Extjs with java by gwt you can learn more at this extjs-gwt gxt blog. It maybe help you How to setup Ext js-GWT : GXT and Example on Eclipse Ganymede 3.4