The demonstration is based upon a simplified example of a bug tracker I have been developing. In this example, the domain class, Issue, has 4 fields,
- name
- description
- status [e.g. UNASSIGNED, ASSIGNED, CLOSED]
- outcome [e.g. FIXED, NOT FIXED, DUPLICATE]
It makes sense to display the outcome field only if an issue has been marked "CLOSED" as below. Changing the status to any other value will reset the form and the outcome field will be hidden.
Now to move onto the implementation details.
Step 1: Download & Import jQuery library
In this step you need to download jQuery and place it in the web-app/js folder.
Next you need to import it into the gsp page by placing the following statement between the <head> tags, e.g.
<g:javascript library="jquery-1.2.6.min"/>
Step 2: Create Basic Form Elements
Staying with the gsp page, we create a form and embed within it 2 key elements. The first of these is a drop-down list for the status field. The second element is a stub represented here as an empty table row. Depending on selections to the status field, the stub will either remain empty or be replaced by an extra form element, e.g. a drop-down list for the outcome field.
<tr>
<td valign="top" class="name">
<label for="status">Status:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:issue,field:'status','errors')}">
<g:select id="status" name="status" from="${issue.constraints.status.inList}"
value="${issue.status}" ></g:select>
</td>
</tr>
<tr class="prop" id="selectOutcome"></tr>
Step 3: Code up Ajax call
Next we need to bind the status drop-down list with javascript functions that will detect user selection and transmit its value to a grails controller via Ajax. The .change() and .ajax() functions provided by jQuery fit the bill. They will send the value selected from the status list to the controller and replace the empty stub with any html content sent back.
<g:javascript>
$(document).ready(function() {
$("#status").change(function() {
$.ajax({
url: "/myform/issue/selectOutcome",
data: "status=" + this.value,
cache: false,
success: function(html) {$("#selectOutcome").html(html);}
});
}
);
});
</g:javascript>
The first argument to the ajax function is the url to the grails action. This is of the form /web context/controller/action. The 'data' parameter is the value of the selection made by the user, and the success parameter will replace the empty stub with the response generated by the grails controller.
Step 4: Implement grails action code
/**
* Enable user to select outcome when issue is closed
*/
* Enable user to select outcome when issue is closed
*/
def selectOutcome = {
String status = params.status
if(status == "CLOSED")
{
render (template:"selectOutcome")
}
render ""
}
This action defined within an appropriate controller, simply checks to see if the selection made by the user for the status field is set to "CLOSED". If true, it will render the content placed within the template file defined below.
Step 5: create template
Create a template file which should contain the form element you want to display/hide in your target gsp page. Note that this file should be named with a leading underscore, e.g. _selectOutcome.gsp
<td valign="top" class="name">
<label for="outcome">Outcome:</label>
</td>
<td valign="top" class="value ${hasErrors(bean:issue,field:'outcome','errors')}">
<g:select id="selectOutcome" name="outcome"
from="${Issue.constraints.outcome.inList}" value=""></g:select>
</td>
This will render a label and a select element for the outcome field.
That's it !
You can download the code for this example [myform.zip] here.
Following the steps above should enable you to implement a similar form toggling feature for your application. Bear in mind though, that there is a potential problem if you will be using jQuery in conjunction with other javascript libraries. However this is a post for another day.
No comments:
Post a Comment