package net.sf.egonet.web.panel; import java.util.ArrayList; import java.util.List; import org.apache.wicket.behavior.SimpleAttributeModifier; import org.apache.wicket.markup.html.form.Radio; import org.apache.wicket.markup.html.form.RadioGroup; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import com.google.common.collect.Lists; import net.sf.egonet.model.Alter; import net.sf.egonet.model.Answer; import net.sf.egonet.model.Question; import net.sf.egonet.model.QuestionOption; import net.sf.egonet.persistence.Options; import net.sf.egonet.web.component.FocusOnLoadBehavior; public class SelectionAnswerFormFieldPanel extends AnswerFormFieldPanel { /** * private inner class extending RadioChoice * This is so it can implement IOnChangeListener and, * in effect, list to itself and show the 'other specify' * text input box */ private class RadioChoicePlus extends RadioGroup { public RadioChoicePlus (String id, Model model) { super(id, model); } protected void onSelectionChanged(Object newSelection) { if(newSelection != null) { String strNewSelection; if ( newSelection instanceof String ) { strNewSelection = (String)newSelection; } else if ( newSelection instanceof QuestionOption ) { strNewSelection = ((QuestionOption)newSelection).getName(); } else { strNewSelection = newSelection.toString(); } if (strNewSelection.trim().startsWith(otherSpecify)) { otherSpecifyLabel.setVisible(true); otherSpecifyTextField.setVisible(true); } else { setNotification(""); otherSpecifyLabel.setVisible(false); otherSpecifyTextField.setVisible(false); } } } protected boolean wantOnSelectionChangedNotifications() { return (otherSpecifyStyle);} } /** * end of private inner class RadioChoicePlus */ private static final String otherSpecify = "OTHER SPECIFY"; private Model answer; private RadioChoicePlus dropDownChoice; private Label otherSpecifyLabel; private TextField otherSpecifyTextField; private String otherSpecifyText; private boolean otherSpecifyStyle; public SelectionAnswerFormFieldPanel(String id, Question question, ArrayList<Alter> alters, Long interviewId) { super(id,question,Answer.SkipReason.NONE,alters, interviewId); this.answer = new Model(); otherSpecifyText = ""; build(); setFirstTimeOnQuestion(true); } public SelectionAnswerFormFieldPanel(String id, Question question, String answer, String otherSpecAnswer, Answer.SkipReason skipReason, ArrayList<Alter> alters, Long interviewId) { super(id,question,skipReason,alters,interviewId); this.answer = new Model(); otherSpecifyText = otherSpecAnswer; if(skipReason.equals(Answer.SkipReason.DONT_KNOW)) { this.answer = new Model(dontKnow); } else if(skipReason.equals(Answer.SkipReason.REFUSE)) { this.answer = new Model(refuse); } else { try { Long optionId = Long.parseLong(answer); for(QuestionOption option : getOptions()) { if(option.getId().equals(optionId)) { this.answer = new Model(option); } } } catch(Exception ex) { // Most likely failed to parse answer. Fall back to no existing answer. } } build(); } private void build() { List<Object> choices = Lists.newArrayList(); choices.addAll(getOptions()); if ( !question.getType().equals(Question.QuestionType.EGO_ID)) { if ( question.getDontKnowButton()) choices.add(dontKnow); if ( question.getRefuseButton()) choices.add(refuse); } dropDownChoice = new RadioChoicePlus("answer",answer); ListView options = new ListView("options",choices) { protected void populateItem(ListItem item) { Object obj = item.getModelObject(); QuestionOption option = obj instanceof QuestionOption ? (QuestionOption) obj : null; String string = obj instanceof String ? (String) obj : null; Radio radio = new Radio("optionInput",item.getModel()); Label label = new Label("optionLabel", option != null ? option.getName() : string); String hotkey = null; if(option != null) { try { Integer intVal = Integer.parseInt(option.getValue()); if(intVal > -1 && intVal < 10) { hotkey = intVal+""; } } catch(Exception ex) { } } if(string != null) { if(string.equals(dontKnow)) { hotkey = "F8"; } if(string.equals(refuse)) { hotkey = "F9"; } } if(hotkey != null) { radio.add(new SimpleAttributeModifier("hotkey",hotkey)); label.add(new SimpleAttributeModifier("hotkey",hotkey)); } item.add(radio); item.add(label); } }; options.setReuseItems(true); dropDownChoice.add(options); add(dropDownChoice); // features that will be visible only for // 'other/specify' questions otherSpecifyStyle = question.getOtherSpecify(); otherSpecifyLabel = new Label("otherSpecifyLabel", "Specify Other: "); otherSpecifyTextField = new TextField("otherSpecifyTextField", new PropertyModel(this, "otherSpecifyText")); add(otherSpecifyLabel); add(otherSpecifyTextField); otherSpecifyLabel.setOutputMarkupId(true); otherSpecifyTextField.setOutputMarkupId(true); if ( otherSpecifyStyle && answerContainsOTHERSPECIFY()) { otherSpecifyLabel.setVisible(true); otherSpecifyTextField.setVisible(true); } else { otherSpecifyLabel.setVisible(false); otherSpecifyTextField.setVisible(false); } } public String getAnswer() { Object selected = answer.getObject(); return selected != null && selected instanceof QuestionOption ? ((QuestionOption) selected).getId().toString() : null; } public List<QuestionOption> getOptions() { return Options.getOptionsForQuestion(getQuestion().getId()); } public void setAutoFocus() { dropDownChoice.add(new FocusOnLoadBehavior()); } @Override public boolean dontKnow() { return answer.getObject() != null && answer.getObject().equals(dontKnow); } @Override public boolean refused() { return answer.getObject() != null && answer.getObject().equals(refuse); } private String getAnswerOptionName() { Object selected = answer.getObject(); return selected != null && selected instanceof QuestionOption ? ((QuestionOption) selected).getName() : null; } /** * returns the string used if an incorrect number of checkboxes * are selected to prompt the user to check more or fewer */ public String getRangeCheckNotification() { String strNotification = ""; if ( dontKnow() || refused()) return(strNotification); if ( otherSpecifyStyle && otherSpecifyTextField.isVisible() && ( otherSpecifyText==null || otherSpecifyText.length()==0 )) strNotification = "Specify Other blank"; return(strNotification); } /** * if the user selected dontKnow or refused to answer a question * don't bother counting the responses. */ public boolean rangeCheckOkay() { boolean bOkay = true; if ( dontKnow() || refused()) return (bOkay); if ( otherSpecifyStyle && otherSpecifyTextField.isVisible() && ( otherSpecifyText==null || otherSpecifyText.length()==0 )) bOkay = false; return(bOkay); } /** * checks to see if the answer from a previous use * of this question starts with the string OTHER SPECIFY * @return true if a saved answer starts with OTHER SPECIFY */ private boolean answerContainsOTHERSPECIFY() { String strAnswerName = getAnswerOptionName(); boolean retVal = false; if ( strAnswerName!=null && strAnswerName.trim().startsWith(otherSpecify)) retVal = true; return(retVal); } public void setOtherText ( String otherSpecifyText ) { this.otherSpecifyText = (otherSpecifyText==null) ? "" : otherSpecifyText; } public String getOtherText() { return (( otherSpecifyText==null) ? "" : otherSpecifyText ) ; } /** * returns true if strAnswerToCount the answer * that has been checked. This will be used an a * list-of-alters format question to count how many times * a specific answer has been selected * @param strAnswerToCount the answer we'll count up the number * of times its been used * @return true if the answer if selected in this panel */ public boolean isSelected ( String strAnswerToCount ) { String selectedAnswer; strAnswerToCount = strAnswerToCount.trim(); selectedAnswer = getAnswerOptionName(); if (selectedAnswer != null) { selectedAnswer = selectedAnswer.trim(); if ( selectedAnswer.equalsIgnoreCase(strAnswerToCount)) return (true); } return (false); } }