PageRenderTime 92ms CodeModel.GetById 35ms app.highlight 48ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/galaxy/web/controllers/forms.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 657 lines | 650 code | 4 blank | 3 comment | 5 complexity | c874073bb08276dbdf4fb8a4f0f37280 MD5 | raw file
  1from galaxy.web.base.controller import *
  2from galaxy.model.orm import *
  3from galaxy.datatypes import sniff
  4from galaxy import model, util
  5import logging, os, sys
  6from galaxy.web.form_builder import * 
  7from galaxy.tools.parameters.basic import parameter_types 
  8from elementtree.ElementTree import XML, Element
  9from galaxy.util.odict import odict
 10import copy
 11from galaxy.web.framework.helpers import time_ago, iff, grids
 12
 13log = logging.getLogger( __name__ )
 14
 15VALID_FIELDNAME_RE = re.compile( "^[a-zA-Z0-9\_]+$" )
 16
 17class FormsGrid( grids.Grid ):
 18    # Custom column types
 19    class NameColumn( grids.TextColumn ):
 20        def get_value(self, trans, grid, form):
 21            return form.latest_form.name
 22    class DescriptionColumn( grids.TextColumn ):
 23        def get_value(self, trans, grid, form):
 24            return form.latest_form.desc
 25    class TypeColumn( grids.TextColumn ):
 26        def get_value(self, trans, grid, form):
 27            return form.latest_form.type
 28    # Grid definition
 29    title = "Forms"
 30    template = "admin/forms/grid.mako"
 31    model_class = model.FormDefinitionCurrent
 32    default_sort_key = "-create_time"
 33    num_rows_per_page = 50
 34    preserve_state = True
 35    use_paging = True
 36    default_filter = dict( deleted="False" )
 37    columns = [
 38        NameColumn( "Name", 
 39                    key="name", 
 40                    model_class=model.FormDefinition,
 41                    link=( lambda item: iff( item.deleted, None, dict( operation="view_latest_form_definition", 
 42                                                                       id=item.id ) ) ),
 43                    attach_popup=True, 
 44                    filterable="advanced" ),
 45        DescriptionColumn( "Description",
 46                           key='desc',
 47                           model_class=model.FormDefinition,
 48                           filterable="advanced" ),
 49        TypeColumn( "Type" ),
 50        grids.DeletedColumn( "Deleted", 
 51                       key="deleted", 
 52                       visible=False, 
 53                       filterable="advanced" )
 54    ]
 55    columns.append( grids.MulticolFilterColumn( "Search", 
 56                                                cols_to_filter=[ columns[0], columns[1] ], 
 57                                                key="free-text-search",
 58                                                visible=False,
 59                                                filterable="standard" ) )
 60    operations = [
 61        grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted )  ),
 62        grids.GridOperation( "Delete", allow_multiple=True, condition=( lambda item: not item.deleted )  ),
 63        grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ),    
 64    ]
 65    global_actions = [
 66        grids.GridAction( "Create new form", dict( controller='forms', action='create_form_definition' ) )
 67    ]
 68
 69class Forms( BaseUIController ):
 70    # Empty TextField
 71    empty_field = { 'name': '', 
 72                    'label': '', 
 73                    'helptext': '', 
 74                    'visible': True,
 75                    'required': False,
 76                    'type': model.TextField.__name__,
 77                    'selectlist': [],
 78                    'layout': 'none',
 79                    'default': '' }
 80    forms_grid = FormsGrid()
 81
 82    @web.expose
 83    @web.require_admin
 84    def browse_form_definitions( self, trans, **kwd ):
 85        if 'operation' in kwd:
 86            operation = kwd['operation'].lower()
 87            if not kwd.get( 'id', None ):
 88                return trans.response.send_redirect( web.url_for( controller='forms',
 89                                                                  action='browse_form_definitions',
 90                                                                  status='error',
 91                                                                  message="Invalid form ID") )
 92            if operation == "view_latest_form_definition":
 93                return self.view_latest_form_definition( trans, **kwd )
 94            elif operation == "delete":
 95                return self.delete_form_definition( trans, **kwd )
 96            elif operation == "undelete":
 97                return self.undelete_form_definition( trans, **kwd )
 98            elif operation == "edit":
 99                return self.edit_form_definition( trans, **kwd )
100        return self.forms_grid( trans, **kwd )
101    @web.expose
102    @web.require_admin
103    def view_latest_form_definition( self, trans, **kwd ):
104        '''Displays the layout of the latest version of the form definition'''
105        form_definition_current_id = kwd.get( 'id', None )
106        try:
107            form_definition_current = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ) \
108                                                      .get( trans.security.decode_id( form_definition_current_id ) )
109        except:
110            return trans.response.send_redirect( web.url_for( controller='forms',
111                                                              action='browse_form_definitions',
112                                                              message='Invalid form',
113                                                              status='error' ) )
114        return trans.fill_template( '/admin/forms/view_form_definition.mako',
115                                    form_definition=form_definition_current.latest_form )
116    @web.expose
117    @web.require_admin
118    def create_form_definition( self, trans, **kwd ):
119        params = util.Params( kwd )
120        message = util.restore_text( params.get( 'message', ''  ) )
121        status = params.get( 'status', 'done' )
122        self.__imported_from_file = False
123        if params.get( 'create_form_button', False ):   
124            form_definition, message = self.save_form_definition( trans, form_definition_current_id=None, **kwd )
125            if not form_definition:
126                return trans.response.send_redirect( web.url_for( controller='forms',
127                                                                  action='create_form_definition',
128                                                                  message=message,
129                                                                  status='error',
130                                                                  name=util.restore_text( params.get( 'name', '' ) ),
131                                                                  description=util.restore_text( params.get( 'description', '' ) ) ))
132            if self.__imported_from_file:
133                return trans.response.send_redirect( web.url_for( controller='forms',
134                                                                  action='edit_form_definition',
135                                                                  id=trans.security.encode_id( form_definition.current.id )) )                  
136            else:
137                return trans.response.send_redirect( web.url_for( controller='forms',
138                                                                  action='edit_form_definition',
139                                                                  id=trans.security.encode_id( form_definition.current.id ),
140                                                                  add_field_button='Add field',
141                                                                  name=form_definition.name,
142                                                                  description=form_definition.desc,
143                                                                  form_type_select_field=form_definition.type ) )  
144        inputs = [ ( 'Name', TextField( 'name', 40, util.restore_text( params.get( 'name', '' ) ) ) ),
145                   ( 'Description', TextField( 'description', 40, util.restore_text( params.get( 'description', '' ) ) ) ),
146                   ( 'Type', self.__build_form_types_widget( trans, selected=params.get( 'form_type', 'none' ) ) ),
147                   ( 'Import from csv file (Optional)', FileField( 'file_data', 40, '' ) ) ]
148        return trans.fill_template( '/admin/forms/create_form.mako', 
149                                    inputs=inputs,
150                                    message=message,
151                                    status=status )
152    @web.expose
153    @web.require_admin
154    def edit_form_definition( self, trans, response_redirect=None, **kwd ):
155        '''
156        This callback method is for handling form editing.  The value of response_redirect
157        should be an URL that is defined by the caller.  This allows for redirecting as desired
158        when the form changes have been saved.  For an example of how this works, see the 
159        edit_template() method in the base controller.
160        '''
161        params = util.Params( kwd )
162        message = util.restore_text( params.get( 'message', ''  ) )
163        status = params.get( 'status', 'done' )
164        try:
165            form_definition_current = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ).get( trans.security.decode_id(kwd['id']) )
166        except:
167            return trans.response.send_redirect( web.url_for( controller='forms',
168                                                              action='browse_form_definitions',
169                                                              message='Invalid form',
170                                                              status='error' ) )
171        form_definition = form_definition_current.latest_form
172        # TODO: eliminate the need for this refresh param.
173        if params.get( 'refresh', False ):
174            # Refresh 
175            current_form = self.get_current_form( trans, **kwd )
176        else:
177            # Show the saved form for editing
178            current_form = self.get_saved_form( form_definition )
179        # Save changes
180        if params.get( 'save_changes_button', False ):
181            new_form_definition, message = self.save_form_definition( trans, form_definition_current_id=form_definition.form_definition_current.id, **kwd )
182            # if validation error encountered while saving the form, show the 
183            # unsaved form, with the error message
184            if not new_form_definition:
185                status = 'error'
186            else:
187                # everything went fine. form saved successfully. Show the saved form or redirect
188                # to response_redirect if appropriate.
189                if response_redirect:
190                    return trans.response.send_redirect( response_redirect )
191                form_definition = new_form_definition
192                current_form = self.get_saved_form( form_definition )
193                message = "The form '%s' has been updated with the changes." % form_definition.name
194        # Add a layout grid
195        elif params.get( 'add_layout_grid_button', False ):
196            current_form[ 'layout' ].append( '' )
197        # Delete a layout grid
198        elif params.get( 'remove_layout_grid_button', False ):
199            index = int( kwd[ 'remove_layout_grid_button' ].split( ' ' )[2] ) - 1
200            del current_form[ 'layout' ][index]
201        # Add a field
202        elif params.get( 'add_field_button', False ):
203            field_index = len( current_form[ 'fields' ] ) + 1
204            self.empty_field[ 'name' ] = '%i_field_name' % field_index
205            self.empty_field[ 'label' ] = 'Field label %i' % field_index
206            current_form[ 'fields' ].append( self.empty_field )
207        # Delete a field
208        elif params.get( 'remove_button', False ):
209            # find the index of the field to be removed from the remove button label
210            index = int( kwd[ 'remove_button' ].split( ' ' )[2] ) - 1
211            del current_form[ 'fields' ][ index ]
212        # Add SelectField option
213        elif 'Add' in kwd.values():
214            current_form, status, message = self.__add_select_field_option( trans=trans, 
215                                                                            current_form=current_form,
216                                                                            **kwd)
217        # Remove SelectField option
218        elif 'Remove' in kwd.values():
219            current_form, status, message = self.__remove_select_field_option( trans=trans, 
220                                                                               current_form=current_form,
221                                                                               **kwd)
222        return self.show_editable_form_definition( trans=trans,
223                                                   form_definition=form_definition,
224                                                   current_form=current_form, 
225                                                   message=message,
226                                                   status=status,
227                                                   response_redirect=response_redirect,
228                                                   **kwd )
229    def get_saved_form( self, form_definition ):
230        '''
231        This retrieves the saved form and returns a dictionary containing the name, 
232        desc, type, layout & fields of the form
233        '''
234        if form_definition.type == form_definition.types.SAMPLE:
235            return dict( name=form_definition.name,
236                         desc=form_definition.desc,
237                         type=form_definition.type,
238                         layout=list( copy.deepcopy( form_definition.layout ) ), 
239                         fields=list( copy.deepcopy( form_definition.fields ) ) )
240        return dict( name=form_definition.name,
241                     desc=form_definition.desc,
242                     type=form_definition.type,
243                     layout=[], 
244                     fields=list( copy.deepcopy( form_definition.fields ) ) )
245
246    def get_current_form( self, trans, **kwd ):
247        '''
248        This method gets all the unsaved user-entered form details and returns a 
249        dictionary containing the name, desc, type, layout & fields of the form
250        '''
251        params = util.Params( kwd )
252        name = util.restore_text( params.name ) 
253        desc = util.restore_text( params.description ) or ""
254        form_type = util.restore_text( params.form_type_select_field )
255        # get the user entered layout grids in it is a sample form definition
256        layout = []
257        if form_type == trans.model.FormDefinition.types.SAMPLE:
258            index = 0
259            while True:
260                if kwd.has_key( 'grid_layout%i' % index ):
261                    grid_name = util.restore_text( params.get( 'grid_layout%i' % index, '' ) )
262                    layout.append( grid_name )
263                    index = index + 1
264                else:
265                    break
266        # for csv file import
267        csv_file = params.get( 'file_data', '' )
268        fields = []
269        if csv_file == '':
270            # get the user entered fields
271            index = 0
272            while True:
273                if kwd.has_key( 'field_label_%i' % index ):
274                    fields.append( self.__get_field( index, **kwd ) )
275                    index = index + 1
276                else:
277                    break
278            fields = fields
279        else:
280            fields, layout = self.__import_fields(trans, csv_file, form_type)
281        return dict(name = name,
282                    desc = desc,
283                    type = form_type,
284                    layout = layout,
285                    fields = fields)
286    def save_form_definition( self, trans, form_definition_current_id=None, **kwd ):
287        '''
288        This method saves the current form 
289        '''
290        # check the form for invalid inputs
291        flag, message = self.__validate_form( **kwd )
292        if not flag:
293            return None, message
294        current_form = self.get_current_form( trans, **kwd )
295        # validate fields
296        field_names_dict = {} 
297        for field in current_form[ 'fields' ]:
298            if not field[ 'label' ]:
299                return None, "All the field labels must be completed."
300            if not VALID_FIELDNAME_RE.match( field[ 'name' ] ):
301                return None, "'%s' is not a valid field name." % field[ 'name' ]
302            if field_names_dict.has_key( field[ 'name' ] ):
303                return None, "Each field name must be unique in the form definition. '%s' is not unique." % field[ 'name' ]
304            else:
305                field_names_dict[ field[ 'name' ] ] = 1
306        # if type is sample form, it should have at least one layout grid
307        if current_form[ 'type' ] == trans.app.model.FormDefinition.types.SAMPLE and not len( current_form[ 'layout' ] ):
308            current_form[ 'layout' ] = [ 'Layout1' ]
309        # create a new form definition
310        form_definition = trans.app.model.FormDefinition( name=current_form[ 'name' ], 
311                                                          desc=current_form[ 'desc' ], 
312                                                          fields=current_form[ 'fields' ], 
313                                                          form_definition_current=None, 
314                                                          form_type=current_form[ 'type' ], 
315                                                          layout=current_form[ 'layout' ] )
316        if form_definition_current_id: # save changes to the existing form    
317            # change the pointer in the form_definition_current table to point 
318            # to this new record
319            form_definition_current = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ).get( form_definition_current_id )
320        else: # create a new form
321            form_definition_current = trans.app.model.FormDefinitionCurrent()
322        # create corresponding row in the form_definition_current table
323        form_definition.form_definition_current = form_definition_current
324        form_definition_current.latest_form = form_definition
325        trans.sa_session.add( form_definition_current )
326        trans.sa_session.flush()
327        message = "The new form named '%s' has been created. " % (form_definition.name)
328        return form_definition, message
329    def show_editable_form_definition( self, trans, form_definition, current_form, message='', status='done', response_redirect=None, **kwd ):
330        """
331        Displays the form and any of the changes made to it in edit mode. In this method 
332        all the widgets are build for all name, description and all the fields of a form 
333        definition.
334        """
335        params = util.Params( kwd )
336        # name & description
337        form_details = [ ( 'Name', TextField( 'name', 40, current_form[ 'name' ] ) ),
338                         ( 'Description', TextField( 'description', 40, current_form[ 'desc' ] ) ),
339                         ( 'Type', HiddenField( 'form_type_select_field', current_form['type']) ) ]
340        form_layout = []
341        if current_form[ 'type' ] == trans.app.model.FormDefinition.types.SAMPLE:
342            for index, layout_name in enumerate( current_form[ 'layout' ] ):
343                form_layout.append( TextField( 'grid_layout%i' % index, 40, layout_name )) 
344        # fields
345        field_details = []
346        for field_index, field in enumerate( current_form[ 'fields' ] ):
347            field_widgets = self.build_form_definition_field_widgets( trans=trans, 
348                                                                      layout_grids=current_form['layout'], 
349                                                                      field_index=field_index, 
350                                                                      field=field, 
351                                                                      form_type=current_form['type'] )
352            field_details.append( field_widgets )
353        return trans.fill_template( '/admin/forms/edit_form_definition.mako',
354                                    form_details=form_details,
355                                    field_details=field_details,
356                                    form_definition=form_definition,
357                                    field_types=trans.model.FormDefinition.supported_field_types,
358                                    message=message,
359                                    status=status,
360                                    current_form_type=current_form[ 'type' ],
361                                    layout_grids=form_layout,
362                                    response_redirect=response_redirect )
363    @web.expose
364    @web.require_admin 
365    def delete_form_definition( self, trans, **kwd ):
366        id_list = util.listify( kwd['id'] )
367        delete_failed = []
368        for id in id_list:
369            try:
370                form_definition_current = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ).get( trans.security.decode_id(id) )
371            except:
372                return trans.response.send_redirect( web.url_for( controller='forms',
373                                                                  action='browse_form_definitions',
374                                                                  message='Invalid form',
375                                                                  status='error' ) )
376            form_definition_current.deleted = True
377            trans.sa_session.add( form_definition_current )
378            trans.sa_session.flush()
379        return trans.response.send_redirect( web.url_for( controller='forms',
380                                                          action='browse_form_definitions',
381                                                          message='%i forms have been deleted.' % len(id_list), 
382                                                          status='done') )
383    @web.expose
384    @web.require_admin
385    def undelete_form_definition( self, trans, **kwd ):
386        id_list = util.listify( kwd['id'] )
387        delete_failed = []
388        for id in id_list:
389            try:
390                form_definition_current = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ).get( trans.security.decode_id(id) )
391            except:
392                return trans.response.send_redirect( web.url_for( controller='forms',
393                                                                  action='browse_form_definitions',
394                                                                  message='Invalid form',
395                                                                  status='error' ) )
396            form_definition_current.deleted = False
397            trans.sa_session.add( form_definition_current )
398            trans.sa_session.flush()
399        return trans.response.send_redirect( web.url_for( controller='forms',
400                                                          action='browse_form_definitions',
401                                                          message='%i forms have been undeleted.' % len(id_list), 
402                                                          status='done') )
403    def build_form_definition_field_widgets( self, trans, layout_grids, field_index, field, form_type ):
404        '''
405        This method returns a list of widgets which describes a form definition field. This 
406        includes the field label, helptext, type, selectfield options, required/optional & layout
407        '''
408        # field label
409        label = TextField( 'field_label_'+str( field_index ), 40, field['label'] )
410        # help text
411        helptext = TextField( 'field_helptext_'+str( field_index ), 40, field['helptext'] )
412        # field type
413        field_type_select_field = SelectField( 'field_type_'+str( field_index ), 
414                                            refresh_on_change=True, 
415                                            refresh_on_change_values=[ SelectField.__name__ ] )
416        # fill up the field type selectfield options
417        field_type_options = []
418        # if the form is for defining samples, then use the sample field types
419        # which does not include TextArea & AddressField
420        if form_type == trans.model.FormDefinition.types.SAMPLE:
421            for supported_field_type in trans.model.Sample.supported_field_types:
422                if supported_field_type.__name__ == field[ 'type' ]:
423                    field_type_select_field.add_option( supported_field_type.__name__, 
424                                                     supported_field_type.__name__, 
425                                                     selected=True )
426                    if supported_field_type.__name__ == SelectField.__name__:
427                        # when field type is Selectfield, add option Textfields 
428                        field_type_options = self.__build_field_type_select_field_options( field, field_index )
429                else:
430                    field_type_select_field.add_option( supported_field_type.__name__, 
431                                                     supported_field_type.__name__ )
432        else:
433            for supported_field_type in trans.model.FormDefinition.supported_field_types:
434                if supported_field_type.__name__ == field[ 'type' ]:
435                    field_type_select_field.add_option( supported_field_type.__name__, 
436                                                     supported_field_type.__name__, 
437                                                     selected=True )
438                    if supported_field_type.__name__ == SelectField.__name__:
439                        # when field type is Selectfield, add option Textfields 
440                        field_type_options = self.__build_field_type_select_field_options( field, field_index )
441                else:
442                    field_type_select_field.add_option( supported_field_type.__name__, 
443                                                     supported_field_type.__name__ )
444        # required/optional radio button
445        required = SelectField( 'field_required_'+str(field_index), display='radio' )
446        if field[ 'required' ] == 'required':
447            required.add_option( 'Required', 'required', selected=True )
448            required.add_option( 'Optional', 'optional' )
449        else:
450            required.add_option( 'Required', 'required' )
451            required.add_option( 'Optional', 'optional', selected=True )
452        # layout grid option select_field
453        if layout_grids and form_type == trans.model.FormDefinition.types.SAMPLE:
454            layout_select_field = SelectField( 'field_layout_'+str( field_index ) )
455            for index, grid_name in enumerate( layout_grids ):
456                if str( field.get( 'layout', None ) ) == str( index ): #existing behavior: integer indexes are stored as strings.
457                    grid_selected = True
458                else:
459                    grid_selected = False
460                layout_select_field.add_option("%i. %s" %( index+1, grid_name ), index, selected=grid_selected )
461        # default value
462        default_value = TextField( 'field_default_'+str(field_index), 
463                                   40, 
464                                   field.get( 'default', '' ) )
465        # field name
466        name = TextField( 'field_name_' + str( field_index ), 40, field[ 'name' ] )
467        name_helptext = "The field name must be unique for each field and must contain only alphanumeric characters and underscore ."
468        if layout_grids and form_type == trans.model.FormDefinition.types.SAMPLE:
469            return [ ( 'Field label', label ),
470                     ( 'Help text', helptext ),
471                     ( 'Type', field_type_select_field, "Add options below", field_type_options ),
472                     ( 'Default value', default_value ),
473                     ( '', required ),
474                     ( 'Select the grid layout to place this field', layout_select_field ),
475                     ( 'Field name', name, name_helptext ) ]
476        return [ ( 'Field label', label ),
477                 ( 'Help text', helptext ),
478                 ( 'Type', field_type_select_field, "Add options below", field_type_options),
479                 ( 'Default value', default_value ),
480                 ( '', required),
481                 ( 'Field name', name, name_helptext ) ]
482    def __build_field_type_select_field_options( self, field, field_index ):
483        '''
484        Returns a list of TextFields, one for each select field option
485        '''
486        field_type_options = []
487        if field[ 'selectlist' ]:
488            for ctr, option in enumerate( field[ 'selectlist' ] ):
489                option_textfield = TextField( 'field_'+str( field_index )+'_option_'+str( ctr ), 40, option )
490                field_type_options.append( ( 'Option '+str( ctr+1 ), option_textfield ) )
491        return field_type_options
492    def __add_select_field_option( self, trans, current_form, **kwd ):
493        '''
494        This method adds a select_field option. The kwd dict searched for
495        the field index which needs to be removed
496        '''
497        message='' 
498        status='ok',
499        index = -1
500        for k, v in kwd.items():
501            if v == 'Add':
502                # extract the field index from the
503                # button name of format: 'addoption_<field>'
504                index = int(k.split('_')[1])
505                break
506        if index == -1:
507            # something wrong happened
508            message='Error in adding selectfield option', 
509            status='error',
510            return current_form, status, message
511        # add an empty option
512        current_form[ 'fields' ][ index ][ 'selectlist' ].append( '' )
513        return current_form, status, message
514    def __remove_select_field_option( self, trans, current_form, **kwd ):
515        '''
516        This method removes a select_field option. The kwd dict searched for
517        the field index and option index which needs to be removed
518        '''
519        message='' 
520        status='ok',
521        option = -1
522        for k, v in kwd.items():
523            if v == 'Remove':
524                # extract the field & option indices from the
525                # button name of format: 'removeoption_<field>_<option>'
526                index = int( k.split( '_' )[1] )
527                option = int( k.split( '_' )[2] )
528                break
529        if option == -1:
530            # something wrong happened
531            message='Error in removing selectfield option', 
532            status='error',
533            return current_form, status, message
534        # remove the option
535        del current_form[ 'fields' ][ index ][ 'selectlist' ][ option ]
536        return current_form, status, message
537    def __get_select_field_options( self, index, **kwd ):
538        '''
539        This method gets all the options entered by the user for field when
540        the fieldtype is SelectField 
541        '''
542        params = util.Params( kwd )
543        ctr=0
544        sb_options = []
545        while True:
546            if kwd.has_key( 'field_'+str(index)+'_option_'+str(ctr) ):
547                option = params.get( 'field_'+str(index)+'_option_'+str(ctr), None ) 
548                sb_options.append( util.restore_text( option ) )
549                ctr = ctr+1
550            else:
551                return sb_options
552    def __get_field( self, index, **kwd ):
553        '''
554        This method retrieves all the user-entered details of a field and
555        returns a dict.
556        '''
557        params = util.Params( kwd )
558        label = util.restore_text( params.get( 'field_label_%i' % index, '' ) )
559        name = util.restore_text( params.get( 'field_name_%i' % index, '' ) )
560        helptext = util.restore_text( params.get( 'field_helptext_%i' % index, '' ) )
561        required =  params.get( 'field_required_%i' % index, False )
562        field_type = util.restore_text( params.get( 'field_type_%i' % index, '' ) )
563        layout = params.get( 'field_layout_%i' % index, '0' )
564        default = util.restore_text( params.get( 'field_default_%i' % index, '' ) )
565        if not name.strip():
566            name = '%i_field_name' % index
567        if field_type == 'SelectField':
568            options = self.__get_select_field_options(index, **kwd)
569            return { 'name': name,
570                     'label': label, 
571                     'helptext': helptext, 
572                     'visible': True,
573                     'required': required,
574                     'type': field_type,
575                     'selectlist': options,
576                     'layout': layout,
577                     'default': default }
578        return { 'name': name,
579                 'label': label, 
580                 'helptext': helptext, 
581                 'visible': True,
582                 'required': required,
583                 'type': field_type,
584                 'layout': layout,
585                 'default': default }
586    def __import_fields( self, trans, csv_file, form_type ):
587        '''
588        "company","name of the company", "True", "required", "TextField",,
589        "due date","turnaround time", "True", "optional", "SelectField","24 hours, 1 week, 1 month"
590        '''
591        import csv
592        fields = []
593        layouts = set()
594        try:
595            reader = csv.reader(csv_file.file)
596            index = 1
597            for row in reader:
598                if len(row) < 7: # ignore bogus rows
599		    continue
600                options = row[5].split(',')
601                if len(row) >= 8:
602                    fields.append( { 'name': '%i_field_name' % index,
603                                     'label': row[0], 
604                                     'helptext': row[1], 
605                                     'visible': row[2],
606                                     'required': row[3],
607                                     'type': row[4],
608                                     'selectlist': options,
609                                     'layout':row[6],
610                                     'default': row[7] } )
611                    layouts.add(row[6])             
612                else:
613                    fields.append( { 'name': '%i_field_name' % index,
614                                     'label': row[0], 
615                                     'helptext': row[1], 
616                                     'visible': row[2],
617                                     'required': row[3],
618                                     'type': row[4],
619                                     'selectlist': options,
620                                     'default': row[6] } )
621                index = index + 1
622        except:
623            return trans.response.send_redirect( web.url_for( controller='forms',
624                                                              action='create_form',
625                                                              status='error',
626                                                              message='Error in importing <b>%s</b> file' % csv_file.file))
627        self.__imported_from_file = True
628        return fields, list(layouts)
629    def __validate_form( self, **kwd ):
630        '''
631        This method checks the following text inputs are filled out by the user
632        - the name of form
633        - form type
634        '''
635        params = util.Params( kwd )
636        # form name
637        if not util.restore_text( params.name ):
638            return None, 'Form name must be filled.'
639        # form type
640        if util.restore_text( params.form_type_select_field ) == 'none': 
641            return None, 'Form type must be selected.'
642        return True, ''
643    def __build_form_types_widget( self, trans, selected='none' ):
644        form_type_select_field = SelectField( 'form_type_select_field' )
645        if selected == 'none':
646            form_type_select_field.add_option( 'Select one', 'none', selected=True )
647        else:
648            form_type_select_field.add_option( 'Select one', 'none' )
649        fd_types = trans.app.model.FormDefinition.types.items()
650        fd_types.sort()
651        for ft in fd_types:
652            if selected == ft[1]:
653                form_type_select_field.add_option( ft[1], ft[1], selected=True )
654            else:
655                form_type_select_field.add_option( ft[1], ft[1] )
656        return form_type_select_field
657