JSF Allowing To Delete Tasks

Allowing to delete tasks

  • Only the owner, creator, of a task can delete it
  • In order to store which task is selected for deletion and who can delete it, we need to keep track of that data with two boolean members. We could add those two boolean flags to the TaskImpl.java but then we would introduce class members to the value POJOs that are only used for JSF functionality. A better way of keeping track of those boolean flags is to create a Task wrapper class, which has a reference to the Task object, and add the boolean flags to that wrapper class.
  • Create tool/src/java/org/sakaiproject/tool/tasklist/jsf/TaskBeanWrapper.java
    • package org.sakaiproject.tool.tasklist.jsf;
      
      import org.sakaiproject.tool.tasklist.api.Task;
      
      
      public class TaskBeanWrapper {
      
      	private Task task;
      	private boolean isSelected;
      	private boolean canDelete;
      	
      	public TaskBeanWrapper(Task task) {
      		
      		this.task = task;
      	}
      	
      	public Task getTask() {
      		
      		return task;
      	}
      	
      	public void setTask(Task task) {
      		
      		this.task = task;
      	}
      	
      	public void setSelected(boolean selected) {
      		
      		this.isSelected = selected;
      	}
      	
      	public boolean isSelected() {
      		
      		return isSelected;
      	}
      	
      	public void setDelete(boolean canDelete) {
      		
      		this.canDelete = canDelete;
      	}
      	
      	public boolean getDelete() {
      		
      		return canDelete;
      	}
      }
      
  • Now we need to modify the tool/src/java/org/sakaiproject/tool/tasklist/jsf/TaskListBean.java
    • We nee to modify the getAllTasks() method so that it returns a collection of TaskBeanWrapper objects instead of TaskImpl objects.
    • At the same time when we build the wrappedTasks collection, we set the canDelete flag appropriately.
      • public DataModel getAllTasks() {
        		log.debug("getAllTasks");
        		
        		Collection tasks = taskListService.getAllTasks(taskListService.getSiteId());
        		Collection wrappedTasks = new LinkedList();
        		
        		TaskBeanWrapper taskBeanWrapper;
        		Iterator iter = tasks.iterator();
        		
        		while(iter.hasNext()) {
        			
        			taskBeanWrapper = new TaskBeanWrapper((Task) iter.next());
        			// Mark the task if the current user can delete the task
        			if(taskBeanWrapper.getTask().getOwner().equals(taskListService.getCurrentUserId())) {
        				taskBeanWrapper.setDelete(true);
        			} else {
        				taskBeanWrapper.setDelete(false);
        			}
        			wrappedTasks.add(taskBeanWrapper);
        		}
        
        		tasksModel = new ListDataModel();
        		tasksModel.setWrappedData(wrappedTasks);
        		
        		return tasksModel;
        	}
        
  • We also need to create an action class, which is called upon clicking on the delete button.
    • public String processActionDelete() {
      		
      		log.debug("processActionDelete");
      		
      		Collection tasks = (Collection) tasksModel.getWrappedData();
      		
      		TaskBeanWrapper task = null;
      		Iterator iter = tasks.iterator();		
      		while(iter.hasNext()) {
      			task = (TaskBeanWrapper) iter.next();
      			if(task.isSelected()) {
      				taskListService.removeTask(task.getTask());
      			}
      		}
      		
      		return "deleteTasks";
      	}
      
  • Now complete TaskList.jsp
    • Since only the creator of a task can delete it, we only render the check box if the current user is the owner
    • We also add the delete button
      • <%@ taglib uri="http://sakaiproject.org/jsf/sakai" prefix="sakai" %>
        <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
        <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> 
        <f:loadBundle basename="org.sakaiproject.tool.tasklist.bundle.Messages" var="msgs"/>
         
        <f:view>
        	<sakai:view_container title="Task List Tool">
        		<sakai:view_content>
        			<h:form id="tasks">
        			
        			 	<sakai:view_title value="#{msgs.task_list_title}"/>
        			 	
        			 	<h:outputText value="Hello, #{TaskListBean.currentUserDisplayName}"/>
        			 	
        			 	<sakai:panel_edit>
        			 		<h:inputText value="#{TaskListBean.taskText}" size="60"/>
        	 				<h:commandButton value="#{msgs.task_list_add}" action="#{TaskListBean.processActionAdd}" />
        			 	</sakai:panel_edit>
        			 	
        			 	<h:dataTable
        			 		id="tasklist"
        			 		value="#{TaskListBean.allTasks}"
        			 		var="entry"
        			 		styleClass="listHier">
        
        					<h:column>
        						<f:facet name="header">
        							<h:outputText value=""/>
        						</f:facet>
        						<h:selectBooleanCheckbox id="taskSelect" value="#{entry.selected}" rendered="#{entry.delete}"/>
        						<h:outputText value="" rendered="#{not entry.delete}"/>
        					</h:column>
        
        					<h:column>
        						<f:facet name="header">
        							<h:outputText value="#{msgs.task_list_owner}"/>
        						</f:facet>
        						<h:outputText value="#{entry.task.owner}"/>
        					</h:column>
        					
        					<h:column>
        						<f:facet name="header">
        							<h:outputText value="#{msgs.task_list_text}"/>
        						</f:facet>
        						<h:outputText value="#{entry.task.task}"/>
        					</h:column>
        
        					<h:column>
        						<f:facet name="header">
        							<h:outputText value="#{msgs.task_list_date}"/>
        						</f:facet>
        						<h:outputText value="#{entry.task.creationDate}">
        							<f:convertDateTime type="both" dateStyle="medium" timeStyle="short" />
        						</h:outputText>
        					</h:column>
        					
        				</h:dataTable>
        				
        				<sakai:button_bar>
        					<sakai:button_bar_item id="deleteTask" action="#{TaskListBean.processActionDelete}" value="#{msgs.task_list_delete}"/>  
                        </sakai:button_bar>
                        
        			 </h:form>
          		</sakai:view_content>	
        	</sakai:view_container>
        </f:view> 
        
  • We also add the navigation rule for the delete action in the faces-config.xml file
    • 	<navigation-case>
      		<from-outcome>deleteTasks</from-outcome>
      		<to-view-id>/tasklist/TaskList.jsp</to-view-id>
      	</navigation-case>
      
      *Screen Capture
    • !TaskListDeleteTask!