diff --git a/src/__tests__/extensions/surveys.js b/src/__tests__/extensions/surveys.js index 4d8a24246..06c69ba44 100644 --- a/src/__tests__/extensions/surveys.js +++ b/src/__tests__/extensions/surveys.js @@ -279,4 +279,103 @@ describe('survey display logic', () => { expect(ratingQuestion2.querySelectorAll('.question-0-rating-0').length).toBe(0) expect(ratingQuestion2.querySelectorAll('.question-0-rating-1').length).toBe(1) }) + + test('open choice value on a multiple choice question is determined by a text input', () => { + mockSurveys = [ + { + id: 'testSurvey2', + name: 'Test survey 2', + appearance: null, + questions: [ + { + question: 'Which types of content would you like to see more of?', + description: 'This is a question description', + type: 'multiple_choice', + choices: ['Tutorials', 'Product Updates', 'Events', 'Other'], + hasOpenChoice: true, + }, + ], + }, + ] + const singleQuestionSurveyForm = createMultipleQuestionSurvey(mockPostHog, mockSurveys[0]) + + const checkboxInputs = singleQuestionSurveyForm + .querySelector('.tab.question-0') + .querySelectorAll('input[type=checkbox]') + let checkboxInputValues = [...checkboxInputs].map((input) => input.value) + expect(checkboxInputValues).toEqual(['Tutorials', 'Product Updates', 'Events', '']) + const openChoiceTextInput = singleQuestionSurveyForm + .querySelector('.tab.question-0') + .querySelector('input[type=text]') + openChoiceTextInput.value = 'NEW VALUE 1' + openChoiceTextInput.dispatchEvent(new Event('input')) + expect(singleQuestionSurveyForm.querySelector('.form-submit').disabled).toEqual(false) + checkboxInputValues = [...checkboxInputs].map((input) => input.value) + expect(checkboxInputValues).toEqual(['Tutorials', 'Product Updates', 'Events', 'NEW VALUE 1']) + checkboxInputs[0].click() + const checkboxInputsChecked = [...checkboxInputs].map((input) => input.checked) + expect(checkboxInputsChecked).toEqual([true, false, false, true]) + + singleQuestionSurveyForm.dispatchEvent(new Event('submit')) + expect(mockPostHog.capture).toBeCalledTimes(1) + expect(mockPostHog.capture).toBeCalledWith('survey sent', { + $survey_name: 'Test survey 2', + $survey_id: 'testSurvey2', + $survey_questions: ['Which types of content would you like to see more of?'], + $survey_response: ['Tutorials', 'NEW VALUE 1'], + sessionRecordingUrl: undefined, + $set: { + ['$survey_responded/testSurvey2']: true, + }, + }) + }) + + test('open choice value on a single choice question is determined by a text input', () => { + mockSurveys = [ + { + id: 'testSurvey2', + name: 'Test survey 2', + appearance: null, + questions: [ + { + question: 'Which features do you use the most?', + description: 'This is a question description', + type: 'single_choice', + choices: ['Surveys', 'Feature flags', 'Analytics', 'Another Feature'], + hasOpenChoice: true, + }, + ], + }, + ] + const singleQuestionSurveyForm = createMultipleQuestionSurvey(mockPostHog, mockSurveys[0]) + + const radioInputs = singleQuestionSurveyForm + .querySelector('.tab.question-0') + .querySelectorAll('input[type=radio]') + let radioInputValues = [...radioInputs].map((input) => input.value) + expect(radioInputValues).toEqual(['Surveys', 'Feature flags', 'Analytics', '']) + const openChoiceTextInput = singleQuestionSurveyForm + .querySelector('.tab.question-0') + .querySelector('input[type=text]') + openChoiceTextInput.value = 'NEW VALUE 2' + openChoiceTextInput.dispatchEvent(new Event('input')) + expect(singleQuestionSurveyForm.querySelector('.form-submit').disabled).toEqual(false) + radioInputValues = [...radioInputs].map((input) => input.value) + expect(radioInputValues).toEqual(['Surveys', 'Feature flags', 'Analytics', 'NEW VALUE 2']) + const radioInputsChecked = [...radioInputs].map((input) => input.checked) + expect(radioInputsChecked).toEqual([false, false, false, true]) + + singleQuestionSurveyForm.dispatchEvent(new Event('submit')) + expect(mockPostHog.capture).toBeCalledTimes(1) + expect(mockPostHog.capture).toBeCalledWith('survey sent', { + $survey_name: 'Test survey 2', + $survey_id: 'testSurvey2', + $survey_questions: ['Which features do you use the most?'], + $survey_response: 'NEW VALUE 2', + sessionRecordingUrl: undefined, + $set: { + ['$survey_responded/testSurvey2']: true, + }, + }) + }) }) diff --git a/src/extensions/surveys.ts b/src/extensions/surveys.ts index 6cfab5d7c..409dc93ca 100644 --- a/src/extensions/surveys.ts +++ b/src/extensions/surveys.ts @@ -261,12 +261,13 @@ const style = (id: string, appearance: SurveyAppearance | null) => { display: inline-block; opacity: 100% !important; } - .multiple-choice-options input[type=checkbox]:checked + label { - font-weight: bold; - } .multiple-choice-options input:checked + label { + font-weight: bold; border: 1.5px solid rgba(0,0,0); } + .multiple-choice-options input:checked + label input { + font-weight: bold; + } .multiple-choice-options label { width: 100%; cursor: pointer; @@ -275,6 +276,26 @@ const style = (id: string, appearance: SurveyAppearance | null) => { border-radius: 4px; background: white; } + .multiple-choice-options .choice-option-open label { + padding-right: 30px; + display: flex; + flex-wrap: wrap; + gap: 8px; + max-width: 100%; + } + .multiple-choice-options .choice-option-open label span { + width: 100%; + } + .multiple-choice-options .choice-option-open input:disabled + label { + opacity: 0.6; + } + .multiple-choice-options .choice-option-open label input { + position: relative; + opacity: 1; + flex-grow: 1; + border: 0; + outline: 0; + } .thank-you-message { position: fixed; bottom: 0px; @@ -600,8 +621,9 @@ export const createMultipleChoicePopup = ( const surveyQuestion = question.question const surveyDescription = question.description const surveyQuestionChoices = question.choices - const singleOrMultiSelect = question.type + const isSingleChoice = question.type === 'single_choice' const isOptional = !!question.optional + const hasOpenChoice = !!question.hasOpenChoice const form = `