app/views/shared/metadata/_related_fields.html.erb
<%= legacy_javascript_tag do %>
jQuery(function() {
(function(undefined) {
var hideSectionAndDisableInputs = function(elements) {
// disable inputs when hidden so they don't fire validation
elements.each(function() {
jQuery(this).hide().find('input').attr('disabled','disabled');
});
};
var showSectionAndEnableInputsIfVisible = function(elements) {
elements.each(function() {
jQuery(this).show();
jQuery(this).find('input').each(function() {
// only enable input if it's not hidden - could be beneath a hidden element in the DOM
if(!jQuery(this).is(':visible')) return;
jQuery(this).attr('disabled', null);
});
});
};
var valueFrom = function(element) {
if (element === null) { return null }
var value = element.value.toLowerCase().replace(/[^a-z0-9]+/, '_');
return (value.length == 0) ? 'blank' : value;
};
var selectRelatedByFieldAndValue = function(fieldName, value) {
return jQuery('.related_to.' + fieldName + '.' + value);
};
var getElementByFieldName = function(fieldName) {
return document.getElementById('<%= root %>_' + fieldName) ||
jQuery("input[name='study[study_metadata_attributes]["+fieldName+"]']:checked")[0] ||
document.getElementById('<%= root %>_' + fieldName + '_id');
};
rerenderFieldsRelatedToControllingField = function(fieldName, controllingField) {
var relatedToDivs = jQuery('.related_to.' + fieldName);
hideSectionAndDisableInputs(relatedToDivs);
var relatedWithRelevantValue = selectRelatedByFieldAndValue(fieldName, valueFrom(controllingField));
showSectionAndEnableInputsIfVisible(relatedWithRelevantValue);
};
addOnChangeHandler = function(fieldName) {
controllingFieldSelector = '[id=<%= root %>_' + fieldName + '],[id=<%= root %>_' + fieldName + '_id],[name=\'study[study_metadata_attributes]['+fieldName+']\']';
jQuery('body').delegate(controllingFieldSelector, 'change', function() {
controllingField = this;
rerenderFieldsRelatedToControllingField(fieldName, controllingField);
});
}
initialize = function() {
<% related.each do |field| %>
var fieldName = "<%= field.to_s %>";
var controllingField = getElementByFieldName(fieldName);
rerenderFieldsRelatedToControllingField(fieldName, controllingField);
addOnChangeHandler(fieldName);
<% end %>
}
initialize();
})();
});
(function($, undefined) {
<% changing_fields.reverse.each do |field, options| %>
attach_option_updater("<%= field.to_s %>", "<%= options[:when].to_s %>", {<%= options[:values].map { |k,v| "#{k.inspect}:#{v.inspect}" }.join(',').html_safe %>});
<% end %>
function attach_option_updater(target, source, values) {
// selector uses 'start with id' rather than 'equals id' to include radio buttons, where ids have the value appended
var selector = '[id^=' + '<%= root %>_' + source + ']';
var sourceFields = $(selector);
var isRadioButton = sourceFields.attr('type') == 'radio';
sourceFields.change(function() {
select_to_change_options_in = $('#<%= root %>_' + target);
selected_option = select_to_change_options_in.val();
options = values[this.value].map(function(value) { return '<option value="' + value + '">' + value + '</option>'; });
select_to_change_options_in.html(options.join('')).val(selected_option);
select_to_change_options_in.trigger('change');
});
// trigger change on load (for radio buttons, only if it's selected)
sourceFields.each(function() {
var isSelected = $(this).attr('checked') == 'checked';
if(!isRadioButton || (isRadioButton && isSelected)) {
$(this).trigger('change');
}
});
};
})(jQuery);
<% end %>