1 /**
2 * Copyright 2005-2013 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.web.form;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.codehaus.jackson.map.ObjectMapper;
22 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
23 import org.kuali.rice.krad.uif.UifConstants;
24 import org.kuali.rice.krad.uif.UifConstants.ViewType;
25 import org.kuali.rice.krad.uif.UifParameters;
26 import org.kuali.rice.krad.uif.service.ViewService;
27 import org.kuali.rice.krad.uif.util.SessionTransient;
28 import org.kuali.rice.krad.uif.view.DialogManager;
29 import org.kuali.rice.krad.uif.view.View;
30 import org.kuali.rice.krad.uif.view.ViewModel;
31 import org.kuali.rice.krad.util.KRADUtils;
32 import org.springframework.web.multipart.MultipartFile;
33
34 import javax.servlet.http.HttpServletRequest;
35 import java.io.IOException;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Map;
40 import java.util.Properties;
41 import java.util.Set;
42 import java.util.UUID;
43
44 /**
45 * Base form class for views within the KRAD User Interface Framework
46 *
47 * <p>
48 * Holds properties necessary to determine the {@code View} instance that
49 * will be used to render the UI
50 * </p>
51 *
52 * @author Kuali Rice Team (rice.collab@kuali.org)
53 */
54 public class UifFormBase implements ViewModel {
55 private static final long serialVersionUID = 8432543267099454434L;
56
57 // logger
58 private static final Log LOG = LogFactory.getLog(UifFormBase.class);
59
60 // current view
61 protected String viewId;
62 protected String viewName;
63 protected ViewType viewTypeName;
64 protected String pageId;
65 protected String methodToCall;
66 protected String formKey;
67 @SessionTransient
68 protected String requestedFormKey;
69 protected String flowKey;
70 protected String sessionId;
71 protected int sessionTimeoutInterval;
72
73 @SessionTransient
74 protected HistoryFlow historyFlow;
75 @SessionTransient
76 protected HistoryManager historyManager;
77
78 @SessionTransient
79 protected String jumpToId;
80 @SessionTransient
81 protected String jumpToName;
82 @SessionTransient
83 protected String focusId;
84 @SessionTransient
85 protected boolean dirtyForm;
86
87 protected String formPostUrl;
88 protected String controllerMapping;
89
90 @SessionTransient
91 private String requestUrl;
92 private Map<String, String> initialRequestParameters;
93
94 protected String state;
95 protected boolean defaultsApplied;
96 protected boolean renderedInLightBox;
97
98 @SessionTransient
99 protected String growlScript;
100 @SessionTransient
101 protected String lightboxScript;
102
103 protected View view;
104 protected View postedView;
105
106 protected Map<String, String> viewRequestParameters;
107 protected List<String> readOnlyFieldsList;
108 protected Map<String, Object> newCollectionLines;
109
110 @SessionTransient
111 protected Map<String, String> actionParameters;
112 protected Map<String, Object> clientStateForSyncing;
113 @SessionTransient
114 protected Map<String, Set<String>> selectedCollectionLines;
115
116 protected List<Object> addedCollectionItems;
117
118 @SessionTransient
119 protected MultipartFile attachmentFile;
120
121 // navigation
122 protected String returnLocation;
123 protected String returnFormKey;
124
125 @SessionTransient
126 protected boolean ajaxRequest;
127 @SessionTransient
128 protected String ajaxReturnType;
129 @SessionTransient
130 private String requestJsonTemplate;
131
132 // dialog fields
133 @SessionTransient
134 protected String dialogExplanation;
135 @SessionTransient
136 protected String dialogResponse;
137 protected DialogManager dialogManager;
138
139 @SessionTransient
140 protected boolean requestRedirected;
141 @SessionTransient
142 protected String updateComponentId;
143
144 protected Map<String, Object> extensionData;
145
146 public UifFormBase() {
147 defaultsApplied = false;
148 renderedInLightBox = false;
149 requestRedirected = false;
150
151 readOnlyFieldsList = new ArrayList<String>();
152 viewRequestParameters = new HashMap<String, String>();
153 newCollectionLines = new HashMap<String, Object>();
154 actionParameters = new HashMap<String, String>();
155 clientStateForSyncing = new HashMap<String, Object>();
156 selectedCollectionLines = new HashMap<String, Set<String>>();
157 addedCollectionItems = new ArrayList();
158 dialogManager = new DialogManager();
159 extensionData = new HashMap<String, Object>();
160 }
161
162 /**
163 * @see org.kuali.rice.krad.uif.view.ViewModel#postBind(javax.servlet.http.HttpServletRequest)
164 */
165 @Override
166 public void postBind(HttpServletRequest request) {
167 // assign form key if this is a new form or the requested form key is not in session
168 UifFormManager uifFormManager = (UifFormManager) request.getSession().getAttribute(UifParameters.FORM_MANAGER);
169 if (StringUtils.isBlank(formKey) || !uifFormManager.hasSessionForm(formKey)) {
170 formKey = generateFormKey();
171 }
172
173 // default form post URL to request URL
174 formPostUrl = request.getRequestURL().toString();
175
176 if (request.getSession() != null) {
177 sessionId = request.getSession().getId();
178 sessionTimeoutInterval = request.getSession().getMaxInactiveInterval();
179 }
180
181 //set controller mapping property
182 controllerMapping = request.getPathInfo();
183
184 // get any sent client view state and parse into map
185 if (request.getParameterMap().containsKey(UifParameters.CLIENT_VIEW_STATE)) {
186 String clientStateJSON = request.getParameter(UifParameters.CLIENT_VIEW_STATE);
187 if (StringUtils.isNotBlank(clientStateJSON)) {
188 // change single quotes to double quotes (necessary because the reverse was done for sending)
189 clientStateJSON = StringUtils.replace(clientStateJSON, "'", "\"");
190
191 ObjectMapper mapper = new ObjectMapper();
192 try {
193 clientStateForSyncing = mapper.readValue(clientStateJSON, Map.class);
194 } catch (IOException e) {
195 throw new RuntimeException("Unable to decode client side state JSON", e);
196 }
197 }
198 }
199
200 // populate read only fields list
201 if (request.getParameter(UifParameters.READ_ONLY_FIELDS) != null) {
202 String readOnlyFields = request.getParameter(UifParameters.READ_ONLY_FIELDS);
203 setReadOnlyFieldsList(KRADUtils.convertStringParameterToList(readOnlyFields));
204 }
205
206 // clean parameters from XSS attacks that will be written out as hiddens
207 this.pageId = KRADUtils.stripXSSPatterns(this.pageId);
208 this.methodToCall = KRADUtils.stripXSSPatterns(this.methodToCall);
209 this.formKey = KRADUtils.stripXSSPatterns(this.formKey);
210 this.requestedFormKey = KRADUtils.stripXSSPatterns(this.requestedFormKey);
211 this.flowKey = KRADUtils.stripXSSPatterns(this.flowKey);
212 this.sessionId = KRADUtils.stripXSSPatterns(this.sessionId);
213 this.formPostUrl = KRADUtils.stripXSSPatterns(this.formPostUrl);
214 this.returnLocation = KRADUtils.stripXSSPatterns(this.returnLocation);
215 this.returnFormKey = KRADUtils.stripXSSPatterns(this.returnFormKey);
216 this.requestUrl = KRADUtils.stripXSSPatterns(this.requestUrl);
217 }
218
219 /**
220 * Creates the unique id used to store this "conversation" in the session.
221 * The default method generates a java UUID.
222 *
223 * @return UUID
224 */
225 protected String generateFormKey() {
226 return UUID.randomUUID().toString();
227 }
228
229 /**
230 * @see org.kuali.rice.krad.uif.view.ViewModel#getViewId()
231 */
232 @Override
233 public String getViewId() {
234 return this.viewId;
235 }
236
237 /**
238 * @see org.kuali.rice.krad.uif.view.ViewModel#setViewId(String)
239 */
240 @Override
241 public void setViewId(String viewId) {
242 this.viewId = viewId;
243 }
244
245 /**
246 * @see org.kuali.rice.krad.uif.view.ViewModel#getViewName()
247 */
248 @Override
249 public String getViewName() {
250 return this.viewName;
251 }
252
253 /**
254 * @see org.kuali.rice.krad.uif.view.ViewModel#setViewName(String)
255 */
256 @Override
257 public void setViewName(String viewName) {
258 this.viewName = viewName;
259 }
260
261 /**
262 * @see org.kuali.rice.krad.uif.view.ViewModel#getViewTypeName()
263 */
264 @Override
265 public ViewType getViewTypeName() {
266 return this.viewTypeName;
267 }
268
269 /**
270 * @see org.kuali.rice.krad.uif.view.ViewModel#setViewTypeName(org.kuali.rice.krad.uif.UifConstants.ViewType)
271 */
272 @Override
273 public void setViewTypeName(ViewType viewTypeName) {
274 this.viewTypeName = viewTypeName;
275 }
276
277 /**
278 * @see org.kuali.rice.krad.uif.view.ViewModel#getPageId()
279 */
280 @Override
281 public String getPageId() {
282 return this.pageId;
283 }
284
285 /**
286 * @see org.kuali.rice.krad.uif.view.ViewModel#setPageId(String)
287 */
288 @Override
289 public void setPageId(String pageId) {
290 this.pageId = pageId;
291 }
292
293 /**
294 * @see org.kuali.rice.krad.uif.view.ViewModel#getFormPostUrl()
295 */
296 @Override
297 public String getFormPostUrl() {
298 return this.formPostUrl;
299 }
300
301 /**
302 * @see org.kuali.rice.krad.uif.view.ViewModel#setFormPostUrl(String)
303 */
304 @Override
305 public void setFormPostUrl(String formPostUrl) {
306 this.formPostUrl = formPostUrl;
307 }
308
309 /**
310 * Name of the controllerMapping for this form (includes slash)
311 *
312 * @return the controllerMapping string
313 */
314 public String getControllerMapping() {
315 return controllerMapping;
316 }
317
318 /**
319 * The current {@link HistoryFlow} for this form which stores a trail of urls/breadcrumbs primarily used for
320 * path-based breadcrumb display
321 *
322 * @return the {@link HistoryFlow}
323 */
324 public HistoryFlow getHistoryFlow() {
325 return historyFlow;
326 }
327
328 /**
329 * Set the current HistoryFlow for this form
330 *
331 * @param historyFlow
332 */
333 public void setHistoryFlow(HistoryFlow historyFlow) {
334 this.historyFlow = historyFlow;
335 }
336
337 /**
338 * The current {@link HistoryManager} that was pulled from session which store all {@link HistoryFlow} objects in
339 * the current session to keep track of the path the user has taken across views (primarily used by path-based
340 * breadcrumbs)
341 *
342 * @return the HistoryManager
343 */
344 public HistoryManager getHistoryManager() {
345 return historyManager;
346 }
347
348 /**
349 * Set the current HistoryManager
350 *
351 * @param historyManager
352 */
353 public void setHistoryManager(HistoryManager historyManager) {
354 this.historyManager = historyManager;
355 }
356
357 /**
358 * The flowKey representing the HistoryFlow this form may be in.
359 *
360 * <p>This allows for a flow to continue by key or start (if set to "start").
361 * If null or blank, no flow (or path based
362 * breadcrumbs) are being tracked.</p>
363 *
364 * @return the flowKey
365 */
366 public String getFlowKey() {
367 return flowKey;
368 }
369
370 /**
371 * Set the flowKey
372 *
373 * @param flowKey
374 */
375 public void setFlowKey(String flowKey) {
376 this.flowKey = flowKey;
377 }
378
379 /**
380 * The original requestUrl for the View represented by this form (url received by the controller for initial
381 * request)
382 *
383 * @return the requestUrl
384 */
385 public String getRequestUrl() {
386 return requestUrl;
387 }
388
389 /**
390 * Set the requestUrl
391 *
392 * @param requestUrl
393 */
394 public void setRequestUrl(String requestUrl) {
395 this.requestUrl = requestUrl;
396 }
397
398 /**
399 * The requestParameters represent all the parameters in the query string that were initially passed to this View
400 * by the initial request
401 *
402 * @return the requestParameters
403 */
404 public Map<String, String> getInitialRequestParameters() {
405 return initialRequestParameters;
406 }
407
408 /**
409 * Set the requestParameters
410 *
411 * @param requestParameters
412 */
413 public void setInitialRequestParameters(Map<String, String> requestParameters) {
414 this.initialRequestParameters = requestParameters;
415 }
416
417 public String getReturnLocation() {
418 return this.returnLocation;
419 }
420
421 public void setReturnLocation(String returnLocation) {
422 this.returnLocation = returnLocation;
423 }
424
425 public String getReturnFormKey() {
426 return this.returnFormKey;
427 }
428
429 public void setReturnFormKey(String returnFormKey) {
430 this.returnFormKey = returnFormKey;
431 }
432
433 /**
434 * Holds the id for the user's current session
435 *
436 * <p>
437 * The user's session id is used to track when a timeout has occurred and enforce the policy
438 * configured with the {@link org.kuali.rice.krad.uif.view.ViewSessionPolicy}. This property gets initialized
439 * in the {@link #postBind(javax.servlet.http.HttpServletRequest)} method and then is written out as a
440 * hidden on the view. Therefore each post done on the view will send back the session id when the view was
441 * rendering, and the {@link org.kuali.rice.krad.web.filter.UifSessionTimeoutFilter} can use that to determine
442 * if a timeout has occurred
443 * </p>
444 *
445 * @return id for the user's current session
446 */
447 public String getSessionId() {
448 return sessionId;
449 }
450
451 /**
452 * Holds the configured session timeout interval
453 *
454 * <p>
455 * Holds the session timeout interval so it can be referenced to give the user notifications (for example the
456 * session timeout warning reads this property). This is initialized from the session object in
457 * {@link #postBind(javax.servlet.http.HttpServletRequest)}
458 * </p>
459 *
460 * @return amount of time in milliseconds before the session will timeout
461 */
462 public int getSessionTimeoutInterval() {
463 return sessionTimeoutInterval;
464 }
465
466 /**
467 * Identifies the controller method that should be invoked to fulfill a
468 * request. The value will be matched up against the 'params' setting on the
469 * {@code RequestMapping} annotation for the controller method
470 *
471 * @return String method to call
472 */
473 public String getMethodToCall() {
474 return this.methodToCall;
475 }
476
477 /**
478 * Setter for the method to call
479 *
480 * @param methodToCall
481 */
482 public void setMethodToCall(String methodToCall) {
483 this.methodToCall = methodToCall;
484 }
485
486 /**
487 * @see org.kuali.rice.krad.uif.view.ViewModel#getViewRequestParameters()
488 */
489 @Override
490 public Map<String, String> getViewRequestParameters() {
491 return this.viewRequestParameters;
492 }
493
494 /**
495 * @see org.kuali.rice.krad.uif.view.ViewModel#setViewRequestParameters(java.util.Map<String,String>)
496 */
497 @Override
498 public void setViewRequestParameters(Map<String, String> viewRequestParameters) {
499 this.viewRequestParameters = viewRequestParameters;
500 }
501
502 /**
503 * @see org.kuali.rice.krad.uif.view.ViewModel#getReadOnlyFieldsList()
504 */
505 @Override
506 public List<String> getReadOnlyFieldsList() {
507 return readOnlyFieldsList;
508 }
509
510 /**
511 * @see org.kuali.rice.krad.uif.view.ViewModel#setReadOnlyFieldsList(java.util.List<String>)
512 */
513 @Override
514 public void setReadOnlyFieldsList(List<String> readOnlyFieldsList) {
515 this.readOnlyFieldsList = readOnlyFieldsList;
516 }
517
518 /**
519 * @see org.kuali.rice.krad.uif.view.ViewModel#getNewCollectionLines()
520 */
521 @Override
522 public Map<String, Object> getNewCollectionLines() {
523 return this.newCollectionLines;
524 }
525
526 /**
527 * @see org.kuali.rice.krad.uif.view.ViewModel#setNewCollectionLines(java.util.Map<String,Object>)
528 */
529 @Override
530 public void setNewCollectionLines(Map<String, Object> newCollectionLines) {
531 this.newCollectionLines = newCollectionLines;
532 }
533
534 /**
535 * @see org.kuali.rice.krad.uif.view.ViewModel#getActionParameters()
536 */
537 @Override
538 public Map<String, String> getActionParameters() {
539 return this.actionParameters;
540 }
541
542 /**
543 * Returns the action parameters map as a {@code Properties} instance
544 *
545 * @return Properties action parameters
546 */
547 public Properties getActionParametersAsProperties() {
548 return KRADUtils.convertMapToProperties(actionParameters);
549 }
550
551 /**
552 * @see org.kuali.rice.krad.uif.view.ViewModel#setActionParameters(java.util.Map<String,String>)
553 */
554 @Override
555 public void setActionParameters(Map<String, String> actionParameters) {
556 this.actionParameters = actionParameters;
557 }
558
559 /**
560 * Retrieves the value for the given action parameter, or empty string if
561 * not found
562 *
563 * @param actionParameterName - name of the action parameter to retrieve value for
564 * @return String parameter value or empty string
565 */
566 public String getActionParamaterValue(String actionParameterName) {
567 if ((actionParameters != null) && actionParameters.containsKey(actionParameterName)) {
568 return actionParameters.get(actionParameterName);
569 }
570
571 return "";
572 }
573
574 /**
575 * Returns the action event that was sent in the action parameters (if any)
576 *
577 * <p>
578 * The action event is a special action parameter that can be sent to indicate a type of action being taken. This
579 * can be looked at by the view or components to render differently
580 * </p>
581 *
582 * TODO: make sure action parameters are getting reinitialized on each request
583 *
584 * @return String action event name or blank if action event was not sent
585 */
586 public String getActionEvent() {
587 if ((actionParameters != null) && actionParameters.containsKey(UifConstants.UrlParams.ACTION_EVENT)) {
588 return actionParameters.get(UifConstants.UrlParams.ACTION_EVENT);
589 }
590
591 return "";
592 }
593
594 /**
595 * @see org.kuali.rice.krad.uif.view.ViewModel#getClientStateForSyncing()
596 */
597 @Override
598 public Map<String, Object> getClientStateForSyncing() {
599 return clientStateForSyncing;
600 }
601
602 /**
603 * Setter for the client state
604 *
605 * @param clientStateForSyncing
606 */
607 public void setClientStateForSyncing(Map<String, Object> clientStateForSyncing) {
608 this.clientStateForSyncing = clientStateForSyncing;
609 }
610
611 /**
612 * @see org.kuali.rice.krad.uif.view.ViewModel#getSelectedCollectionLines()
613 */
614 @Override
615 public Map<String, Set<String>> getSelectedCollectionLines() {
616 return selectedCollectionLines;
617 }
618
619 /**
620 * @see org.kuali.rice.krad.uif.view.ViewModel#setSelectedCollectionLines(java.util.Map<String,java.util.Set<String>>)
621 */
622 @Override
623 public void setSelectedCollectionLines(Map<String, Set<String>> selectedCollectionLines) {
624 this.selectedCollectionLines = selectedCollectionLines;
625 }
626
627 /**
628 * Key string that identifies the form instance in session storage
629 *
630 * <p>
631 * When the view is posted, the previous form instance is retrieved and then
632 * populated from the request parameters. This key string is retrieve the
633 * session form from the session service
634 * </p>
635 *
636 * @return String form session key
637 */
638 public String getFormKey() {
639 return this.formKey;
640 }
641
642 /**
643 * Setter for the form's session key
644 *
645 * @param formKey
646 */
647 public void setFormKey(String formKey) {
648 this.formKey = formKey;
649 }
650
651 /**
652 * This is the formKey sent on the original request. It may differ from the actual form key stored in formKey
653 * based on if the form still exists in session by this key or not.
654 *
655 * @return the original requested form key
656 */
657 public String getRequestedFormKey() {
658 return requestedFormKey;
659 }
660
661 /**
662 * Set the requestedFormKey
663 *
664 * @param requestedFormKey
665 */
666 public void setRequestedFormKey(String requestedFormKey) {
667 this.requestedFormKey = requestedFormKey;
668 }
669
670 /**
671 * @see org.kuali.rice.krad.uif.view.ViewModel#isDefaultsApplied()
672 */
673 @Override
674 public boolean isDefaultsApplied() {
675 return this.defaultsApplied;
676 }
677
678 /**
679 * @see org.kuali.rice.krad.uif.view.ViewModel#setDefaultsApplied(boolean)
680 */
681 @Override
682 public void setDefaultsApplied(boolean defaultsApplied) {
683 this.defaultsApplied = defaultsApplied;
684 }
685
686 /**
687 * Indicates whether a redirect has been requested for the view
688 *
689 * @return boolean true if redirect was requested, false if not
690 */
691 public boolean isRequestRedirected() {
692 return requestRedirected;
693 }
694
695 /**
696 * Setter for the request redirect indicator
697 *
698 * @param requestRedirected
699 */
700 public void setRequestRedirected(boolean requestRedirected) {
701 this.requestRedirected = requestRedirected;
702 }
703
704 /**
705 * Holder for files that are attached through the view
706 *
707 * @return MultipartFile representing the attachment
708 */
709 public MultipartFile getAttachmentFile() {
710 return this.attachmentFile;
711 }
712
713 /**
714 * Setter for the form's attachment file
715 *
716 * @param attachmentFile
717 */
718 public void setAttachmentFile(MultipartFile attachmentFile) {
719 this.attachmentFile = attachmentFile;
720 }
721
722 /**
723 * @see org.kuali.rice.krad.uif.view.ViewModel#getUpdateComponentId()
724 */
725 public String getUpdateComponentId() {
726 return updateComponentId;
727 }
728
729 /**
730 * @see org.kuali.rice.krad.uif.view.ViewModel#setUpdateComponentId(java.lang.String)
731 */
732 public void setUpdateComponentId(String updateComponentId) {
733 this.updateComponentId = updateComponentId;
734 }
735
736 /**
737 * @see org.kuali.rice.krad.uif.view.ViewModel#getView()
738 */
739 @Override
740 public View getView() {
741 return this.view;
742 }
743
744 /**
745 * @see org.kuali.rice.krad.uif.view.ViewModel#setView(org.kuali.rice.krad.uif.view.View)
746 */
747 @Override
748 public void setView(View view) {
749 this.view = view;
750 }
751
752 /**
753 * @see org.kuali.rice.krad.uif.view.ViewModel#getPostedView()
754 */
755 @Override
756 public View getPostedView() {
757 return this.postedView;
758 }
759
760 /**
761 * @see org.kuali.rice.krad.uif.view.ViewModel#setPostedView(org.kuali.rice.krad.uif.view.View)
762 */
763 @Override
764 public void setPostedView(View postedView) {
765 this.postedView = postedView;
766 }
767
768 /**
769 * Instance of the {@code ViewService} that can be used to retrieve
770 * {@code View} instances
771 *
772 * @return ViewService implementation
773 */
774 protected ViewService getViewService() {
775 return KRADServiceLocatorWeb.getViewService();
776 }
777
778 /**
779 * The jumpToId for this form, the element with this id will be jumped to automatically
780 * when the form is loaded in the view.
781 * Using "TOP" or "BOTTOM" will jump to the top or the bottom of the resulting page.
782 * jumpToId always takes precedence over jumpToName, if set.
783 *
784 * @return the jumpToId
785 */
786 public String getJumpToId() {
787 return this.jumpToId;
788 }
789
790 /**
791 * @param jumpToId the jumpToId to set
792 */
793 public void setJumpToId(String jumpToId) {
794 this.jumpToId = jumpToId;
795 }
796
797 /**
798 * The jumpToName for this form, the element with this name will be jumped to automatically
799 * when the form is loaded in the view.
800 * WARNING: jumpToId always takes precedence over jumpToName, if set.
801 *
802 * @return the jumpToName
803 */
804 public String getJumpToName() {
805 return this.jumpToName;
806 }
807
808 /**
809 * @param jumpToName the jumpToName to set
810 */
811 public void setJumpToName(String jumpToName) {
812 this.jumpToName = jumpToName;
813 }
814
815 /**
816 * Field to place focus on when the page loads
817 * An empty focusId will result in focusing on the first visible input element by default.
818 *
819 * @return the focusId
820 */
821 public String getFocusId() {
822 return this.focusId;
823 }
824
825 /**
826 * @param focusId the focusId to set
827 */
828 public void setFocusId(String focusId) {
829 this.focusId = focusId;
830 }
831
832 /**
833 * True when the form is considered dirty (data has changed from original value), false otherwise
834 *
835 * <p>For most scenarios, this flag should NOT be set to true.
836 * If this is set, it must be managed explicitly by the application. This flag exists for marking a
837 * form dirty from a server call, so it must be changed to false when the form is no longer considered dirty.
838 * The krad save Action and navigate methodToCall resets this flag back to false, but any other setting of
839 * this flag must be managed by custom configuration/methods, if custom dirtyForm management is needed.</p>
840 *
841 * @return true if the form is considered dirty, false otherwise
842 */
843 public boolean isDirtyForm() {
844 return dirtyForm;
845 }
846
847 /**
848 * Sets the dirtyForm flag
849 *
850 * <p>For most scenarios, this flag should NOT be set to true.
851 * If this is set, it must be managed explicitly by the application. This flag exists for marking a
852 * form dirty from a server call, so it must be changed to false when the form is no longer considered dirty.
853 * The krad save Action and navigate methodToCall resets this flag back to false, but any other setting of
854 * this flag must be managed by custom configuration/methods, if custom dirtyForm management is needed.</p>
855 *
856 * @param dirtyForm
857 */
858 public void setDirtyForm(boolean dirtyForm) {
859 this.dirtyForm = dirtyForm;
860 }
861
862 /**
863 * Set the dirtyForm flag using a String that will be converted to boolean
864 *
865 * @param dirtyForm
866 */
867 public void setDirtyForm(String dirtyForm) {
868 if(dirtyForm != null){
869 this.dirtyForm = Boolean.parseBoolean(dirtyForm);
870 }
871 }
872
873 /**
874 * Indicates whether the view is rendered within a lightbox
875 *
876 * <p>
877 * Some discussion (for example how a close button behaves) need to change based on whether the
878 * view is rendered within a lightbox or the standard browser window. This boolean is true when it is
879 * within a lightbox
880 * </p>
881 *
882 * @return boolean true if view is rendered within a lightbox, false if not
883 */
884 public boolean isRenderedInLightBox() {
885 return this.renderedInLightBox;
886 }
887
888 /**
889 * Setter for the rendered within lightbox indicator
890 *
891 * @param renderedInLightBox
892 */
893 public void setRenderedInLightBox(boolean renderedInLightBox) {
894 this.renderedInLightBox = renderedInLightBox;
895 }
896
897 /**
898 * @see org.kuali.rice.krad.uif.view.ViewModel#getGrowlScript()
899 */
900 @Override
901 public String getGrowlScript() {
902 return growlScript;
903 }
904
905 /**
906 * @see org.kuali.rice.krad.uif.view.ViewModel#setGrowlScript(String)
907 */
908 @Override
909 public void setGrowlScript(String growlScript) {
910 this.growlScript = growlScript;
911 }
912
913 /**
914 * @see org.kuali.rice.krad.uif.view.ViewModel#getState()
915 */
916 public String getState() {
917 return state;
918 }
919
920 /**
921 * @see org.kuali.rice.krad.uif.view.ViewModel#setState(String)
922 */
923 public void setState(String state) {
924 this.state = state;
925 }
926
927 /**
928 * @see org.kuali.rice.krad.uif.view.ViewModel#getLightboxScript()
929 */
930 @Override
931 public String getLightboxScript() {
932 return lightboxScript;
933 }
934
935 /**
936 * @see org.kuali.rice.krad.uif.view.ViewModel#setLightboxScript(String)
937 */
938 @Override
939 public void setLightboxScript(String lightboxScript) {
940 this.lightboxScript = lightboxScript;
941 }
942
943 /**
944 * @see org.kuali.rice.krad.uif.view.ViewModel#isAjaxRequest()
945 */
946 @Override
947 public boolean isAjaxRequest() {
948 return ajaxRequest;
949 }
950
951 /**
952 * @see org.kuali.rice.krad.uif.view.ViewModel#setAjaxRequest(boolean)
953 */
954 @Override
955 public void setAjaxRequest(boolean ajaxRequest) {
956 this.ajaxRequest = ajaxRequest;
957 }
958
959 /**
960 * @see org.kuali.rice.krad.uif.view.ViewModel#getAjaxReturnType()
961 */
962 @Override
963 public String getAjaxReturnType() {
964 return ajaxReturnType;
965 }
966
967 /**
968 * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdateComponentRequest()
969 */
970 @Override
971 public boolean isUpdateComponentRequest() {
972 return isAjaxRequest() && StringUtils.isNotBlank(getAjaxReturnType()) && getAjaxReturnType().equals(
973 UifConstants.AjaxReturnTypes.UPDATECOMPONENT.getKey());
974 }
975
976 /**
977 * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdateDialogRequest()
978 */
979 @Override
980 public boolean isUpdateDialogRequest() {
981 return isAjaxRequest() && StringUtils.isNotBlank(getAjaxReturnType()) && getAjaxReturnType().equals(
982 UifConstants.AjaxReturnTypes.UPDATEDIALOG.getKey());
983 }
984
985 /**
986 * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdatePageRequest()
987 */
988 @Override
989 public boolean isUpdatePageRequest() {
990 return isAjaxRequest() && StringUtils.isNotBlank(getAjaxReturnType()) && getAjaxReturnType().equals(
991 UifConstants.AjaxReturnTypes.UPDATEPAGE.getKey());
992 }
993
994 /**
995 * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdateNoneRequest()
996 */
997 @Override
998 public boolean isUpdateNoneRequest() {
999 return isAjaxRequest() && StringUtils.isNotBlank(getAjaxReturnType()) && getAjaxReturnType().equals(
1000 UifConstants.AjaxReturnTypes.UPDATENONE.getKey());
1001 }
1002
1003 /**
1004 * @see org.kuali.rice.krad.uif.view.ViewModel#isBuildViewRequest()
1005 */
1006 @Override
1007 public boolean isBuildViewRequest() {
1008 return !isAjaxRequest() || (StringUtils.isNotBlank(getAjaxReturnType()) && (getAjaxReturnType().equals(
1009 UifConstants.AjaxReturnTypes.UPDATEVIEW.getKey()) || isUpdatePageRequest()));
1010 }
1011
1012 /**
1013 * @see org.kuali.rice.krad.uif.view.ViewModel#isUpdateViewRequest()
1014 */
1015 @Override
1016 public boolean isUpdateViewRequest() {
1017 return isAjaxRequest() &&
1018 StringUtils.isNotBlank(getAjaxReturnType()) &&
1019 (isUpdateComponentRequest() || getAjaxReturnType().equals(
1020 UifConstants.AjaxReturnTypes.DISPLAYLIGHTBOX.getKey()));
1021 }
1022
1023 /**
1024 * @see org.kuali.rice.krad.uif.view.ViewModel#setAjaxReturnType(String)
1025 */
1026 @Override
1027 public void setAjaxReturnType(String ajaxReturnType) {
1028 this.ajaxReturnType = ajaxReturnType;
1029 }
1030
1031 /**
1032 * @see org.kuali.rice.krad.uif.view.ViewModel#isJsonRequest()
1033 */
1034 public boolean isJsonRequest() {
1035 return StringUtils.isNotBlank(getRequestJsonTemplate());
1036 }
1037
1038 /**
1039 * @see org.kuali.rice.krad.uif.view.ViewModel#getRequestJsonTemplate()
1040 */
1041 public String getRequestJsonTemplate() {
1042 return requestJsonTemplate;
1043 }
1044
1045 /**
1046 * @see org.kuali.rice.krad.uif.view.ViewModel#setRequestJsonTemplate
1047 */
1048 public void setRequestJsonTemplate(String requestJsonTemplate) {
1049 this.requestJsonTemplate = requestJsonTemplate;
1050 }
1051
1052 /**
1053 * Returns the String entered by the user when presented a dialog
1054 *
1055 * <p>
1056 * Field defined here so all forms will be able to bind to a dialog using the same property
1057 * </p>
1058 *
1059 * @return String - the text entered by a user as a reply in a modal dialog.
1060 */
1061 public String getDialogExplanation() {
1062 return dialogExplanation;
1063 }
1064
1065 /**
1066 * Sets the dialogExplanation text value.
1067 *
1068 * @param dialogExplanation - text entered by user when replying to a modal dialog
1069 */
1070 public void setDialogExplanation(String dialogExplanation) {
1071 this.dialogExplanation = dialogExplanation;
1072 }
1073
1074 /**
1075 * Represents the option chosen by the user when interacting with a modal dialog
1076 *
1077 * <p>
1078 * This is used to determine which option was chosen by the user. The value is the key in the key/value pair
1079 * selected in the control.
1080 * </p>
1081 *
1082 * @return - String key selected by the user
1083 */
1084 public String getDialogResponse() {
1085 return dialogResponse;
1086 }
1087
1088 /**
1089 * Sets the response key text selected by the user as a response to a modal dialog
1090 *
1091 * @param dialogResponse - the key of the option chosen by the user
1092 */
1093 public void setDialogResponse(String dialogResponse) {
1094 this.dialogResponse = dialogResponse;
1095 }
1096
1097 /**
1098 * Gets the DialogManager for this view/form
1099 *
1100 * <p>
1101 * The DialogManager tracks modal dialog interactions with the user
1102 * </p>
1103 *
1104 * @return
1105 */
1106 public DialogManager getDialogManager() {
1107 return dialogManager;
1108 }
1109
1110 /**
1111 * Sets the DialogManager for this view
1112 *
1113 * @param dialogManager - DialogManager instance for this view
1114 */
1115 public void setDialogManager(DialogManager dialogManager) {
1116 this.dialogManager = dialogManager;
1117 }
1118
1119 /**
1120 * @see org.kuali.rice.krad.uif.view.ViewModel#getExtensionData()
1121 */
1122 public Map<String, Object> getExtensionData() {
1123 return extensionData;
1124 }
1125
1126 /**
1127 * @see org.kuali.rice.krad.uif.view.ViewModel#setExtensionData(java.util.Map<String,Object>)
1128 */
1129 public void setExtensionData(Map<String, Object> extensionData) {
1130 this.extensionData = extensionData;
1131 }
1132
1133 /**
1134 * The {@code List} that contains all newly added items for the collections on the model
1135 *
1136 * <p>
1137 * This list contains the new items for all the collections on the model.
1138 * </p>
1139 *
1140 * @return List of the newly added item lists
1141 */
1142 public List getAddedCollectionItems() {
1143 return addedCollectionItems;
1144 }
1145
1146 /**
1147 * Setter for the newly added item list
1148 *
1149 * @param addedCollectionItems
1150 */
1151 public void setAddedCollectionItems(List addedCollectionItems) {
1152 this.addedCollectionItems = addedCollectionItems;
1153 }
1154
1155 /**
1156 * Indicates whether an collection item has been newly added
1157 *
1158 * <p>
1159 * Tests collection items against the list of newly added items on the model. This list gets cleared when the view
1160 * is submitted and the items are persisted.
1161 * </p>
1162 *
1163 * @param item - the item to test against list of newly added items
1164 * @return boolean true if the item has been newly added
1165 */
1166 public boolean isAddedCollectionItem(Object item) {
1167 return addedCollectionItems.contains(item);
1168 }
1169
1170 }