Search in sources :

Example 1 with QuestionOption

use of services.question.QuestionOption in project civiform by seattle-uat.

the class ProgramBlockPredicatesEditView method createValueField.

private ContainerTag createValueField(QuestionDefinition questionDefinition) {
    if (questionDefinition.getQuestionType().isMultiOptionType()) {
        // If it's a multi-option question, we need to provide a discrete list of possible values to
        // choose from instead of a freeform text field. Not only is it a better UX, but we store the
        // ID of the options rather than the display strings since the option display strings are
        // localized.
        ImmutableList<QuestionOption> options = ((MultiOptionQuestionDefinition) questionDefinition).getOptions();
        ContainerTag valueOptionsDiv = div().with(div("Values").withClasses(BaseStyles.CHECKBOX_GROUP_LABEL));
        for (QuestionOption option : options) {
            ContainerTag optionCheckbox = FieldWithLabel.checkbox().setFieldName("predicateValues[]").setValue(String.valueOf(option.id())).setLabelText(option.optionText().getDefault()).getContainer();
            valueOptionsDiv.with(optionCheckbox);
        }
        return valueOptionsDiv;
    } else {
        return div().with(FieldWithLabel.input().setFieldName("predicateValue").setLabelText("Value").addReferenceClass(ReferenceClasses.PREDICATE_VALUE_INPUT).getContainer()).with(div().withClasses(ReferenceClasses.PREDICATE_VALUE_COMMA_HELP_TEXT, Styles.HIDDEN, Styles.TEXT_XS, BaseStyles.FORM_LABEL_TEXT_COLOR).withText("Enter a list of comma-separated values. For example, \"v1,v2,v3\"."));
    }
}
Also used : QuestionOption(services.question.QuestionOption) MultiOptionQuestionDefinition(services.question.types.MultiOptionQuestionDefinition) ContainerTag(j2html.tags.ContainerTag)

Example 2 with QuestionOption

use of services.question.QuestionOption in project civiform by seattle-uat.

the class QuestionOptionTest method localizeOrDefault_returnsDefaultForUnsupportedLocale.

@Test
public void localizeOrDefault_returnsDefaultForUnsupportedLocale() {
    QuestionOption option = QuestionOption.create(1L, LocalizedStrings.of(Locale.US, "default"));
    assertThat(option.localizeOrDefault(Locale.CHINESE)).isEqualTo(LocalizedQuestionOption.create(1L, 1L, "default", Locale.US));
}
Also used : LocalizedQuestionOption(services.question.LocalizedQuestionOption) QuestionOption(services.question.QuestionOption) Test(org.junit.Test)

Example 3 with QuestionOption

use of services.question.QuestionOption in project civiform by seattle-uat.

the class Question method setQuestionOptions.

/**
 * Add {@link QuestionOption}s to the builder, taking into account legacy columns.
 *
 * <p>The majority of questions should have a `questionOptions` and not `legacyQuestionOptions`.
 */
private Question setQuestionOptions(QuestionDefinitionBuilder builder) throws InvalidQuestionTypeException {
    if (!QuestionType.of(questionType).isMultiOptionType()) {
        return this;
    }
    // `legacyQuestionOptions` is a legacy implementation that only supported a single locale.
    if (questionOptions != null) {
        builder.setQuestionOptions(questionOptions);
        return this;
    }
    // If the multi option question does have legacyQuestionOptions, we can assume there is only one
    // locale and convert the strings to QuestionOption instances each with a single locale.
    Locale firstKey = legacyQuestionOptions.keySet().stream().iterator().next();
    ImmutableList<QuestionOption> options = Streams.mapWithIndex(legacyQuestionOptions.get(firstKey).stream(), (optionText, i) -> QuestionOption.create(Long.valueOf(i), Long.valueOf(i), LocalizedStrings.of(firstKey, optionText))).collect(toImmutableList());
    builder.setQuestionOptions(options);
    return this;
}
Also used : Locale(java.util.Locale) PrePersist(javax.persistence.PrePersist) InvalidQuestionTypeException(services.question.exceptions.InvalidQuestionTypeException) EnumeratorQuestionDefinition(services.question.types.EnumeratorQuestionDefinition) QuestionOption(services.question.QuestionOption) ArrayList(java.util.ArrayList) Table(javax.persistence.Table) ImmutableList(com.google.common.collect.ImmutableList) DbArray(io.ebean.annotation.DbArray) MultiOptionQuestionDefinition(services.question.types.MultiOptionQuestionDefinition) DbJsonB(io.ebean.annotation.DbJsonB) Locale(java.util.Locale) PostLoad(javax.persistence.PostLoad) Constraints(play.data.validation.Constraints) ManyToMany(javax.persistence.ManyToMany) Entity(javax.persistence.Entity) JoinTable(javax.persistence.JoinTable) PreUpdate(javax.persistence.PreUpdate) ImmutableMap(com.google.common.collect.ImmutableMap) PostPersist(javax.persistence.PostPersist) QuestionType(services.question.types.QuestionType) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) UnsupportedQuestionTypeException(services.question.exceptions.UnsupportedQuestionTypeException) QuestionDefinition(services.question.types.QuestionDefinition) Streams(com.google.common.collect.Streams) QuestionDefinitionBuilder(services.question.types.QuestionDefinitionBuilder) List(java.util.List) LocalizedStrings(services.LocalizedStrings) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) Optional(java.util.Optional) PostUpdate(javax.persistence.PostUpdate) QuestionOption(services.question.QuestionOption)

Example 4 with QuestionOption

use of services.question.QuestionOption in project civiform by seattle-uat.

the class MultiOptionQuestionForm method getBuilder.

@Override
public QuestionDefinitionBuilder getBuilder() {
    MultiOptionQuestionDefinition.MultiOptionValidationPredicates.Builder predicateBuilder = MultiOptionQuestionDefinition.MultiOptionValidationPredicates.builder();
    if (getMinChoicesRequired().isPresent()) {
        predicateBuilder.setMinChoicesRequired(getMinChoicesRequired());
    }
    if (getMaxChoicesAllowed().isPresent()) {
        predicateBuilder.setMaxChoicesAllowed(getMaxChoicesAllowed());
    }
    ImmutableList.Builder<QuestionOption> questionOptionsBuilder = ImmutableList.builder();
    Preconditions.checkState(this.optionIds.size() == this.options.size(), "Option ids and options are not the same size.");
    // Note: the question edit form only sets or updates the default locale.
    for (int i = 0; i < options.size(); i++) {
        questionOptionsBuilder.add(QuestionOption.create(optionIds.get(i), i, LocalizedStrings.withDefaultValue(options.get(i))));
    }
    // The IDs are not guaranteed to be in any type of order, so doing this ensures that we find
    // the largest ID in the list and accurately set the next largest.
    Long maxId = optionIds.stream().max(Long::compareTo).orElse(-1L);
    setNextAvailableId(maxId + 1);
    for (int i = 0; i < newOptions.size(); i++) {
        questionOptionsBuilder.add(QuestionOption.create(nextAvailableId.getAsLong() + i, options.size() + i, LocalizedStrings.withDefaultValue(newOptions.get(i))));
    }
    ImmutableList<QuestionOption> questionOptions = questionOptionsBuilder.build();
    // Sets the next available ID as the previous ID + the size of new options, since each new
    // option ID is assigned in order.
    setNextAvailableId(nextAvailableId.getAsLong() + newOptions.size());
    return super.getBuilder().setQuestionOptions(questionOptions).setValidationPredicates(predicateBuilder.build());
}
Also used : LocalizedQuestionOption(services.question.LocalizedQuestionOption) QuestionOption(services.question.QuestionOption) ImmutableList(com.google.common.collect.ImmutableList) OptionalLong(java.util.OptionalLong)

Example 5 with QuestionOption

use of services.question.QuestionOption in project civiform by seattle-uat.

the class AdminQuestionController method updateDefaultLocalizationForOptions.

/**
 * Update the default locale text only for a multi-option question's option text.
 */
private void updateDefaultLocalizationForOptions(QuestionDefinitionBuilder updated, MultiOptionQuestionDefinition existing, ImmutableList<QuestionOption> updatedOptions) {
    ImmutableMap<String, QuestionOption> existingTranslations = existing.getOptions().stream().collect(toImmutableMap(o -> o.optionText().getDefault(), o -> o));
    // If there are existing translations for an unchanged default locale string, keep those
    // translations. If we do not have existing translations for a given string, create
    // a new, empty set of translations.
    ImmutableList.Builder<QuestionOption> updatedOptionsBuilder = ImmutableList.builder();
    for (QuestionOption updatedOption : updatedOptions) {
        if (existingTranslations.containsKey(updatedOption.optionText().getDefault()) && existingTranslations.get(updatedOption.optionText().getDefault()).id() == updatedOption.id()) {
            QuestionOption existingOption = existingTranslations.get(updatedOption.optionText().getDefault());
            updatedOptionsBuilder.add(existingOption.toBuilder().setId(updatedOption.id()).setDisplayOrder(updatedOption.displayOrder()).build());
        } else {
            updatedOptionsBuilder.add(updatedOption);
        }
    }
    updated.setQuestionOptions(updatedOptionsBuilder.build());
}
Also used : InvalidQuestionTypeException(services.question.exceptions.InvalidQuestionTypeException) Arrays(java.util.Arrays) EnumeratorQuestionDefinition(services.question.types.EnumeratorQuestionDefinition) CiviFormError(services.CiviFormError) ErrorAnd(services.ErrorAnd) QuestionOption(services.question.QuestionOption) QuestionFormBuilder(forms.QuestionFormBuilder) Inject(javax.inject.Inject) QuestionNotFoundException(services.question.exceptions.QuestionNotFoundException) ImmutableList(com.google.common.collect.ImmutableList) MultiOptionQuestionDefinition(services.question.types.MultiOptionQuestionDefinition) QuestionEditView(views.admin.questions.QuestionEditView) CiviFormController(controllers.CiviFormController) MultiOptionQuestionForm(forms.MultiOptionQuestionForm) Secure(org.pac4j.play.java.Secure) QuestionForm(forms.QuestionForm) QuestionService(services.question.QuestionService) Request(play.mvc.Http.Request) ImmutableMap(com.google.common.collect.ImmutableMap) QuestionType(services.question.types.QuestionType) QuestionsListView(views.admin.questions.QuestionsListView) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) UnsupportedQuestionTypeException(services.question.exceptions.UnsupportedQuestionTypeException) QuestionDefinition(services.question.types.QuestionDefinition) Authorizers(auth.Authorizers) InvalidUpdateException(services.question.exceptions.InvalidUpdateException) Result(play.mvc.Result) QuestionDefinitionBuilder(services.question.types.QuestionDefinitionBuilder) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) CompletionStage(java.util.concurrent.CompletionStage) HttpExecutionContext(play.libs.concurrent.HttpExecutionContext) LocalizedStrings(services.LocalizedStrings) EnumeratorQuestionForm(forms.EnumeratorQuestionForm) Optional(java.util.Optional) ReadOnlyQuestionService(services.question.ReadOnlyQuestionService) FormFactory(play.data.FormFactory) QuestionOption(services.question.QuestionOption) ImmutableList(com.google.common.collect.ImmutableList)

Aggregations

QuestionOption (services.question.QuestionOption)10 MultiOptionQuestionDefinition (services.question.types.MultiOptionQuestionDefinition)5 ImmutableList (com.google.common.collect.ImmutableList)4 Test (org.junit.Test)4 LocalizedStrings (services.LocalizedStrings)4 LocalizedQuestionOption (services.question.LocalizedQuestionOption)4 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)3 Optional (java.util.Optional)3 QuestionDefinition (services.question.types.QuestionDefinition)3 QuestionDefinitionBuilder (services.question.types.QuestionDefinitionBuilder)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 Locale (java.util.Locale)2 OptionalLong (java.util.OptionalLong)2 Result (play.mvc.Result)2 CiviFormError (services.CiviFormError)2 Authorizers (auth.Authorizers)1 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 SerializationFeature (com.fasterxml.jackson.databind.SerializationFeature)1 GuavaModule (com.fasterxml.jackson.datatype.guava.GuavaModule)1