PageSourceSearch

https://enquete.ndl.go.jp/scripts/survey_runtime.js

js ndl.go.jp collected 2026-09-24 06:42:02 UTC 21,137 bytes, 669 lines download raw bytes

1/*
2 * JavaScript functions in survey taking
3 *
4 * This file is part of LimeSurvey
5 * Copyright (C) 2007-2013 The LimeSurvey Project Team
6 * All rights reserved.
7 * License: GNU/GPL License v2 or later, see LICENSE.php
8 * LimeSurvey is free software. This version may have been modified pursuant
9 * to the GNU General Public License, and as distributed it includes or
10 * is derivative of works licensed under the GNU General Public License or
11 * other free or open source software licenses.
12 * See COPYRIGHT.php for copyright notices and details.
13 */
14
15// Some function can be launch before document ready (and seems intersting)
16limesurveySubmitHandler();
17needConfirmHandler();
18tableCellAdapters();
19activateLanguageChanger();
20$(document).ready(function()
21{
22    navbuttonsJqueryUi();
23    showStartPopups();
24    addClassEmpty();
25    noScrollOnSelect();
26    doToolTipTable();
27
28    if (typeof LEMsetTabIndexes === 'function') { LEMsetTabIndexes(); }
29    if (typeof checkconditions!='undefined') checkconditions();
30    if (typeof template_onload!='undefined') template_onload();
31    if (typeof(focus_element) != 'undefined')
32    {
33        $(focus_element).focus();
34    }
35
36    // Keypad functions
37    var kp = $("input.num-keypad");
38    if(kp.length)
39    {
40        kp.keypad({
41            showAnim: 'fadeIn', keypadOnly: false,
42            onKeypress: function(key, value, inst) {
43                $(this).trigger('keyup');
44            }
45        });
46    }
47    kp = $(".text-keypad");
48    if(kp.length)
49    {
50        var spacer = $.keypad.HALF_SPACE;
51        for(var i = 0; i != 8; ++i) spacer += $.keypad.SPACE;
52        kp.keypad({
53            showAnim: 'fadeIn',
54            keypadOnly: false,
55            layout: [
56                spacer + $.keypad.CLEAR + $.keypad.CLOSE, $.keypad.SPACE,
57                '!@#$%^&*()_=' + $.keypad.HALF_SPACE + $.keypad.BACK,
58                $.keypad.HALF_SPACE + '`~[]{}<>\\|/' + $.keypad.SPACE + $.keypad.SPACE + '789',
59                'qwertyuiop\'"' + $.keypad.HALF_SPACE + $.keypad.SPACE + '456',
60                $.keypad.HALF_SPACE + 'asdfghjkl;:' + $.keypad.SPACE + $.keypad.SPACE + '123',
61                $.keypad.SPACE + 'zxcvbnm,.?' + $.keypad.SPACE + $.keypad.SPACE + $.keypad.HALF_SPACE + '-0+',
62                $.keypad.SHIFT + $.keypad.SPACE_BAR + $.keypad.ENTER],
63                onKeypress: function(key, value, inst) {
64                    $(this).trigger('keyup');
65                }
66            });
67    }
68
69    // Maxlength for textareas TODO limit to not CSS3 compatible browser
70    maxlengthtextarea();
71
72});
73
74/**
75 * setJsVar : Get all global used var
76 */
77function setJsVar(){
78    bFixNumAuto=LSvar.bFixNumAuto;
79    bNumRealValue=LSvar.bNumRealValue;
80    LEMradix=LSvar.sLEMradix;
81    numRegex = new RegExp('[^-\.,0-9]','g');
82    intRegex = new RegExp('[^-0-9]','g');
83}
84// Deactivate all other button on submit
85function limesurveySubmitHandler(){
86    // Return false disallow all other system
87    $(document).on("click",".disabled",function(){return false});
88    $(document).on("click",'.active',function(){return false;});// "[active]" don't seem to work with jquery-1.10.2
89
90    $(document).on('click',"#limesurvey .button", function(event){
91        $(this).prop('active',true).addClass('active');
92        $("#limesurvey .button.ui-button" ).not($(this)).button( "option", "disabled", true );
93        $("#limesurvey .button").not($(this)).prop('disabled',true).addClass('disabled');
94    });
95    if (document.all && !document.querySelector) { // IE7 or lower
96        $(function() {
97            $("#defaultbtn").css('display','inline').css('width','0').css('height','0').css('padding','0').css('margin','0').css('overflow','hidden');
98            $("#limesurvey [type='submit']").not("#defaultbtn").first().before($("#defaultbtn"));
99        });
100    }
101}
102
103
104// Ask confirmation on click on .needconfirm
105function needConfirmHandler(){
106    $(document).on('click',"[data-confirmedby]", function(event){
107        text=$("label[for='"+$(this).data('confirmedby')+"']").text();
108        if (confirm(text)) {
109            $("#"+$(this).data('confirmedby')).prop('checked',true);
110            return true;
111        }
112        $(".button.ui-button" ).button( "option", "disabled", false );
113        $(".button").prop('disabled',false).removeClass('disabled');
114        $(this).prop('active',false).removeClass('active');
115        return false;
116    });
117}
118/**
119 * checkconditions : javascript function attach to some element
120 * Launch ExprMgr_process_relevance_and_tailoring with good value
121 */
122function checkconditions(value, name, type, evt_type)
123{
124    if (typeof evt_type === 'undefined')
125    {
126        evt_type = 'onchange';
127    }
128    if (type == 'radio' || type == 'select-one')
129    {
130        $('#java'+name).val(value);
131    }
132    else if (type == 'checkbox')
133    {
134        if ($('#answer'+name).is(':checked'))
135        {
136            $('#java'+name).val('Y');
137        } else
138        {
139            $('#java'+name).val('');
140        }
141    }
142    else if (type == 'text' && name.match(/other$/))
143    {
144        $('#java'+name).val(value);
145    }
146
147    aQuestionsWithDependencies = $('#aQuestionsWithDependencies').data('qids');
148
149    var result;
150    if(typeof name !== 'undefined')
151    {
152        result = name.split('X');
153        result = result[2]
154    }
155
156    // $isRelevant = $.inArray(result, aQuestionsWithDependencies); NEED TO ADD THE QUESTIONS WITH CONDITIONS BEFORE WE CAN USE IT !!!!
157    $isRelevant = 1;
158    if($.isFunction(window.ExprMgr_process_relevance_and_tailoring ) && $isRelevant!=-1)
159        ExprMgr_process_relevance_and_tailoring(evt_type,name,type);
160}
161
162/**
163 * fixnum_checkconditions : javascript function attach to some element
164 * Update the answer of the user to be numeric and launch checkconditions
165 *
166 * Also checks if any of the arrow keys is pressed to avoid unecessary hassle.
167 */
168function fixnum_checkconditions(value, name, type, evt_type, intonly)
169{
170    if(window.event){
171    var keyPressed =  window.event.keyCode || 0;
172    if(
173            keyPressed == 37 //left arrow
174        ||  keyPressed == 39 //right arrow
175    ){return false; }
176    }
177
178    var decimalValue;
179    var newval = new String(value);
180    var checkNumericRegex = new RegExp(/^(-)?[0-9]*(,|\.|)[0-9]*$/);
181    var cleansedValue = newval.replace(numRegex,'');
182    /**
183    * If have to use parsed value.
184    */
185    if(!bNumRealValue)
186    {
187        if(checkNumericRegex.test(value)) {
188            try{
189                decimalValue = new Decimal(cleansedValue);
190            } catch(e){
191                try{
192                    decimalValue = new Decimal(cleansedValue.replace(',','.'));
193                } catch(e){
194                    decimalValue = new Decimal(NaN);
195                }
196            }
197
198            if (typeof intonly !=='undefined' && intonly==1) {
199                newval = decimalValue.trunc();
200            }
201        } else {
202            newval = cleansedValue;
203        }
204
205    }
206
207    /**
208     * If have to fix numbers automatically.
209     */
210    if(bFixNumAuto && (newval != ""))
211    {
212
213        if(window.correctNumberField!=null) {
214            clearTimeout(window.correctNumberField);
215            window.correctNumberField = null;
216        }
217
218        var addition = "";
219        if(cleansedValue && cleansedValue.split("").pop().match(/(,)|(\.)/)){
220            addition = cleansedValue.split("").pop();
221        }
222        var matchFollowingZeroes =  cleansedValue.match(/^-?([0-9])*(,|\.)(0+)$/);
223        if(matchFollowingZeroes){
224            addition = LEMradix+matchFollowingZeroes[3];
225        }
226        if(decimalValue == undefined){
227            try{
228                decimalValue = new Decimal(cleansedValue);
229            } catch(e){
230                try{
231                    decimalValue = new Decimal(cleansedValue.replace(',','.'));
232                } catch(e){
233                    decimalValue = new Decimal(NaN);
234
235                }
236            }
237        }
238
239        /**
240         * Work on length of the number
241         * Avoid numbers longer than 20 characters before the decimal separator and 10 after the decimal separator.
242         */
243        // Treat decimal part, if there is one.
244        // Trim after 10th decimal if larger than 10 decimals.
245        if(decimalValue.dp()>10){
246            decimalValue.toDecimalPlaces(10);
247        }
248
249        /**
250         * Set display value
251         */
252        displayVal = decimalValue.toString();
253        if (displayVal=='NaN')
254        {
255            newval=displayVal;
256            displayVal=value;
257        }
258        else{
259            if(LEMradix==",")
260                displayVal = displayVal.replace(/\./,',');
261
262            newval = displayVal+addition
263
264            if (name.match(/other$/)) {
265                if($('#answer'+name+'text').val() != newval){
266                    $('#answer'+name+'text').val(newval);
267                }
268            }
269
270            if($('#answer'+name).val() != newval){
271                window.correctNumberField = setTimeout(function(){$('#answer'+name).val(newval);}, 400);
272            }
273        }
274    }
275
276    /**
277     * Check conditions
278     */
279    if (typeof evt_type === 'undefined')
280    {
281        evt_type = 'onchange';
282    }
283    checkconditions(newval, name, type, evt_type);
284}
285
286// Set jquery-ui to LS Button
287function navbuttonsJqueryUi(){
288    $('[dir!="rtl"] #moveprevbtn').button({
289    icons: {
290        primary: 'ui-icon-triangle-1-w'
291    }
292    });
293    $('[dir="rtl"] #moveprevbtn').button({
294    icons: {
295        secondary: 'ui-icon-triangle-1-e'
296    }
297    });
298    $('[dir!="rtl"] #movenextbtn').button({
299    icons: {
300        secondary: 'ui-icon-triangle-1-e'
301    }
302    });
303    $('[dir="rtl"] #movenextbtn').button({
304    icons: {
305        primary: 'ui-icon-triangle-1-w'
306    }
307    });
308    $(".button").button();
309    // TODO trigger handler activate/deactivate to update ui-button class
310}
311/**
312 * showStartPopups : Take all message in startPopups json array and launch an alert with text
313 */
314function showStartPopups(){
315    if(typeof showpopup=="undefined"){showpopup=1;}
316    if(typeof startPopups=="undefined"){startPopups=[];}
317    if(showpopup){
318        $.each(startPopups,function(key, text){
319            alert($("<div/>").html(text).text());// Parse HTML because of &#039;
320        });
321    }
322}
323/**
324 * Update survey just when select a new language
325 */
326function activateLanguageChanger(){
327    $(document).on('change','select.languagechanger', function() {
328        if($(this).hasClass('previewmode'))
329        {
330            var target=$(this).data('targeturl');
331            $('<form>', {
332                "html": '<input type="hidden" name="lang" value="' + $(this).find('option:selected').val() + '" />',
333                "action": target
334            }).appendTo(document.body).submit();
335            return false;
336        }
337        if(!$(this).closest('form').length){// If there are no form : we can't use it, we need to create and submit. This break no-js compatibility in some page (token for example).
338            if($('form#limesurvey').length==1){ // The limesurvey form exist in document, move select and button inside and click
339                $("form#limesurvey [name='lang']").remove();// Remove existing lang selector
340                $("<input type='hidden']>").attr('name','lang').val($(this).find('option:selected').val()).appendTo($('form#limesurvey'));
341                $("#changelangbtn").appendTo($('form#limesurvey'));
342                $('#changelangbtn').click();
343            }else{
344                if($(this).data('targeturl')){
345                    var target=$(this).data('targeturl');
346                }else{
347                    var target=document.location.href;
348                }
349                $('<form>', {
350                    "html": '<input type="hidden" name="lang" value="' + $(this).find('option:selected').val() + '" />',
351                    "action": target,
352                    "method": 'post'
353                }).appendTo(document.body).append($("input[name='YII_CSRF_TOKEN']")).submit();
354            }
355        }else{
356            $(this).closest('form').find("[name='lang']").not($(this)).remove();// Remove other lang
357            $('#changelangbtn').click();
358        }
359    });
360    $(function(){
361        $(".changelang.jshide").hide();
362    });
363}
364/**
365 * Manage the index
366 */
367function manageIndex(){
368    $("#index .jshide").hide();
369    $("#index").on('click','li,.row',function(e){
370        if(!$(e.target).is('button')){
371            $(this).children("[name='move']").click();
372        }
373    });
374    $(function() {
375        $(".outerframe").addClass("withindex");
376        var idx = $("#index");
377        var row = $("#index .row.current");
378        if(row.length)
379            idx.scrollTop(row.position().top - idx.height() / 2 - row.height() / 2);
380    });
381}
382/**
383 * Put a empty class on empty answer text item (limit to answers part)
384 * @author Denis Chenu / Shnoulle
385 */
386function addClassEmpty()
387{
388    $('.answer-item input.text[value=""]').addClass('empty');
389    $('.answer-item input[type=text][value=""]').addClass('empty');
390    $('.answer-item textarea').each(function(index) {
391    if ($(this).val() == ""){
392        $(this).addClass('empty');
393    }
394    });
395    $("body").delegate(".answer-item input.text,.text-item input[type=text],.answer-item textarea","blur focusout",function(){
396    if ($(this).val() == ""){
397        $(this).addClass('empty');
398    }else{
399        $(this).removeClass('empty');
400    }
401    });
402}
403
404/**
405 * Disable scroll on select, put it in function to allow update in template
406 *
407 */
408function noScrollOnSelect()
409{
410    $(".question").find("select").each(function () {
411        hookEvent($(this).attr('id'),'mousewheel',noScroll);
412    });
413}
414/**
415 * Adapt cell to have a click on cell do a click on input:radio or input:checkbox (if unique)
416 * Using delegate the can be outside document.ready (using .on is possible but on $(document) then : less readbale
417 * @author Denis Chenu / Shnoulle
418 */
419function tableCellAdapters()
420{
421//	$('table.question').delegate('tbody td input:checkbox,tbody td input:radio,tbody td label',"click", function(e) {
422//		e.stopPropagation();
423//	});
424    $(document).on('click','table.question tbody td',function(event) {// 'table.question tbody td' or 'td.radio-item,td.checkbox-item': maybe less js here
425        var eventTarget=$(event.target).prop("tagName");// Alternative us data
426        var eventActivate=$(this).find("input:radio,input:checkbox");
427        if(eventActivate.length==1 && (eventTarget!='INPUT' && eventTarget!='LABEL' ) )
428        {
429            $(eventActivate).click();
430            $(eventActivate).triggerHandler("click");
431            // Why not use trigger('click'); only ?
432        }
433    });
434}
435
436Array.prototype.push = function()
437{
438    var n = this.length >>> 0;
439    for (var i = 0; i < arguments.length; i++)
440    {
441        this[n] = arguments[i];
442        n = n + 1 >>> 0;
443    }
444    this.length = n;
445    return n;
446};
447
448Array.prototype.pop = function() {
449    var n = this.length >>> 0, value;
450    if (n) {
451        value = this[--n];
452        delete this[n];
453    }
454    this.length = n;
455    return value;
456};
457
458
459//defined in group.php & question.php & survey.php, but a static function
460function inArray(needle, haystack)
461{
462    for (h in haystack)
463    {
464        if (haystack[h] == needle)
465        {
466            return true;
467        }
468    }
469    return false;
470}
471
472//defined in group.php & survey.php, but a static function
473function match_regex(testedstring,str_regexp)
474{
475    // Regular expression test
476    if (str_regexp == '' || testedstring == '') return false;
477    pattern = new RegExp(str_regexp);
478    return pattern.test(testedstring)
479}
480
481function addHiddenField(theform,thename,thevalue)
482{
483    var myel = document.createElement('input');
484    myel.type = 'hidden';
485    myel.name = thename;
486    theform.appendChild(myel);
487    myel.value = thevalue;
488}
489
490function cancelBubbleThis(eventObject)
491{
492    if (!eventObject) var eventObject = window.event;
493    eventObject.cancelBubble = true;
494    if (eventObject && eventObject.stopPropagation) {
495        eventObject.stopPropagation();
496    }
497}
498
499function cancelEvent(e)
500{
501  e = e ? e : window.event;
502  if(e.stopPropagation)
503    e.stopPropagation();
504  if(e.preventDefault)
505    e.preventDefault();
506  e.cancelBubble = true;
507  e.cancel = true;
508  e.returnValue = false;
509  return false;
510}
511
512function hookEvent(element, eventName, callback)
513{
514  if(typeof(element) == "string")
515    element = document.getElementById(element);
516  if(element == null)
517    return;
518  if(element.addEventListener)
519  {
520    if(eventName == 'mousewheel')
521      element.addEventListener('DOMMouseScroll', callback, false);
522    element.addEventListener(eventName, callback, false);
523  }
524  else if(element.attachEvent)
525    element.attachEvent("on" + eventName, callback);
526}
527
528function noScroll(e)
529{
530  e = e ? e : window.event;
531  cancelEvent(e);
532}
533
534
535function getkey(e)
536{
537   if (window.event) return window.event.keyCode;
538    else if (e) return e.which; else return null;
539}
540
541function goodchars(e, goods)
542{
543    var key, keychar;
544    key = getkey(e);
545    if (key == null) return true;
546
547    // get character
548    keychar = String.fromCharCode(key);
549    keychar = keychar.toLowerCase();
550    goods = goods.toLowerCase();
551
552   // check goodkeys
553    if (goods.indexOf(keychar) != -1)
554        return true;
555
556    // control keys
557    if ( key==null || key==0 || key==8 || key==9  || key==27 )
558      return true;
559
560    // else return false
561    return false;
562}
563
564function show_hide_group(group_id)
565{
566    var questionCount;
567
568    // First let's show the group description, otherwise, all its childs would have the hidden status
569    $("#group-" + group_id).show();
570    // If all questions in this group are conditionnal
571    // Count visible questions in this group
572        questionCount=$("div#group-" + group_id).find("div[id^='question']:visible").size();
573
574        if( questionCount == 0 )
575        {
576            $("#group-" + group_id).hide();
577        }
578}
579
580// round function from phpjs.org
581function round (value, precision, mode) {
582    // http://kevin.vanzonneveld.net
583    var m, f, isHalf, sgn; // helper variables
584    precision |= 0; // making sure precision is integer
585    m = Math.pow(10, precision);
586    value *= m;
587    sgn = (value > 0) | -(value < 0); // sign of the number
588    isHalf = value % 1 === 0.5 * sgn;
589    f = Math.floor(value);
590
591    if (isHalf) {
592        switch (mode) {
593        case 'PHP_ROUND_HALF_DOWN':
594            value = f + (sgn < 0); // rounds .5 toward zero
595            break;
596        case 'PHP_ROUND_HALF_EVEN':
597            value = f + (f % 2 * sgn); // rouds .5 towards the next even integer
598            break;
599        case 'PHP_ROUND_HALF_ODD':
600            value = f + !(f % 2); // rounds .5 towards the next odd integer
601            break;
602        default:
603            value = f + (sgn > 0); // rounds .5 away from zero
604        }
605    }
606
607    return (isHalf ? value : Math.round(value)) / m;
608}
609
610/* Maxlengt on textarea */
611function maxlengthtextarea(){
612    // Calling this function at document.ready : use maxlength attribute on textarea
613    // Can be replaced by inline javascript
614    $("textarea[maxlength]").change(function(){ // global solution
615        var maxlen=$(this).attr("maxlength");
616        if ($(this).val().length > maxlen) {
617            $(this).val($(this).val().substring(0, maxlen));
618        }
619    });
620    $("textarea[maxlength]").keyup(function(){ // For copy/paste (not for all browser)
621        var maxlen=$(this).attr("maxlength");
622        if ($(this).val().length > maxlen) {
623            $(this).val($(this).val().substring(0, maxlen));
624        }
625    });
626    $("textarea[maxlength]").keydown(function(event){ // No new key after maxlength
627        var maxlen=$(this).attr("maxlength");
628        var k =event.keyCode;
629        if (($(this).val().length >= maxlen) &&
630         !(k == null ||k==0||k==8||k==9||k==13||k==27||k==37||k==38||k==39||k==40||k==46)) {
631            // Don't accept new key except NULL,Backspace,Tab,Enter,Esc,arrows,Delete
632            return false;
633        }
634    });
635}
636/**
637 * Add a title on cell with answer
638 * Title must be updated because label can be updated by expression : mouseover do it only if needed. Accessibility must use aria-labelledby
639 **/
640function doToolTipTable()
641{
642    $(document).on("mouseover"," td.answer-item",function() {
643        var text = $(this).find('label').text().trim();
644        if(text!==""){
645            $(this).attr('title', text);
646        }else{
647            $(this).removeAttr('title');
648        }
649    });
650}
651//Hide the Answer and the helper field in an
652$(document).ready(
653    function(){
654        $('.question-container').each(function(){
655            if($(this).find('div.answer-container').find('input').length == 1)
656            {
657                if($(this).find('div.answer-container').find('input[type=hidden]').length >0
658                    && $(this).find('div.answer-container').find('select').length < 1)
659                {
660                    $(this).find('div.answer-container').css({display: 'none'});
661                }
662                if(trim($(this).find('div.question-help-container').find('div').html()) == "")
663                {
664                    $(this).find('div.question-help-container').css({display: 'none'});
665                }
666            }
667        });
668    }
669);

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.