Tuesday, May 13, 2014

AngularJS: Create editable tables with dynamic columns

I was recently asked:

"[how do I] implement functionality for new/delete for arrays in AngularJS... [when] object structure is unknown until runtime execution."

There are lots of ways to do this using Metawidget, which is why Metawidget doesn't dictate one out-of-the-box. By default, AngularJS Metawidget will only render arrays as read-only:

Adding editing capabilities depends on your particular UI needs. Here's one approach. Essentially we:

  • Create an Angular directive to render a simple <table> with editable rows. This directive is not specific to Metawidget
  • Create a Metawidget WidgetBuilder that can instantiate and configure the editable table. This includes reading metadata at runtime to determine the table's columns

So you'll end up with something like this:

The important Metawidget bit looks like this:

$scope.metawidgetConfig = {

   ...custom WidgetBuilder...
   
   widgetBuilder: new metawidget.widgetbuilder.CompositeWidgetBuilder( [ function( elementName, attributes, mw ) {

      if ( attributes.type === 'array' ) {

         ...inspects array metadata...
         
         var inspectionResult = mw.inspect( mw.toInspect, typeAndNames.type, typeAndNames.names );
         
         ...creates editable table

         var widget = $( '<table>' ).attr( 'edit-table', '' )
               .attr( 'columns', columns ).attr( 'ng-model', mw.path + '.' + attributes.name );
         return widget[0];
      }

You can download a complete project here. Feedback welcome!

7 comments:

Sandesh Madarpalle said...
This comment has been removed by the author.
Sandesh Madarpalle said...

we are having data as json array with one of field as json array....we are trying provide UI like editable table with one of cell contain nested editable table.....but we are able to provide first editable table but we are facing issue while to show nested editable table...can you please help me for this

Sandesh Madarpalle said...



http://plnkr.co/edit/eWUBboDVZaqJicvHuld9?p=preview

Richard Kennard said...

Yes, you can do this.

The general approach is to use a nested Metawidget whenever you have some complex content to display.

In the example above, the 'editable table' directive does not support adding nested Metawidgets for unknown types. So you could add that.

Alternatively, you could forget about the 'editable table' directive completely and just use:

metawidget.widgetbuilder.HtmlWidgetBuilder( { alwaysUseNestedMetawidgetInTables: true })

This will force Metawidget to use nested Metawidgets everywhere in tables, which should give you the result you want?

szunyiap tang said...

I am new to metawidgets. Can you provide solution for the http://plnkr.co/edit/eWUBboDVZaqJicvHuld9?p=preview for editable array. It is similar to the problem I encountered. create editable array. Thanks

Richard Kennard said...

Okay fixed a couple bugs for you: http://plnkr.co/edit/j1OlIjO3j6lfei6iDYEh?p=preview

szunyiap tang said...

Thanks Kennard.
How to perform editing for the STORE DETAILS and display on the UI.
I am facing issue to do editing on the array of STORE DETAILS.
On the next step, I wanted to add array for store details like adding row