After our comment,s I think I have things working the way you want. No changes to HTML, but the JQuery I used is as follows:
$(function() {
$('#survey_page').on('change',
'.parent_question select, .parent_question input',
function() {
console.log($(this).attr('name') + " selected: " + $(this).val());
var child_input = $('[name="' + $(this).data('child-name') + '"]');
//console.log(child_input);
var child_question = child_input.closest('.survey_answers');
var trigger_on = $(this).data('trigger-on');
var show = $(this)[0].selectedIndex == undefined ? ($(this).closest('.survey_answers').find('input').index($(this)) + 1) == trigger_on : $(this)[0].selectedIndex == trigger_on;
console.log("Show child (" + $(this).data('child-name') + "): " + show);
if (show) {
child_question.show();
} else {
child_question.hide();
child_input.val('');
child_input.attr('checked', false);
console.log(child_input);
if (child_input.is("textarea")) {
console.log("Next item is textarea, triggering change.");
child_input.trigger('change');
}
}
});
});
Here is a working example: https://jsfiddle.net/Twisty/16tw7q3j/4/
If the users selects specific answers, conditionally, more questions are exposed. If the users goes back and changes an answer, it should reset the conditions on children item.
I moved the change
event away from the body
to #survey_page
, yet either should work. I also conditionally trigger change if the child input is textarea
, which I think helps prevent looping. Feel free to test and comment if it's not working as you wanted. Not sure if my test Fiddle matches your environment exactly.
Update
This might be overkill at the moment, but it works: https://jsfiddle.net/Twisty/16tw7q3j/9/
$(function() {
$('body').on('change', '.parent_question select, .parent_question input', function() {
var current_input_name = $(this).prop('name');
var current_input_id = parseInt(current_input_name.substring(24, 26));
var last_input_name = $(".parent_question:last [name^='survey[answers]']").prop('name');
var last_input_id = parseInt(last_input_name.substring(24, 26));
console.log("Change " + current_input_name + "/" + last_input_name + ", " + current_input_id + "/" + last_input_id);
var child_input = $('[name="' + $(this).data('child-name') + '"]');
var child_question = child_input.closest('.survey_answers');
var trigger_on = $(this).data('trigger-on');
var show = $(this)[0].selectedIndex == undefined ? ($(this).closest('.survey_answers').find('input').index($(this)) + 1) == trigger_on : $(this)[0].selectedIndex == trigger_on;
if (show) {
child_question.show();
} else {
child_question.hide();
child_input.val('');
child_input.prop('checked', false);
}
for (var i = current_input_id + 2; i <= last_input_id; i++) {
console.log("Clearing survey[answers][question" + i + "]");
var nextElem = $("[name='survey[answers][question" + i + "]']");
nextElem.parents("div.survey_answers").hide();
nextElem.val('');
nextElem.prop('checked', false);
}
});
});
I create the scope between the current changed element, skip the child, since that is handled conditionally already, and clear out all the other selections.