iT邦幫忙

0

Limesurvey進階應用--縣市鄉鎮選單

  • 分享至 

  • xImage
  •  

寫在前面

Limesurvey是一個開源網路調查軟體。可以註冊使用它的服務,或者使用Community Edition架設自己的網路調查系統。
Limesurvey具有功能完整的圖形界面,可以讓任何人輕鬆的建立自己的問卷進行網路調查。與許多網路調查系統不同的是,除了圖形界面,它也支援部分可程式編輯功能,並支援javascript及css,讓這套系統,具備更大的彈性空間。
Limesurvey的架設及基本操作,可以在網路上找到一些教學,Limesurvey官方也有詳細的操作說明。撰寫這篇文章的目的,是在這些基礎操作之外,分享一些進階應用,給使用這套軟體的朋友參考。

言歸正傳

做為這一系列的第一篇文章,先分享一個變化較大的應用--縣市鄉鎮選單的製作。縣市鄉鎮選單是調查中很常見的一種題型。常見的設計,會以兩個相互連動的下拉選單呈現,先讓填答者選擇縣市,然後再選擇鄉鎮市區。例如以下的題目:
https://ithelp.ithome.com.tw/upload/images/20241019/20142528valXLwV2Bq.png
當然Limesurvey沒有這種題型可以直接套用。這就必須由我們自己創造出來了。有鑑於Limesurvey支援javascript,因此我們可以透過javascript來進行改造。我們的目標是建立兩個相互關聯的下來選單,一個是「縣市」,一個「鄉鎮市區」;同時為了以防特殊狀況,會在兩個選單中都加入「其他」的選項,若選擇「其他」時,則提供開放文字欄位,讓填答者自由輸入。據此,我們需要三個欄位來承接相對應的資料(欄位1紀錄縣市的答案,欄位2紀錄鄉鎮市區的答案或欄位1選擇其他時的文字,欄位3紀錄鄉鎮市區選擇其他時的文字)。
首先我們先把題目建立出來。我們採用的題型是「Array (Texts)」。其中,Y軸維持預設的一個題目即可,X軸則建立三個子題。同時子題的文字欄位都保持空白即可。如下圖:
https://ithelp.ithome.com.tw/upload/images/20241019/20142528N6lPpqfn7I.png
接著,我們利用javascript對題目進行改造。我們只需在題目欄位點選"</>"按鈕,並將javascript填入題目的source(原始碼)中即可。程式如下:

 <script type="text/javascript">
 
  $(document).on('ready pjax:scriptcomplete',function(){
    var thisQuestion = $('#question{QID}');
//建立縣市鄉鎮列表,為節省篇幅,以下僅以基隆市及台北市做代表。 
var townships = {
"01": [
  { code: "200", name: "仁愛區" },
  { code: "201", name: "信義區" },
  { code: "202", name: "中正區" },
  { code: "203", name: "中山區" },
  { code: "204", name: "安樂區" },
  { code: "205", name: "暖暖區" },
  { code: "206", name: "七堵區" },
  { code: "997", name: "其他(請說明)" }],
"02": [
 	{ code: "100", name: "中正區" },
	{ code: "103", name: "大同區" },
	{ code: "104", name: "中山區" },
	{ code: "105", name: "松山區" },
	{ code: "106", name: "大安區" },
	{ code: "108", name: "萬華區" },
	{ code: "110", name: "信義區" },
	{ code: "111", name: "士林區" },
	{ code: "112", name: "北投區" },
	{ code: "114", name: "內湖區" },
	{ code: "115", name: "南港區" },
	{ code: "116", name: "文山區" },
  	{ code: "997", name: "其他(請說明)" }]
};
    
    // Column specific classes
    $('tr.subquestion-list', thisQuestion).each(function(i) {
      $('th, td', this).each(function(i) {
        $(this).addClass('column-'+i);
      });
    });
 
    // Insert selects into column 1
    if($('.answer-item.column-1 .inserted-select', thisQuestion).length == 0) {
      $('.answer-item.column-1', thisQuestion).addClass('with-select').append('<select class="inserted-select form-control list-question-select"  id="city-select">\
        <option value="">請選擇縣市</option>\
        <option value="01">基隆市</option>\
        <option value="02">台北市</option>\
        <option value="97">其他(請說明)</option>\
      </select>');
    } 
 
    // Insert selects into column 2
    if($('.answer-item.column-2 .inserted-select', thisQuestion).length == 0) {
      $('.answer-item.column-2', thisQuestion).addClass('with-select').append('<select class="inserted-select form-control list-question-select"  id="township-select">\
        <option value="">請選擇鄉鎮市區</option>\
      </select>');  
  } 
 
 // 初始時隱藏原本的文字框
    $('.answer-item.column-1 input:text', thisQuestion).css({
      'display': 'none'
    });
    $('.answer-item.column-2 input:text', thisQuestion).css({
      'display': 'none'
    });
    $('.answer-item.column-3 input:text', thisQuestion).css({
      'display': 'none'
    });

   // 縣市選單改變時,動態更新鄉鎮市區選單
$('#city-select').on('change', function() {
  var selectedCity = $(this).val(); // 使用選項的 value
  var $townshipSelect = $('#township-select');
  var $textInput = $('.answer-item.column-2 input:text', thisQuestion); // 原本的文字框
    
    //當縣市選擇「其他」時,鄉鎮市區欄位顯示原本的文字框
  if (selectedCity === '97') {
    $townshipSelect.hide();
    $textInput.val('')
    $textInput.show();
  } else {
    $townshipSelect.show();
    $textInput.hide();
    
    // 更新鄉鎮市區選單
    $townshipSelect.empty();
    $townshipSelect.append('<option value="">請選擇鄉鎮市區</option>');

    var townshipOptions = townships[selectedCity] || [];
    townshipOptions.forEach(function(township) {
      // 使用鄉鎮市區名稱作為顯示,代碼作為 value
      $townshipSelect.append('<option value="' + township.code + '">' + township.name + '</option>');
    });
  }
  
      
$('#township-select').on('change', function() {
    var selectedTown = $(this).val();
    var $textInput2 = $('.answer-item.column-3 input:text', thisQuestion);
  	//當鄉鎮市欄位選擇「其他」時,顯示第二個文字框(column-3)
    if (selectedTown === '997') {
      $textInput2.val('')
      $textInput2.show();
    }else {
      $textInput2.hide();
    }
  });
  
// 同步選擇的縣市 value 到 column-1 的輸入框中
  $('.answer-item.column-1 input:text', thisQuestion).val(selectedCity).trigger('keyup');
  //當縣市選擇其他時,此時不會用到第三個欄位,因此主動在第三個欄位填入NA,避免空值導致此題無法送出
    if (selectedCity == "97") {
    $('.answer-item.column-3 input:text', thisQuestion).val("NA").trigger('keyup');
  }
});

// 當使用者在 column-2 的文字框中輸入時,將資料同步到該題的答案字段中
$('.answer-item.column-2 input:text').on('input', function() {
  var enteredText = $(this).val();
  $(this).closest('.answer-item').find('input:text').val(enteredText);
});

// 鄉鎮市區選單改變時,同步選擇的 code 到 column-2 的文字框
$('#township-select').on('change', function() {
  var selectedTownshipCode = $('#township-select').val(); // 使用選項的 code
  $('.answer-item.column-2 input:text', thisQuestion).val(selectedTownshipCode).trigger('keyup');
  //當鄉鎮市區不是選擇其他時,此時不會用到第三個欄位,因此主動在第三個欄位填入NA,避免空值導致此題無法送出
  if (selectedTownshipCode != "997") {
    $('.answer-item.column-3 input:text', thisQuestion).val("NA").trigger('keyup');
  }
});
    
});
  
</script>

為了方便調查後的資料進行統計分析,我選擇將縣市鄉鎮的代碼記錄在欄位中;由於題目的本質是文字欄位,因此如果希望直接記錄縣市鄉鎮的名稱也沒問題,只要做適當的修改,將文字寫入欄位中即可。
將這段javascript貼到題目的source中,就可以存檔,然後預覽看看效果了。這個做法也可以適用其他多層選單的題目。在此也提供Limesurvey建立地區題的範例,可直接匯入Limesurvey測試。

此功能是參考Limesurvey Community討論區中,一篇名為Array (Text) Type Question With Customized Drop Down In Specific Columns的討論串裡,Tony Partner的範例進行修改的。如果有其他更方便的做法或問題,也歡迎討論。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言