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.widgets.dialog.ConfirmationDialog;
10  import org.kuali.student.common.ui.client.widgets.field.layout.layouts.VerticalFieldLayout;
11  import org.kuali.student.common.ui.client.widgets.list.KSSelectItemWidgetAbstract;
12  import org.kuali.student.common.ui.client.widgets.list.SelectionChangeEvent;
13  import org.kuali.student.common.ui.client.widgets.list.SelectionChangeHandler;
14  
15  import com.google.gwt.event.dom.client.ClickEvent;
16  import com.google.gwt.event.dom.client.ClickHandler;
17  
18  /**
19   * A section that contains sections that can be swapped in based on user selection on a KSSelectItemWidgetAbstract
20   * 
21   * 
22   * @author Kuali Student Team
23   *
24   */
25  public class SwapSection extends BaseSection implements HasSectionDeletion{
26  	
27  	private HashMap<String, Section> swapSectionMap = new HashMap<String, Section>();
28  	private KSSelectItemWidgetAbstract selectableWidget;
29  	private List<Section> deleted = new ArrayList<Section>();
30  	private ConfirmationDialog dialog; 
31  	private boolean showConfirmation = true;
32  	private List<String> lastSelection = new ArrayList<String>();
33  	private List<String> deletionParentKeys;
34  	private SwapEventHandler swapEventHandler;
35  	protected List<String> prevSelection = new ArrayList<String>();
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  		dialog.getCancelButton().addClickHandler(new ClickHandler() {
70  
71              @Override
72              public void onClick(ClickEvent event) {
73                  for (int i = 0; i < prevSelection.size(); i++) {
74                      SwapSection.this.selectableWidget.selectItem(prevSelection.get(i));
75                  }
76              }
77          });
78  		
79  		selectableWidget.addSelectionChangeHandler(new SelectionChangeHandler(){
80  
81  			@Override
82  			public void onSelectionChange(SelectionChangeEvent event) {
83  				if(event.isUserInitiated() && showConfirmation){
84  					if(SwapSection.this.selectableWidget.getSelectedItems().size() < lastSelection.size()){
85  						dialog.show();
86  					}
87  					else if(!SwapSection.this.selectableWidget.getSelectedItems().containsAll(lastSelection)){
88  //						List<String> selected  = SwapSection.this.selectableWidget.getSelectedItems();
89  //						for(int i = 0; i < selected.size(); i++){
90  //							String key = selected.get(i);
91  //							Section section = swapSectionMap.get(key);
92  //							if(section!=null){
93  //								if(section.getLayout().isVisible()){
94  //									dialog.show();
95  //								}
96  //							}
97  //						}
98  						dialog.show();
99  					}
100 					else{
101 						handleUserSelection();
102 					}
103 				}
104 				else if(event.isUserInitiated()){
105 					handleUserSelection();
106 				}
107 				else{
108 					handleSelection();
109 				}
110 				prevSelection.clear();              
111                 prevSelection.addAll(lastSelection);
112 				lastSelection.clear();
113 				lastSelection.addAll(SwapSection.this.selectableWidget.getSelectedItems());
114 			}
115 		});
116 		layout = new VerticalFieldLayout();
117 		this.add(layout);
118 	}
119 	
120 	private void handleUserSelection(){
121 		List<String> selected  = SwapSection.this.selectableWidget.getSelectedItems();
122 		for(int i = 0; i < selected.size(); i++){
123 			String key = selected.get(i);
124 			showSwappableSection(key);
125 		}
126 		
127 		Iterator<String> it = swapSectionMap.keySet().iterator();
128 		while(it.hasNext()){
129 			String key = it.next();
130 			if(!selected.contains(key)){
131 				removeSwappableSection(key);
132 			}
133 		}
134 		//SectionUpdateEvent e = new SectionUpdateEvent();
135 		//e.setSection(this);
136 		//LayoutController.findParentLayout(layout).fireApplicationEvent(e);
137 	}
138 	
139 	/**
140 	 * This is handled differently than handleUserSelection because it is assumed that the client
141 	 * is setting the correct values into the widgets, therefore no need to delete sections
142 	 * (also reduces chance of actually deleting data before it is even shown)
143 	 */
144 	private void handleSelection(){
145 		List<String> selected  = SwapSection.this.selectableWidget.getSelectedItems();
146 		for(int i = 0; i < selected.size(); i++){
147 			String key = selected.get(i);
148 			showSwappableSection(key);
149 		}
150 		
151 		Iterator<String> it = swapSectionMap.keySet().iterator();
152 		while(it.hasNext()){
153 			String key = it.next();
154 			if(!selected.contains(key)){
155 				removeSwappableSection(key);
156 			}
157 		}
158 	}
159 	
160 	private void showSwappableSection(String key){
161 		Section section = swapSectionMap.get(key);
162 		if(section != null){
163 			if(deleted.contains(section)){
164 				deleted.remove(section);
165 			}
166 			if(!section.getLayout().isVisible()){
167 				section.enableValidation(true);
168 				section.getLayout().setVisible(true);
169 			}
170 		}
171 		if (swapEventHandler != null){
172 		    swapEventHandler.onShowSwappableSection(key, section);
173 		}
174 	}
175 	
176 	private void removeSwappableSection(String key){
177 		Section section = swapSectionMap.get(key);
178 		if(section != null){
179 			if(!deleted.contains(section)){
180 				deleted.add(section);
181 			}
182 			if(section.getLayout().isVisible()){
183 				section.enableValidation(false);
184 				section.getLayout().setVisible(false);
185 			}
186 
187 		}
188 		if (swapEventHandler != null){
189             swapEventHandler.onRemoveSwappableSection(key, section);
190         }
191 	}
192 	
193 	public void enableConfirmation(boolean enable){
194 		showConfirmation = enable;
195 	}
196 	
197 	public String addSection(Section section, String swapKey){
198 		swapSectionMap.put(swapKey, section);
199 		String key = layout.addLayout(section.getLayout());
200 		section.getLayout().setVisible(false);
201 		if(selectableWidget.getSelectedItems().contains(swapKey)){
202 			handleSelection();
203 		}
204 		sections.add(section);
205 		return key;
206 	}
207 	
208 	public String addSection(String key, Section section, String swapKey){
209 		swapSectionMap.put(swapKey, section);
210 		section.getLayout().setKey(key);
211 		String rkey = layout.addLayout(section.getLayout());
212 		section.getLayout().setVisible(false);
213 		if(selectableWidget.getSelectedItems().contains(swapKey)){
214 			handleSelection();
215 		}
216 		sections.add(section);
217 		return rkey;
218 	}
219 	
220 	
221 	@Override
222 	public String addSection(Section section) {
223 		throw new UnsupportedOperationException("Sections can be added to swappable section only through " +
224 				"the addSection(Section section, String swapKey) method");
225 		
226 	}
227 
228 	@Override
229 	public String addSection(String key, Section section) {
230 		throw new UnsupportedOperationException("Sections can be added to swappable section only through " +
231 				"the addSection(Section section, String swapKey) method");
232 	}
233 
234 	@Override
235 	public List<Section> getDeletedSections() {
236 		return deleted;
237 	}
238 
239     @Override
240     public List<String> getDeletionParentKeys() {
241         return deletionParentKeys;
242     }
243 
244     /**
245      * deletionParentKeys is optional and is only needed when you want to delete the
246      * entire structure in addition to individual fields with in deleted sections.
247      * 
248      * @see SectionBinding#setModelValue(Section, org.kuali.student.common.ui.client.mvc.DataModel, String)
249      */
250     @Override
251     public void setDeletionParentKey(List<String> deletionParentKeys) {
252         this.deletionParentKeys = deletionParentKeys;
253     }
254 
255     public SwapEventHandler getSwapEventHandler() {
256         return swapEventHandler;
257     }
258 
259     public void setSwapEventHandler(SwapEventHandler swapEventHandler) {
260         this.swapEventHandler = swapEventHandler;
261     }
262     
263 }