Ask the community, share ideas, and connect with other LimeSurvey users!
<div style="text-align: center;"> <span style="font-size:20px;"><strong>
<audio controls="" preload="auto" style="width:100%"> <source src="EXTERNAL_URL_TO_MP3_AUDIO_SAMPLE" type="audio/mpeg" /></audio>
</strong></span></div>
Therefore you have to use<p><a href="<a href=" www.myserver.de/lime6/index.php/772936?token=111&lang=de "> www.myserver.de/lime6/
{% if (aSurveyInfo.showsurveypolicynotice == 1) %} {{include('./subviews/privacy/privacy_text.twig')}} {% elseif (aSurveyInfo.showsurveypolicynotice == 2) %} {{include( './subviews/privacy/privacy_modal.twig')}} {% endif %}
[code]{% include 'sidebar.html.twig' ignore missing %}
<!-- Button for starting the recording --><button id="startBtn" style="background-color: green; color: white;" type="button">Click here to use your microphone to answer</button> <!-- Modal HTML --></p> <div id="countdownModal" style="display:none; position:fixed; left:0; top:0; width:100vw; height:100vh; background:rgba(0,0,0,0.5); z-index:1050; align-items:center; justify-content:center;"> <div style="background:white; padding:30px; border-radius:10px; text-align:center; min-width: 240px;"> <h2>Get Ready!</h2> <p>Starting in <span id="countdownValue">3</span>...</p> </div> </div> <script> $(document).ready(function() { const startButton = $('#startBtn'); const answerTextarea = $('#answer947655X225X9377'); const modal = $('#countdownModal'); const countdownEl = $('#countdownValue'); let startedOnce = false; let isRecording = false; let lastManualValue = ""; // Keeps manual edits and previous result let recognitionActiveSessionTranscript = ""; // Keeps what is added in the present session if ("webkitSpeechRecognition" in window) { const recognition = new webkitSpeechRecognition(); recognition.continuous = true; recognition.interimResults = true; recognition.lang = "en-US"; let interimTranscript = ""; let pauseTimeout; // Helper: Capitalize after punctuation const capitalizeAfterPunctuation = (text) => { return text.replace(/(?:^|\. )(\w)/g, (match, p1) => match.replace(p1, p1.toUpperCase())); }; // Handle user edits answerTextarea.on('input propertychange', function(){ if (!isRecording) { lastManualValue = answerTextarea.val(); } }); // Start speech recognition and sync with edits const startRecognition = () => { // Always take the CURRENT textarea contents as base lastManualValue = answerTextarea.val(); recognitionActiveSessionTranscript = ""; recognition.start(); }; const stopRecognition = () => { recognition.stop(); }; recognition.onstart = () => { isRecording = true; startButton.text("Stop and edit my answer").css({ "background-color": "red", "color": "white" }); }; recognition.onend = () => { isRecording = false; // Update manual value in case user typed something after last pause lastManualValue = answerTextarea.val(); startButton.text("Resume recording").css({ "background-color": "green", "color": "white" }); clearTimeout(pauseTimeout); }; recognition.onresult = (event) => { interimTranscript = ""; clearTimeout(pauseTimeout); for (let i = event.resultIndex; i < event.results.length; i++) { const transcript = event.results[i][0].transcript; if (event.results[i].isFinal) { recognitionActiveSessionTranscript += transcript; } else { interimTranscript += transcript; } } // Compose up-to-date value: always prepend latest manual edits! let finalText = lastManualValue + (recognitionActiveSessionTranscript ? " " + capitalizeAfterPunctuation(recognitionActiveSessionTranscript.trim()) : "") + (interimTranscript ? " " + interimTranscript : ""); answerTextarea.val(finalText.trim()); // After a pause: finalize what's been heard pauseTimeout = setTimeout(() => { recognitionActiveSessionTranscript = recognitionActiveSessionTranscript.trim() + ". "; recognitionActiveSessionTranscript = capitalizeAfterPunctuation(recognitionActiveSessionTranscript); let finalVal = lastManualValue + (recognitionActiveSessionTranscript ? " " + recognitionActiveSessionTranscript.trim() : ""); answerTextarea.val(finalVal.trim()); }, 1000); }; // Modal logic function showCountdownModal(seconds, callback) { countdownEl.text(seconds); modal.css('display', 'flex'); let left = seconds; const countdownInterval = setInterval(() => { left--; countdownEl.text(left); if (left <= 0) { clearInterval(countdownInterval); modal.hide(); callback(); } }, 1000); } // Button click logic startButton.on('click', function() { if (isRecording) { stopRecognition(); } else if (!startedOnce) { startedOnce = true; showCountdownModal(3, function() { startRecognition(); }); } else { startRecognition(); } }); } else { answerTextarea.val("Web Speech API not supported in this browser."); } }); </script>
<script type="text/javascript" data-author="Tony Partner"> $(document).on('ready pjax:scriptcomplete',function(){ $("#answer{SGQ}SQ001_SQ001").mask("999.999.999-99",{ placeholder:" " }); // Listener on the text input $('#answer{SGQ}SQ002_SQ002').on('keyup', function(e) { $(this).val($(this).val().toUpperCase()); checkconditions($(this).attr('value'), $(this).attr('name'), $(this).attr('type')); }); $("#answer{SGQ}SQ001_SQ002").val(" "); $("#answer{SGQ}SQ001_SQ002").hide(); // Identify the questions var qArrayID = '{QID}'; var qArray = $('#question'+qArrayID); var arrayLength = $('tr[id^="javatbd"]', qArray).length; var qUploads = qArray.nextAll('.upload-files:lt('+arrayLength+')'); // Add some classes qArray.addClass('array-with-uploads-question'); $(qUploads).addClass('d-none'); // Insert the "Upload" buttons $('tr[id^="javatbd"] .answer-item:last-child', qArray).each(function(i) { $('*', this).remove(); $(this).append('<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#upload-'+qArrayID+'-'+(i+1)+'" data-bs-backdrop="static" data-bs-keyboard="false">Anexar comprovante</button>'); }); // Loop through the upload questions $(qUploads).each(function(i) { // Create a modal $('body').append('<div class="modal fade upload-modal" id="upload-'+qArrayID+'-'+(i+1)+'" tabindex="-1" aria-labelledby="uploadModalLabel'+qArrayID+'-'+(i+1)+'" aria-hidden="true">\ <div class="modal-dialog">\ <div class="modal-content">\ <div class="modal-header">\ <h5 class="modal-title" id="uploadModalLabel'+qArrayID+'-'+(i+1)+'">'+$('.ls-label-question', this).html()+'</h5>\ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fechar"></button>\ </div>\ <div class="modal-body">\ </div>\ <div class="modal-footer">\ <button type="button" class="btn btn-primary" data-bs-dismiss="modal">OK</button>\ </div>\ </div>\ </div>\ </div>'); // Move this question into the modal $('#upload-'+qArrayID+'-'+(i+1)+' .modal-body').append($(this)); $(this).removeClass('d-none'); }); // Interrupt the Previous/Next/Submit function (to put upload questions back in the form) $('#limesurvey').on('submit', function(e) { $('.upload-modal .upload-files').appendTo($('.group-container:eq(0)')).addClass('d-none'); }); }); </script> <style data-author="Tony Partner" type="text/css"> .upload-modal .file-upload-modal.in { height: max-content; } </style>