Changeset 833 for trunk


Ignore:
Timestamp:
03/03/11 12:24:01 (8 years ago)
Author:
gav
Message:

AJAX Work Done and PM Entry, second draft.

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/EntryDetailedController.groovy

    r826 r833  
    3131        if(entryInstance) { 
    3232            if(entryInstance.enteredBy.loginName == authService.currentUser.loginName) { 
    33                 def taskID = entryInstance.task.id 
     33                def taskId = entryInstance.task.id 
    3434                entryInstance.delete(flush:true) 
    3535                flash.message = "Entry ${params.id} deleted" 
    36                 redirect(controller: 'taskDetailed', action: 'show', id: taskID) 
     36                redirect(controller: 'taskDetailed', action: 'show', id: taskId) 
    3737            } 
    3838            else { 
     
    9494    def ajaxCreate = { 
    9595        if(!params.taskId || !params.entryTypeId) { 
    96             flash.message = g.message(code:"entry.create.no.params") 
    97             redirect(controller:"taskDetailed", action:"search") 
     96            response.status = 403 
     97            params.errorMessage = g.message(code: "entry.create.no.params.ajax") 
     98            render(template: "/shared/messages") 
    9899            return 
    99100        } 
     
    102103 
    103104        if(!taskInstance) { 
    104             flash.message = g.message(code:"task.notFound") 
    105             redirect(controller:"taskDetailed", action:"search") 
     105            response.status = 403 
     106            params.errorMessage = g.message(code:"default.not.found", args:['Task',params.taskId]) 
     107            render(template: "/shared/messages") 
    106108            return 
    107109        } 
     
    109111        // Check for Complete task. 
    110112        if(taskInstance.taskStatus.id == 3) { 
    111             flash.errorMessage = g.message(code:"task.operationNotPermittedOnCompleteTask") 
    112             redirect(controller:"taskDetailed", action:"show", id: taskInstance.id) 
     113            response.status = 403 
     114            params.errorMessage = g.message(code:"task.operationNotPermittedOnCompleteTask") 
     115            render(template: "/shared/messages") 
    113116            return 
    114117        } 
    115118 
     119        // Success. 
    116120        def entryInstance = new Entry() 
    117121        entryInstance.task = taskInstance 
     
    119123        render(template: "create", model: ['entryInstance': entryInstance]) 
    120124    } 
     125 
     126    def ajaxSave = { 
     127        def result = taskService.saveEntry(params) 
     128 
     129        // Success. 
     130        if(!result.error) { 
     131            def entryList = Entry.withCriteria { 
     132                                                                eq("entryType", result.entryInstance.entryType) 
     133                                                                task { 
     134                                                                    idEq(result.taskId) 
     135                                                                } 
     136                                                        } 
     137            render(template: "list", model: ['entryList': entryList]) 
     138            return 
     139        } 
     140 
     141        if(result.error.code != "default.create.failure") { 
     142            response.status = 403 
     143            params.errorMessage = g.message(code: result.error.code) 
     144            render(template: "/shared/messages") 
     145            return 
     146        } 
     147 
     148        response.status = 403 
     149        render(template: "create", model: ['entryInstance': result.entryInstance]) 
     150    } // ajaxSave 
    121151 
    122152    def create = { 
  • trunk/grails-app/controllers/TaskDetailedController.groovy

    r809 r833  
    424424                                                        } 
    425425 
     426            def entryPMList = Entry.withCriteria { 
     427                                                                eq("entryType", EntryType.get(6)) 
     428                                                                eq("task", taskInstance) 
     429                                                        } 
     430 
    426431            def subTaskInstanceList = Task.findAllByParentTaskAndTrash(taskInstance, false, params) 
    427432            def subTaskInstanceTotal = Task.countByParentTaskAndTrash(taskInstance, false) 
     
    450455                            entryCauseList: entryCauseList, 
    451456                            entryWorkDoneList: entryWorkDoneList, 
     457                            entryPMList: entryPMList, 
    452458                            taskProcedureRevision: taskProcedureRevision, 
    453459                            taskProcedureExits: taskProcedureExits, 
  • trunk/grails-app/i18n/messages.properties

    r830 r833  
    176176 
    177177entry.create.no.params=Please select a task, then add an entry. 
     178entry.create.no.params.ajax=Incorrect params supplied. 
    178179 
    179180taskRecurringSchedule.notFound=Could not complete operation, recurring schedule not found. 
  • trunk/grails-app/views/entryDetailed/_create.gsp

    r830 r833  
    11 
    2     <g:form action="save" method="post" > 
     2 
     3    <g:render template="/shared/messages" /> 
     4    <g:hasErrors bean="${entryInstance}"> 
     5        <div class="errors"> 
     6            <g:renderErrors bean="${entryInstance}" as="list" /> 
     7        </div> 
     8    </g:hasErrors> 
     9    <div class="pane_close"> 
     10        <img  src="${resource(dir:'images/skin',file:'cross.png')}" alt="Close" title="Close"/> 
     11    </div> 
     12    <g:form action="ajaxSave" method="post" name="createEntryForm"> 
    313        <g:hiddenField name="task.id" value="${entryInstance.task.id}" /> 
    414        <g:hiddenField name="entryType.id" value="${entryInstance.entryType.id}" /> 
  • trunk/grails-app/views/taskDetailed/_showProcedureTab.gsp

    r831 r833  
    2525        <br /> 
    2626 
    27         <div id="pmEntryContainer"></div> 
     27        <div id="pmEntryContainer"> 
     28            <g:if test="${entryPMList.isEmpty()}"> 
     29                <h1>No PM Entries</h1> 
     30                <br /> 
     31            </g:if> 
     32            <g:else> 
     33                <g:render template="/entryDetailed/list" 
     34                                    model="['entryList':entryPMList]" /> 
     35            </g:else> 
     36        </div> 
     37 
     38        <br /> 
     39 
     40        <div id="createPMEntryContainer" style="display:none;"></div> 
    2841 
    2942        <div style="text-align:right;" id="pmEntryButton"> 
     
    3245                            class="add" 
    3346                            value="Add PM Entry" 
    34                             onclick="loadEntryForm(jQuery('#pmEntryContainer'), 
    35                                                                     jQuery('#pmEntryButton'), 
    36                                                                     {taskId: ${taskInstance?.id}, entryTypeId: 6})" /> 
     47                            onclick="getCreateEntryForm(jQuery('#pmEntryContainer'), 
     48                                                                                jQuery('#createPMEntryContainer'), 
     49                                                                                jQuery('#pmEntryButton'), 
     50                                                                                {taskId: ${taskInstance?.id}, entryTypeId: 6})" /> 
    3751            </span> 
    3852        </div> 
     53 
    3954    </g:else> 
  • trunk/grails-app/views/taskDetailed/_showTaskTab.gsp

    r823 r833  
    230230                <tbody> 
    231231                    <g:each in="${entryFaultList}" status="i" var="entry"> 
    232                             <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}"/> 
     232                            <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}"> 
    233233 
    234234                                <td style="width:65%" onclick='window.location = "${request.getContextPath()}/entryDetailed/edit/${entry.id}"'> 
     
    300300                <tbody> 
    301301                    <g:each in="${entryCauseList}" status="i" var="entry"> 
    302                             <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}"/> 
     302                            <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}"> 
    303303 
    304304                                <td style="width:65%" onclick='window.location = "${request.getContextPath()}/entryDetailed/edit/${entry.id}"'> 
     
    339339    <br /> 
    340340 
    341     <g:if test="${entryWorkDoneList.isEmpty()}"> 
    342         <h1>No Work Done</h1> 
    343         <br /> 
    344     </g:if> 
    345     <g:else> 
    346         <div class="list"> 
    347             <h1>Work Done</h1> 
    348             <table> 
    349                 <thead> 
    350                     <tr> 
    351                         <th>Comment</th> 
    352                         <th>Date Done</th> 
    353                         <th>Duration</th> 
    354                         <th>Entered By</th> 
    355                         <th></th> 
    356                     </tr> 
    357                 </thead> 
    358                 <tbody> 
    359                     <g:each in="${entryWorkDoneList}" status="i" var="entry"> 
    360                             <tr class="${(i % 2) == 0 ? 'clickableOdd' : 'clickableEven'}"/> 
    361  
    362                                 <td width="65%" onclick='window.location = "${request.getContextPath()}/entryDetailed/edit/${entry.id}"'> 
    363                                     ${entry.comment.encodeAsHTML()} 
    364                                 </td> 
    365  
    366                                 <td onclick='window.location = "${request.getContextPath()}/entryDetailed/edit/${entry.id}"'> 
    367                                     <g:formatDate date="${entry.dateDone}" format="EEE, dd-MMM-yyyy"/> 
    368                                 </td> 
    369  
    370                                 <td onclick='window.location = "${request.getContextPath()}/entryDetailed/edit/${entry.id}"'> 
    371                                     ${entry.durationHour}:${entry.durationMinute} 
    372                                 </td> 
    373  
    374                                 <td onclick='window.location = "${request.getContextPath()}/entryDetailed/edit/${entry.id}"'> 
    375                                     ${entry.enteredBy.encodeAsHTML()} 
    376                                 </td> 
    377  
    378                                 <td class="notClickable"> 
    379                                     <g:link controller="entryDetailed" action="edit" id="${entry.id}"> 
    380                                         <img  src="${resource(dir:'images/skin',file:'database_edit.png')}" alt="Edit" title="Edit" /> 
    381                                     </g:link> 
    382                                 </td> 
    383  
    384                             </tr> 
    385                     </g:each> 
    386                 </tbody> 
    387             </table> 
    388         </div> 
    389     </g:else> 
    390  
    391     <div class="buttons"> 
    392         <g:form controller="entryDetailed"> 
    393             <g:hiddenField name="taskInstance.id" value="${taskInstance?.id}" /> 
    394             <g:hiddenField name="entryType.id" value="3" /> 
    395             <span class="button"> 
    396                 <g:actionSubmit value="Add Work Done" action="create"  class="add"/> 
    397             </span> 
    398         </g:form> 
    399     </div> 
     341    <div id="workDoneContainer"> 
     342        <g:if test="${entryWorkDoneList.isEmpty()}"> 
     343            <h1>No Work Done</h1> 
     344            <br /> 
     345        </g:if> 
     346        <g:else> 
     347            <g:render template="/entryDetailed/list" 
     348                                model="['entryList':entryWorkDoneList]" /> 
     349        </g:else> 
     350    </div> 
     351 
     352    <br /> 
     353 
     354    <div id="createWorkDoneContainer" style="display:none;"></div> 
     355 
     356    <div style="text-align:right;" id="workDoneButton"> 
     357        <span class="buttons"> 
     358            <input type="button" 
     359                        class="add" 
     360                        value="Add Work Done" 
     361                        onclick="getCreateEntryForm(jQuery('#workDoneContainer'), 
     362                                                                            jQuery('#createWorkDoneContainer'), 
     363                                                                            jQuery('#workDoneButton'), 
     364                                                                            {taskId: ${taskInstance?.id}, entryTypeId: 3})" /> 
     365        </span> 
     366    </div> 
  • trunk/web-app/css/main.css

    r825 r833  
    751751    right: 5px; 
    752752    padding: 5px; 
     753    cursor: pointer; 
    753754} 
    754755 
  • trunk/web-app/js/taskShow.js

    r831 r833  
    11 
    2 // Load an Entry from via AJAX. 
    3 // @container Container object to load response into. 
     2// Load data into createContainer and register events. 
     3function loadCreateContainer(data, createContainer, listContainer, button) { 
     4        // Load the response data and show container. 
     5        createContainer.html(data).slideDown(800); 
     6        // Scroll the window. 
     7        jQuery('html,body').animate({scrollTop: createContainer.offset().top}, 900, function() { 
     8            createContainer.find(':input[name="comment"]').focus(); 
     9        }); 
     10        // Hijack form submit to use our function. 
     11        var eventData = {listContainer:listContainer,createContainer:createContainer, button:button}; 
     12        createContainer.find('form:first').submit(eventData, submitCreateEntryForm); 
     13        // Register the close img click handler. 
     14        createContainer.find('.pane_close img').click(function(){ 
     15            createContainer.slideUp(600); 
     16            button.show(600); 
     17        }); 
     18} 
     19 
     20// Submit a create Entry form via AJAX. 
     21function submitCreateEntryForm(event) { 
     22 
     23    var actionUrl = getContextPath()+"/entryDetailed/ajaxSave/"; 
     24 
     25    event.preventDefault(); 
     26    var listContainer = event.data.listContainer; 
     27    var createContainer = event.data.createContainer; 
     28    var button = event.data.button; 
     29    var form = createContainer.find('form:first'); 
     30 
     31    // On success reload listContainer. 
     32    function success(data, textStatus, jqXHR){ 
     33        createContainer.hide(); 
     34        listContainer.html(data); 
     35        button.show(600); 
     36    } 
     37 
     38    // On create failure controller sets 403 and returns the form template. 
     39    function error(jqXHR, textStatus, errorThrown){ 
     40        if(jqXHR.status == 403 && jqXHR.responseText){ 
     41            loadCreateContainer(jqXHR.responseText, createContainer, listContainer, button); 
     42        } 
     43        else { 
     44            createContainer.html(errorIndication().show()).slideDown(600); 
     45        } 
     46        button.show(600); 
     47    } 
     48 
     49    // Start. 
     50    createContainer.html(loadingIndication().show()).slideDown(600); 
     51 
     52    jQuery.ajax({ 
     53        url: actionUrl, 
     54        data: form.serializeArray(), 
     55        success: success, 
     56        error: error 
     57    }); 
     58} 
     59 
     60// Get a create Entry form via AJAX. 
     61// @listContainer Container object to reload list into. 
     62// @createContainer Container object to load response into. 
    463// @button Button object used to trigger this function. 
    5 // @args Params map to pass to actionUrl. 
    6 function loadEntryForm(container, button, params) { 
     64// @params Params map to pass to actionUrl. 
     65function getCreateEntryForm(listContainer, createContainer, button, params) { 
    766 
    867    var actionUrl = getContextPath()+"/entryDetailed/ajaxCreate/"; 
    968 
     69    // On success load createContainer. 
    1070    function success(data, textStatus, jqXHR){ 
    11         container.html(data); 
    12         jQuery('html,body').animate({scrollTop: container.offset().top}, 800, function() { 
    13             container.css("border", "1px solid #006DBA"); 
    14             container.find(':input[name="comment"]').focus(); 
    15         }); 
     71        loadCreateContainer(data, createContainer, listContainer, button); 
    1672    } 
    1773 
     74    // On error show controller responseText or show default error. 
    1875    function error(jqXHR, textStatus, errorThrown){ 
    19         container.html(errorIndication().slideDown(600)); 
     76        if(jqXHR.status == 403 && jqXHR.responseText){ 
     77            loadCreateContainer(jqXHR.responseText, createContainer, listContainer, button); 
     78        } 
     79        else { 
     80            createContainer.html(errorIndication().show()).slideDown(600); 
     81        } 
    2082        button.show(600); 
    2183    } 
     
    2385    // Start. 
    2486    button.hide(600); 
    25     container.html(loadingIndication().slideDown(600)); 
     87    createContainer.html(loadingIndication().show()).slideDown(600); 
    2688 
    2789    jQuery.ajax({ 
     
    3294    }); 
    3395} 
     96 
Note: See TracChangeset for help on using the changeset viewer.