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

https://bitbucket.org/cistrome/cistrome-harvard/ · Python · 657 lines · 554 code · 6 blank · 97 comment · 84 complexity · c874073bb08276dbdf4fb8a4f0f37280 MD5 · raw file

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