UNPKG

samagra-x-enketo-core

Version:

Extensible Enketo form engine

79 lines (64 loc) 3.13 kB
/** * @module output */ import $ from 'jquery'; export default { /** * Updates output values, optionally filtered by those values that contain a changed node name * * @param {UpdatedDataNodes} [updated] - The object containing info on updated data nodes. */ update( updated ) { const outputCache = {}; let val = ''; const that = this; if ( !this.form ) { throw new Error( 'Output module not correctly instantiated with form property.' ); } const $nodes = this.form.getRelatedNodes( 'data-value', '.or-output', updated ); const clonedRepeatsPresent = this.form.repeatsPresent && this.form.view.html.querySelector( '.or-repeat.clone' ); $nodes.each( function() { const $output = $( this ); const output = this; // nodes are in document order, so we discard any nodes in questions/groups that have a disabled parent if ( $output.closest( '.or-branch' ).parent().closest( '.disabled' ).length ) { return; } const expr = output.dataset.value; /* * Note that in XForms input is the parent of label and in HTML the other way around so an output inside a label * should look at the HTML input to determine the context. * So, context is either the input name attribute (if output is inside input label), * or the parent with a name attribute * or the whole document */ let context = output.closest( '.question, .or-group' ); if ( !context.matches( '.or-group' ) ) { context = context.querySelector( '[name]' ); } let contextPath = that.form.input.getName( context ); /* * If the output is part of a group label and that group contains repeats with the same name, * but currently has 0 repeats, the context will not be available. See issue 502. * This same logic is applied in branch.js. */ if ( $( context ).children( `.or-repeat-info[data-name="${contextPath}"]` ).length && !$( context ).children( `.or-repeat[name="${contextPath}"]` ).length ) { contextPath = null; } const insideRepeat = ( clonedRepeatsPresent && $output.parentsUntil( '.or', '.or-repeat' ).length > 0 ); const insideRepeatClone = ( insideRepeat && $output.parentsUntil( '.or', '.or-repeat.clone' ).length > 0 ); const index = ( insideRepeatClone && contextPath ) ? that.form.input.getIndex( context ) : 0; if ( typeof outputCache[ expr ] !== 'undefined' ) { val = outputCache[ expr ]; } else { val = that.form.model.evaluate( expr, 'string', contextPath, index, true ); if ( !insideRepeat ) { outputCache[ expr ] = val; } } if ( $output.text() !== val ) { $output.text( val ); } } ); } };