View Javadoc

1   package org.kuali.student.common.ui.client.configurable.mvc.sections;
2   
3   import java.util.ArrayList;
4   import java.util.HashMap;
5   import java.util.Iterator;
6   import java.util.List;
7   
8   import org.kuali.student.common.ui.client.application.Application;
9   import org.kuali.student.common.ui.client.configurable.mvc.LayoutController;
10  import org.kuali.student.common.ui.client.event.SectionUpdateEvent;
11  import org.kuali.student.common.ui.client.widgets.dialog.ConfirmationDialog;
12  import org.kuali.student.common.ui.client.widgets.field.layout.layouts.VerticalFieldLayout;
13  import org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract;
14  import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
15  import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
16  
17  import com.google.gwt.event.dom.client.ClickEvent;
18  import com.google.gwt.event.dom.client.ClickHandler;
19  
20  /**
21   * A section that contains sections that can be swapped in based on user selection on a KSSelectItemWidgetAbstract
22   * 
23   * 
24   * @author Kuali Student Team
25   *
26   */
27  public class SwapSection extends BaseSection implements HasSectionDeletion{
28  	
29  	private HashMap<String, Section> swapSectionMap = new HashMap<String, Section>();
30  	private KSSelectItemWidgetAbstract selectableWidget;
31  	private List<Section> deleted = new ArrayList<Section>();
32  	private ConfirmationDialog dialog; 
33  	private boolean showConfirmation = true;
34  	private List<String> lastSelection = new ArrayList<String>();
35  	private List<String> deletionParentKeys;
36  	
37  	/**
38  	 * Constructor for SwapSection, note that the SelectableWidget passed in is not added to the
39  	 * UI but is instead used as reference to show different sections.  The widget must still be added
40  	 * to a layout as a field or a widget to show in the UI.  A default confirmation dialog will be used.
41  	 * @param selectableWidget
42  	 */
43  	public SwapSection(KSSelectItemWidgetAbstract selectableWidget){
44  		this.init(selectableWidget);
45  	}
46  	
47  	public SwapSection(KSSelectItemWidgetAbstract selectableWidget, ConfirmationDialog dialog){
48          this.dialog = dialog;
49  		this.init(selectableWidget);
50  	}
51  	
52  	private void init(KSSelectItemWidgetAbstract selectableWidget){
53  		this.selectableWidget = selectableWidget;
54  		
55  		if(dialog == null){
56  			dialog = 
57  				new ConfirmationDialog(Application.getApplicationContext().getMessage("fieldDeletionTitle"),  
58  						Application.getApplicationContext().getMessage("fieldDeletionConfirmMessage"));
59  		}
60  		dialog.getConfirmButton().addClickHandler(new ClickHandler(){
61  
62  			@Override
63  			public void onClick(ClickEvent event) {
64  				handleUserSelection();
65  				dialog.hide();
66  			}
67  		});
68  		
69  		selectableWidget.addSelectionChangeHandler(new SelectionChangeHandler(){
70  
71  			@Override
72  			public void onSelectionChange(SelectionChangeEvent event) {
73  				if(event.isUserInitiated() && showConfirmation){
74  					if(SwapSection.this.selectableWidget.getSelectedItems().size() < lastSelection.size()){
75  						dialog.show();
76  					}
77  					else if(!SwapSection.this.selectableWidget.getSelectedItems().containsAll(lastSelection)){
78  //						List<String> selected  = SwapSection.this.selectableWidget.getSelectedItems();
79  //						for(int i = 0; i < selected.size(); i++){
80  //							String key = selected.get(i);
81  //							Section section = swapSectionMap.get(key);
82  //							if(section!=null){
83  //								if(section.getLayout().isVisible()){
84  //									dialog.show();
85  //								}
86  //							}
87  //						}
88  						dialog.show();
89  					}
90  					else{
91  						handleUserSelection();
92  					}
93  				}
94  				else if(event.isUserInitiated()){
95  					handleUserSelection();
96  				}
97  				else{
98  					handleSelection();
99  				}
100 				lastSelection.clear();
101 				lastSelection.addAll(SwapSection.this.selectableWidget.getSelectedItems());
102 			}
103 		});
104 		layout = new VerticalFieldLayout();
105 		this.add(layout);
106 	}
107 	
108 	private void handleUserSelection(){
109 		List<String> selected  = SwapSection.this.selectableWidget.getSelectedItems();
110 		for(int i = 0; i < selected.size(); i++){
111 			String key = selected.get(i);
112 			showSwappableSection(key);
113 		}
114 		
115 		Iterator<String> it = swapSectionMap.keySet().iterator();
116 		while(it.hasNext()){
117 			String key = it.next();
118 			if(!selected.contains(key)){
119 				removeSwappableSection(key);
120 			}
121 		}
122 		//SectionUpdateEvent e = new SectionUpdateEvent();
123 		//e.setSection(this);
124 		//LayoutController.findParentLayout(layout).fireApplicationEvent(e);
125 	}
126 	
127 	/**
128 	 * This is handled differently than handleUserSelection because it is assumed that the client
129 	 * is setting the correct values into the widgets, therefore no need to delete sections
130 	 * (also reduces chance of actually deleting data before it is even shown)
131 	 */
132 	private void handleSelection(){
133 		List<String> selected  = SwapSection.this.selectableWidget.getSelectedItems();
134 		for(int i = 0; i < selected.size(); i++){
135 			String key = selected.get(i);
136 			showSwappableSection(key);
137 		}
138 		
139 		Iterator<String> it = swapSectionMap.keySet().iterator();
140 		while(it.hasNext()){
141 			String key = it.next();
142 			if(!selected.contains(key)){
143 				removeSwappableSection(key);
144 			}
145 		}
146 	}
147 	
148 	private void showSwappableSection(String key){
149 		Section section = swapSectionMap.get(key);
150 		if(section != null){
151 			if(deleted.contains(section)){
152 				deleted.remove(section);
153 			}
154 			if(!section.getLayout().isVisible()){
155 				section.enableValidation(true);
156 				section.getLayout().setVisible(true);
157 			}
158 		}
159 	}
160 	
161 	private void removeSwappableSection(String key){
162 		Section section = swapSectionMap.get(key);
163 		if(section != null){
164 			if(!deleted.contains(section)){
165 				deleted.add(section);
166 			}
167 			if(section.getLayout().isVisible()){
168 				section.enableValidation(false);
169 				section.getLayout().setVisible(false);
170 			}
171 
172 		}
173 	}
174 	
175 	public void enableConfirmation(boolean enable){
176 		showConfirmation = enable;
177 	}
178 	
179 	public String addSection(Section section, String swapKey){
180 		swapSectionMap.put(swapKey, section);
181 		String key = layout.addLayout(section.getLayout());
182 		section.getLayout().setVisible(false);
183 		if(selectableWidget.getSelectedItems().contains(swapKey)){
184 			handleSelection();
185 		}
186 		sections.add(section);
187 		return key;
188 	}
189 	
190 	public String addSection(String key, Section section, String swapKey){
191 		swapSectionMap.put(swapKey, section);
192 		section.getLayout().setKey(key);
193 		String rkey = layout.addLayout(section.getLayout());
194 		section.getLayout().setVisible(false);
195 		if(selectableWidget.getSelectedItems().contains(swapKey)){
196 			handleSelection();
197 		}
198 		sections.add(section);
199 		return rkey;
200 	}
201 	
202 	
203 	@Override
204 	public String addSection(Section section) {
205 		throw new UnsupportedOperationException("Sections can be added to swappable section only through " +
206 				"the addSection(Section section, String swapKey) method");
207 		
208 	}
209 
210 	@Override
211 	public String addSection(String key, Section section) {
212 		throw new UnsupportedOperationException("Sections can be added to swappable section only through " +
213 				"the addSection(Section section, String swapKey) method");
214 	}
215 
216 	@Override
217 	public List<Section> getDeletedSections() {
218 		return deleted;
219 	}
220 
221     @Override
222     public List<String> getDeletionParentKeys() {
223         return deletionParentKeys;
224     }
225 
226     /**
227      * deletionParentKeys is optional and is only needed when you want to delete the
228      * entire structure in addition to individual fields with in deleted sections.
229      * 
230      * @see SectionBinding#setModelValue(Section, org.kuali.student.common.ui.client.mvc.DataModel, String)
231      */
232     @Override
233     public void setDeletionParentKey(List<String> deletionParentKeys) {
234         this.deletionParentKeys = deletionParentKeys;
235     }
236 }