package org.akaza.openclinica.view.form;
import org.akaza.openclinica.bean.submit.DisplayItemBean;
import org.akaza.openclinica.bean.submit.DisplayItemGroupBean;
import org.akaza.openclinica.bean.submit.ItemDataBean;
import org.akaza.openclinica.bean.submit.SectionBean;
import org.akaza.openclinica.i18n.util.ResourceBundleProvider;
import org.jdom.Element;
import java.util.ArrayList;
import java.util.List;
import java.util.SortedMap;
/**
* A utility class containing various methods that are used for generating Web
* form views.
*
*/
public class ViewBuilderUtil {
/**
* For the purpose of generating a certain HTML view, this method finds out
* whether any horizontally displayed checkboxes or radio buttons are
* involved.
*
* @param displayBeans
* A List of DisplayItemBeans for a CRF Section
* @return true if any of the DisplayItemBeans have a horizontal checkbox or
* radio button
*/
public boolean hasResponseLayout(List<DisplayItemBean> displayBeans) {
String responseName;
for (DisplayItemBean dBean : displayBeans) {
responseName = dBean.getMetadata().getResponseSet().getResponseType().getName();
if (responseName == null) {
responseName = "";
}
if (dBean.getMetadata().getResponseLayout().equalsIgnoreCase("horizontal")
&& (responseName.equalsIgnoreCase("radio") || responseName.equalsIgnoreCase("checkbox"))) {
return true;
}
}
return false;
}
public int calcNumberofColumns(DisplayItemGroupBean displayGroup) {
if (displayGroup == null || displayGroup.getItems().size() == 0) {
return 0;
}
int columns = 0;
String responseName;
String responseLayout;
for (DisplayItemBean disBean : displayGroup.getItems()) {
responseName = disBean.getMetadata().getResponseSet().getResponseType().getName();
responseLayout = disBean.getMetadata().getResponseLayout();
if ((responseName.equalsIgnoreCase("radio") || responseName.equalsIgnoreCase("checkbox")) && responseLayout.equalsIgnoreCase("horizontal")) {
columns += disBean.getMetadata().getResponseSet().getOptions().size();
} else {
columns++;
}
}
return columns;
}
public void addRemoveRowControl(Element row, String repeatParentId,
boolean hasDarkBorders) {
Element repeatCell = new Element("td");
if(hasDarkBorders){
String cssClasses = CssRules.getClassNamesForTag("td borders_on");
repeatCell.setAttribute("class",cssClasses);
} else {
repeatCell = this.setClassNames(repeatCell);
}
repeatCell.addContent(RepeatManager.createrepeatButtonControl(ResourceBundleProvider.getResWord("remove"), repeatParentId));
row.addContent(repeatCell);
}
public void createAddRowControl(Element tbody, String repeatParentId, int columnNumber, boolean hasDarkBorders) {
Element addButtonRow = new Element("tr");
Element addButtonCell = new Element("td");
if(hasDarkBorders){
String cssClasses = CssRules.getClassNamesForTag("td borders_on");
addButtonCell.setAttribute("class",cssClasses);
} else {
addButtonCell = this.setClassNames(addButtonCell);
}
addButtonCell.setAttribute("style","display:block;");
addButtonCell.setAttribute("colspan", columnNumber + "");
addButtonCell.addContent(RepeatManager.createrepeatButtonControl(ResourceBundleProvider.getResWord("add"), repeatParentId));
addButtonRow.addContent(addButtonCell);
tbody.addContent(addButtonRow);
}
public Element setClassNames(Element styledElement) {
String cssClasses = CssRules.getClassNamesForTag(styledElement.getName());
return cssClasses.length() == 0 ? styledElement : styledElement.setAttribute("class", cssClasses);
}
public void showTitles(Element divRoot, SectionBean sectionBean) {
// Don't create an Element if the Section does not have
// a title, subtitle, or instructions
if (divRoot == null || sectionBean.getInstructions().length() == 0 && sectionBean.getTitle().length() == 0 && sectionBean.getSubtitle().length() == 0) {
return;
}
Element table = new Element("table");
table.setAttribute("class", CssRules.getClassNamesForTag("table section"));
table.setAttribute("width", "100%");
divRoot.addContent(table);
if (sectionBean.getTitle().length() > 0) {
addTitles(sectionBean, table, "Title");
}
if (sectionBean.getSubtitle().length() > 0) {
addTitles(sectionBean, table, "Subtitle");
}
if (sectionBean.getInstructions().length() > 0) {
addTitles(sectionBean, table, "Instructions");
}
}
public void addTitles(SectionBean sbean, Element table, String content) {
Element tr = new Element("tr");
tr.setAttribute("class", "aka_stripes");
table.addContent(tr);
Element title = new Element("td");
title.setAttribute("nowrap", "nowrap");
title.setAttribute("class", "aka_table_cell_left");
Element bold = new Element("b");
bold.addContent(content + ": ");
title.addContent(bold);
if (content.equalsIgnoreCase("subtitle")) {
title.addContent(sbean.getSubtitle());
} else if (content.equalsIgnoreCase("title")) {
title.addContent(sbean.getTitle());
} else if (content.equalsIgnoreCase("instructions")) {
title.addContent(sbean.getInstructions());
}
tr.addContent(title);
}
/**
* Generate a List of HTML rows (tr tag) for a matrix type table that
* already has form-field values from the database. In other words, the user
* previously created repeating rows and filled them with some data.
*
* @param sortedDataMap
* A SortedMap where the indiex is the Item Data's ordinal (like
* "2"), and the value is a List of ItemDataBeans associated with
* that ordinal. These data make up the row's content.
* @param rowContentBeans
* The DisplayItemBeans that provide the HTML fields for the
* rows.
* @param tabIndex
* The incremented tab index for the form section.
* @param repeatParentId
* The String id for the input name fields. See the RepeatManager
* class.
* @param hasDiscrepancyMgt
* A boolean indicating whether the discrepancy note icon should
* be displayed.
* @param forPrinting
* A boolean value indicating whether CRF printing is involved
* (if true, then discrepancy note icons are not clickable).
* @param hasDarkBorders
* @return A List of row Elements, as in new Element("tr"); containing the
* previously generated repeating rows.
*/
public List<Element> generatePersistentMatrixRows(SortedMap<Integer, List<ItemDataBean>> sortedDataMap, List<DisplayItemBean> rowContentBeans,
int tabIndex, String repeatParentId,
boolean hasDiscrepancyMgt, boolean forPrinting,
boolean hasDarkBorders) {
List<Element> newRows = new ArrayList<Element>();
List<ItemDataBean> tempList;
Element tr;
Element td;
CellFactory cellFactory = new CellFactory();
RepeatManager repeatManager = new RepeatManager();
String responseName;
boolean repeatFlag = true; // for now...
String forcedParentId = "";
// for each repeated row of the matrix table..
for (Integer ordinal : sortedDataMap.keySet()) {
tr = new Element("tr");
tempList = sortedDataMap.get(ordinal);
forcedParentId = ordinal - 1 + "";
for (DisplayItemBean disItemBean : rowContentBeans) {
for (ItemDataBean itemDBean : tempList) {
if (disItemBean.getItem().getId() == itemDBean.getItemId()) {
disItemBean.setData(itemDBean);
break;
}
}
responseName = disItemBean.getMetadata().getResponseSet().getResponseType().getName();
// start horiz
if (disItemBean.getMetadata().getResponseLayout().equalsIgnoreCase("horizontal")
&& (responseName.equalsIgnoreCase("checkbox") || responseName.equalsIgnoreCase("radio"))) {
// The final true parameter styfles the display of default
// values in CRFs (because
// default values do not appear in forms that have db values
Element[] elements =
cellFactory.createCellContentsForChecks(responseName, disItemBean, disItemBean.getMetadata().getResponseSet().getOptions().size(),
++tabIndex, true, forPrinting);
for (Element el : elements) {
if(hasDarkBorders){
String cssClasses = CssRules.getClassNamesForTag("td borders_on");
el.setAttribute("class",cssClasses);
} else {
el = this.setClassNames(el);
}
if (repeatFlag) {
el = repeatManager.addChildRepeatAttributes(el, repeatParentId, disItemBean.getItem().getId(), forcedParentId);
}
tr.addContent(el);
}
// move to the next item
continue;
}
// end
td = new Element("td");
if(hasDarkBorders){
String cssClasses = CssRules.getClassNamesForTag("td borders_on");
td.setAttribute("class",cssClasses);
} else {
td = this.setClassNames(td);
}
td = cellFactory.createCellContents(td, responseName, disItemBean, ++tabIndex, hasDiscrepancyMgt, true, forPrinting);
// In this case, the parent id looks like parentId_1, etc.
td = repeatManager.addChildRepeatAttributes(td, repeatParentId, disItemBean.getItem().getId(), forcedParentId);
tr.addContent(td);
}
this.addRemoveRowControl(tr, repeatParentId, hasDarkBorders);
newRows.add(tr);
}
return newRows;
}
public List generatePersistentMatrixRowsNew(SortedMap<Integer, List<ItemDataBean>> sortedDataMap, List<DisplayItemBean> rowContentBeans,
int tabIndex, String repeatParentId,
boolean hasDiscrepancyMgt, boolean forPrinting,
boolean hasDarkBorders, int maxColRows) {
List newRows = new ArrayList();
List<ItemDataBean> tempList;
Element tr;
Element td;
CellFactory cellFactory = new CellFactory();
RepeatManager repeatManager = new RepeatManager();
String responseName;
boolean repeatFlag = true; // for now...
String forcedParentId = "";
// for each repeated row of the matrix table..
for (Integer ordinal : sortedDataMap.keySet()) {
List<Element> rowList = new ArrayList();
tr = new Element("tr");
tempList = sortedDataMap.get(ordinal);
forcedParentId = ordinal - 1 + "";
int count = 0;
for (DisplayItemBean disItemBean : rowContentBeans) {
count++;
for (ItemDataBean itemDBean : tempList) {
if (disItemBean.getItem().getId() == itemDBean.getItemId()) {
disItemBean.setData(itemDBean);
break;
}
}
responseName = disItemBean.getMetadata().getResponseSet().getResponseType().getName();
if ((responseName.equalsIgnoreCase("radio")
|| responseName.equalsIgnoreCase("multi-select")
|| responseName.equalsIgnoreCase("single-select")
|| responseName.equalsIgnoreCase("checkbox")) && forPrinting) {
responseName = "checkbox";
}
// start horiz
if (disItemBean.getMetadata().getResponseLayout().equalsIgnoreCase("horizontal")
&& (responseName.equalsIgnoreCase("checkbox") || responseName.equalsIgnoreCase("radio"))) {
// The final true parameter styfles the display of default
// values in CRFs (because
// default values do not appear in forms that have db values
Element[] elements =
cellFactory.createCellContentsForChecks(responseName, disItemBean, disItemBean.getMetadata().getResponseSet().getOptions().size(),
++tabIndex, true, forPrinting);
for (Element el : elements) {
if(hasDarkBorders){
String cssClasses = CssRules.getClassNamesForTag("td borders_on");
el.setAttribute("class",cssClasses);
} else {
el = this.setClassNames(el);
}
if (repeatFlag) {
el = repeatManager.addChildRepeatAttributes(el, repeatParentId, disItemBean.getItem().getId(), forcedParentId);
}
tr.addContent(el);
if(count%maxColRows==0){
rowList.add(tr);
tr = new Element("tr");
}
}
// move to the next item
continue;
}
// end
td = new Element("td");
if(hasDarkBorders){
String cssClasses = CssRules.getClassNamesForTag("td borders_on");
td.setAttribute("class",cssClasses);
} else {
td = this.setClassNames(td);
}
td = cellFactory.createCellContents(td, responseName, disItemBean, ++tabIndex, hasDiscrepancyMgt, true, forPrinting);
// In this case, the parent id looks like parentId_1, etc.
td = repeatManager.addChildRepeatAttributes(td, repeatParentId, disItemBean.getItem().getId(), forcedParentId);
tr.addContent(td);
if(count%maxColRows==0){
rowList.add(tr);
tr = new Element("tr");
}
}
if(count%maxColRows!=0)rowList.add(tr);
newRows.add(rowList);
}
return newRows;
}
}