1/** 2 * @file 3 * JavaScript behaviors for range element integration. 4 */ 5 6(function ($, Drupal) { 7 8 'use strict'; 9 10 /** 11 * Display HTML5 range output in a left/right aligned number input. 12 * 13 * @type {Drupal~behavior} 14 */ 15 Drupal.behaviors.webformRangeOutputNumber = { 16 attach: function (context) { 17 $(context).find('.js-form-type-range').once('webform-range-output-number').each(function () { 18 // Handle browser that don't support the HTML5 range input. 19 if (Modernizr.inputtypes.range === false) { 20 return; 21 } 22 23 var $element = $(this); 24 var $input = $element.find('input[type="range"]'); 25 var $output = $element.find('input[type="number"]'); 26 if (!$output.length) { 27 return; 28 } 29 30 // Set output value. 31 $output.val($input.val()); 32 33 // Sync input and output values. 34 $input.on('change input', function () { 35 $output.val($input.val()); 36 }); 37 $output.on('change input', function () { 38 $input.val($output.val()); 39 }); 40 }); 41 } 42 }; 43 44 /** 45 * Display HTML5 range output in a floating bubble. 46 * 47 * @type {Drupal~behavior} 48 * 49 * @see https://css-tricks.com/value-bubbles-for-range-inputs/ 50 * @see https://stackoverflow.com/questions/33794123/absolute-positioning-in-relation-to-a-inputtype-range 51 */ 52 Drupal.behaviors.webformRangeOutputBubble = { 53 attach: function (context) { 54 $(context).find('.js-form-type-range').once('webform-range-output-bubble').each(function () { 55 // Handle browser that don't support the HTML5 range input. 56 if (Modernizr.inputtypes.range === false) { 57 return; 58 } 59 60 var $element = $(this); 61 var $input = $element.find('input[type="range"]'); 62 var $output = $element.find('output'); 63 var display = $output.attr('data-display'); 64 65 if (!$output.length) { 66 return; 67 } 68 69 $element.css('position', 'relative'); 70 71 $input.on('change input', function () { 72 var inputValue = $input.val(); 73 74 // Set output text with prefix and suffix. 75 var text = ($output.attr('data-field-prefix') || '') + 76 inputValue + 77 ($output.attr('data-field-suffix') || ''); 78 $output.text(text); 79 80 // Set output top position. 81 var top; 82 if (display === 'above') { 83 top = $input.position().top - $output.outerHeight() + 2; 84 } 85 else { 86 top = $input.position().top + $input.outerHeight() + 2; 87 } 88 89 // It is impossible to accurately calculate the exact position of the 90 // range's buttons so we only incrementally move the output bubble. 91 var inputWidth = $input.outerWidth(); 92 var buttonPosition = Math.floor(inputWidth * (inputValue - $input.attr('min')) / ($input.attr('max') - $input.attr('min'))); 93 var increment = Math.floor(inputWidth / 5); 94 var outputWidth = $output.outerWidth(); 95 96 // Set output left position. 97 var left; 98 if (buttonPosition <= increment) { 99 left = 0; 100 } 101 else if (buttonPosition <= increment * 2) { 102 left = (increment * 1.5) - outputWidth; 103 if (left < 0) { 104 left = 0; 105 } 106 } 107 else if (buttonPosition <= increment * 3) { 108 left = (increment * 2.5) - (outputWidth / 2); 109 110 } 111 else if (buttonPosition <= increment * 4) { 112 left = (increment * 4) - outputWidth; 113 if (left > (increment * 5) - outputWidth) { 114 left = (increment * 5) - outputWidth; 115 } 116 } 117 else if (buttonPosition <= inputWidth) { 118 left = (increment * 5) - outputWidth; 119 } 120 // Also make sure to include the input's left position. 121 left = Math.floor($input.position().left + left); 122 123 // Finally, position the output. 124 $output.css({top: top, left: left}); 125 }) 126 // Fake a change to position output at page load. 127 .trigger('input'); 128 129 // Add fade in/out event handlers if opacity is defined. 130 var defaultOpacity = $output.css('opacity'); 131 if (defaultOpacity < 1) { 132 // Fade in/out on focus/blur of the input. 133 $input.on('focus mouseover', function () { 134 $output.stop().fadeTo('slow', 1); 135 }); 136 $input.on('blur mouseout', function () { 137 $output.stop().fadeTo('slow', defaultOpacity); 138 });
139 // Also fade in when focusing the output. 140 $output.on('touchstart mouseover', function () { 141 $output.stop().fadeTo('slow', 1); 142 }); 143 } 144 }); 145 } 146 }; 147 148})(jQuery, Drupal);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.