Changeset 507 for trunk


Ignore:
Timestamp:
Jun 1, 2010, 2:45:21 PM (13 years ago)
Author:
roberth
Message:

Implemented file upload template fields

Location:
trunk
Files:
9 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateEntity.groovy

    r506 r507  
    2222        Map templateDateFields = [:]
    2323        Map templateRelTimeFields = [:] // Contains relative times in seconds
     24        Map templateFileFields = [:] // Contains filenames
    2425        Map templateTermFields = [:]
    2526
     
    3435                templateTermFields: Term,
    3536                templateRelTimeFields: long,
     37                templateFileFields: String,
    3638                systemFields: TemplateField
    3739        ]
     
    4244                templateTextFields type: 'text'
    4345        }
     46
     47        def fileService
    4448
    4549        /**
     
    238242                                }
    239243                        }
     244                        return (!error)
     245                })
     246                templateFileFields(validator: { fields, obj, errors ->
     247                        // note that we only use 'fields' and 'errors', 'obj' is
     248                        // merely here because it's the way the closure is called
     249                        // by the validator...
     250
     251                        // define a boolean
     252                        def error = false
     253
     254                        // iterate through fields
     255                        fields.each { key, value ->
     256                                // check if the value is of proper type
     257                                if (value && value.class != String) {
     258                                        // it's of some other type
     259                                        try {
     260                                                // try to cast it to the proper type
     261                                                fields[key] = (value as String)
     262
     263                                                // Find the file on the system
     264                                                // if it does not exist, the filename can
     265                                                // not be entered
     266                                               
     267                                        } catch (Exception e) {
     268                                                // could not typecast properly, value is of improper type
     269                                                // add error message
     270                                                error = true
     271                                                errors.rejectValue(
     272                                                        'templateFileFields',
     273                                                        'templateEntity.typeMismatch.string',
     274                                                        [key, value.class] as Object[],
     275                                                        'Property {0} must be of type String and is currently of type {1}'
     276                                                )
     277                                        }
     278                                }
     279                        }
     280
     281                        // got an error, or not?
    240282                        return (!error)
    241283                })
     
    263305                        case TemplateFieldType.RELTIME:
    264306                                return templateRelTimeFields
     307                        case TemplateFieldType.FILE:
     308                                return templateFileFields
    265309                        case TemplateFieldType.FLOAT:
    266310                                return templateFloatFields
     
    383427                }
    384428
     429                // Sometimes the fileService is not created yet
     430                if( !fileService ) {
     431                    fileService = new FileService();
     432                }
     433
     434                // Magic setter for files: handle values for file fields
     435                //
     436                // If NULL is given, the field value is emptied and the old file is removed
     437                // If an empty string is given, the field value is kept as was
     438                // If a file is given, it is moved to the right directory. Old files are deleted. If
     439                //   the file does not exist, the field is kept
     440                // If a string is given, it is supposed to be a file in the upload directory. If
     441                //   it is different from the old one, the old one is deleted. If the file does not
     442                //   exist, the old one is kept.
     443                if (field.type == TemplateFieldType.FILE) {
     444                    def currentFile = getFieldValue( field.name );
     445
     446                    if( value == null ) {
     447                        // If NULL is given, the field value is emptied and the old file is removed
     448                        value = "";
     449                        if( currentFile )
     450                        {
     451                            fileService.delete( currentFile )
     452                        }                       
     453                    } else if( value.class == File ) {
     454                        // a file was given. Attempt to move it to the upload directory, and
     455                        // afterwards, store the filename. If the file doesn't exist
     456                        // or can't be moved, "" is returned
     457                        value = fileService.moveFileToUploadDir( value );
     458
     459                        if( value ) {
     460                            if( currentFile )
     461                            {
     462                                fileService.delete( currentFile )
     463                            }
     464                        } else {
     465                            value = currentFile;
     466                        }
     467                    } else if ( value == "" ) {
     468                        value = currentFile;
     469                    } else {
     470                        if( value != currentFile ) {
     471                            if( fileService.fileExists( value ) ) {
     472                                // When a FILE field is filled, and a new file is set
     473                                // the existing file should be deleted
     474                                if( currentFile )
     475                                {
     476                                    fileService.delete( currentFile )
     477                                }
     478                            } else {
     479                                // If the file does not exist, the field is kept
     480                                value = currentFile;
     481                            }
     482                        }
     483                    }
     484                }
     485
     486
    385487                // Magic setter for ontology terms: handle string values
    386488                if (field.type == TemplateFieldType.ONTOLOGYTERM && value && value.class == String) {
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateFieldType.groovy

    r500 r507  
    1717        ONTOLOGYTERM('Ontology Reference'),
    1818        DATE('Date'),
    19         RELTIME('Relative time') // relative date, e.g. days since start of study
     19        RELTIME('Relative time'), // relative date, e.g. days since start of study
     20        FILE('File')
    2021
    2122        String name
     
    2627
    2728        static list() {
    28                 [STRING, TEXT, INTEGER, FLOAT, DOUBLE, STRINGLIST, ONTOLOGYTERM, DATE, RELTIME]
     29                [STRING, TEXT, INTEGER, FLOAT, DOUBLE, STRINGLIST, ONTOLOGYTERM, DATE, RELTIME, FILE]
    2930        }
    3031
     
    4748                        case RELTIME:
    4849                                return null
     50                        case FILE:
     51                                return ""
    4952                        default:
    5053                                throw new NoSuchFieldException("Field type ${fieldType} not recognized")
  • trunk/grails-app/taglib/dbnp/studycapturing/WizardTagLib.groovy

    r502 r507  
    510510                )
    511511        }
     512
     513        /**
     514         * File form element
     515         * @param Map attributes
     516         * @param Closure help content
     517         */
     518        def fileFieldElement = { attrs, body ->
     519                // render term element
     520                baseElement.call(
     521                        'fileField',
     522                        attrs,
     523                        body
     524                )
     525        }
     526
     527        def fileField = { attrs ->
     528            /*
     529            out << '<input type="file" name="' + attrs.name + '"/>'
     530            if( attrs.value ) {
     531                out << '<a href="' + resource(dir: '') + '/file/get/' + attrs.value + '" class="isExample">Now contains: ' + attrs.value + '</a>'
     532            }
     533            */
     534
     535            out << '<div id="upload_button_' + attrs.name + '" class="upload_button">Upload</div>';
     536            out << '<input type="hidden" name="' + attrs.name + '" id="' + attrs.name + '" value="' + attrs.value + '">';
     537            out << '<div id="' + attrs.name + 'Example" class="upload_info"></div>';
     538            out << '<script type="text/javascript">';
     539            out << '  $(document).ready( function() { ';
     540            out << '    var filename = "' + attrs.value + '";';
     541            out << '    fileUploadField( "' + attrs.name + '" );';
     542            out << '    if( filename != "" ) {';
     543            out << '      $("#' + attrs.name + 'Example").html("Current file: " + createFileHTML( filename ) )';
     544            out << '    }';
     545            out << '  } );';
     546            out << "</script>\n";
     547        }
    512548
    513549        /**
     
    925961                                                ){helpText}
    926962                                                break
     963                                        case ['FILE']:
     964                                                inputElement = (renderType == 'element') ? 'fileFieldElement' : 'fileField'
     965                                                out << "$inputElement"(
     966                                                        description: ucName,
     967                                                        name: prependName + it.escapedName(),
     968                                                        value: fieldValue ? fieldValue : "",
     969                                                        addExampleElement: true
     970                                                ){helpText}
     971                                                break
    927972                                        default:
    928973                                                // unsupported field type
  • trunk/grails-app/views/wizard/common/_wizard.gsp

    r432 r507  
    1717<div id="wizard" class="wizard">
    1818        <h1>Study wizard</h1>
    19         <g:form action="pages" name="wizardForm" id="wizardForm">
     19        <g:form action="pages" name="wizardForm" id="wizardForm" enctype="multipart/form-data">
    2020        <g:hiddenField name="do" value="" />
    2121                <div id="wizardPage">
  • trunk/grails-app/views/wizard/index.gsp

    r428 r507  
    2626        <script type="text/javascript" src="${resource(dir: 'js', file: 'timepicker-0.2.1.min.js')}"></script>
    2727        <script type="text/javascript" src="${resource(dir: 'js', file: 'wizard.min.js')}"></script>
     28        <script type="text/javascript" src="${resource(dir: 'js', file: 'ajaxupload.3.6.js')}"></script>
    2829</g:if><g:else>
    2930        <link rel="stylesheet" href="${resource(dir: 'css', file: 'wizard.css')}"/>
     
    3536        <script type="text/javascript" src="${resource(dir: 'js', file: 'timepicker-0.2.1.js')}"></script>
    3637        <script type="text/javascript" src="${resource(dir: 'js', file: 'wizard.js')}"></script>
     38        <script type="text/javascript" src="${resource(dir: 'js', file: 'ajaxupload.3.6.js')}"></script>
    3739</g:else>
    3840</head>
  • trunk/grails-app/views/wizard/pages/_demo.gsp

    r359 r507  
    1616%>
    1717
     18<g:if test="${demoElement}">
     19    <wizard:templateElements entity="${demoElement}" />
     20</g:if>
    1821<span class="info">
    1922        <span class="title">Ontology chooser</span>
  • trunk/test/unit/dbnp/studycapturing/TemplateFieldTests.groovy

    r497 r507  
    2020                        name: 'testRelTime',
    2121                        type: TemplateFieldType.RELTIME
     22                    ),
     23                    new TemplateField(
     24                        name: 'testFile',
     25                        type: TemplateFieldType.FILE
    2226                    )
    2327                ]
  • trunk/web-app/css/wizard.css

    r501 r507  
    336336    border: 1px solid red;
    337337}
     338
     339.wizard .upload_button {
     340    display: inline; border: 1px solid #006dba; padding: 4px 8px; cursor: pointer; line-height: 26px;
     341}
     342
     343.wizard .upload_info {
     344    display: inline; color: #006dba;
     345    margin-left: 5px;
     346}
     347.wizard .upload_info .error {
     348    color: red;
     349}
     350}
  • trunk/web-app/js/wizard.js

    r502 r507  
    308308    });
    309309}
     310
     311// Create a file upload field
     312function fileUploadField(field_id) {
     313        /* example 2 */
     314        new AjaxUpload('#upload_button_' + field_id, {
     315                //action: 'upload.php',
     316                action: baseUrl + '/file/upload', // I disabled uploads in this example for security reaaons
     317                data : {},
     318                name : field_id,
     319                autoSubmit: true,
     320                onChange : function(file, ext){
     321                    oldFile = $('#' + field_id).val();
     322                    if( oldFile != '' ) {
     323                        if( !confirm( 'The old file is deleted when uploading a new file. Do you want to continue?') ) {
     324                            return false;
     325                        }
     326                    }
     327
     328                    this.setData({
     329                            'field':   field_id,
     330                            'oldFile': oldFile
     331                    });
     332
     333                    // Give feedback to the user
     334                    $('#' + field_id + 'Example').html('Uploading ' + createFileHTML( file ));
     335
     336
     337                },
     338                onComplete : function(file, response){
     339                    if( response == "" ) {
     340                        $('#' + field_id).val( '' );
     341                        $('#' + field_id + 'Example').html('<span class="error">Error uploading ' + createFileHTML( file ) + '</span>' );
     342                    } else {
     343                        $('#' + field_id).val( response );
     344                        $('#' + field_id + 'Example').html('Uploaded ' + createFileHTML( file ) );
     345                    }
     346                }
     347        });
     348}
     349
     350function createFileHTML( filename ) {
     351    return '<a target="_blank" href="' + baseUrl + '/file/get/' + filename + '">' + filename + '</a>';
     352}
Note: See TracChangeset for help on using the changeset viewer.