Ví dụ về ExpressionScript
From LimeSurvey Manual
Cấu trúc
Phần đầu tiên của bài viết sẽ mô tả Biểu thức có thể được sử dụng để làm gì và nơi tìm/thêm Biểu thức. Phần thứ hai cung cấp các ví dụ về cách sử dụng Biểu thức.
Các loại biểu thức
LimeSurvey sử dụng Biểu thức cho các mục đích sau:
Mức độ liên quan
Mục đích: Ẩn nhóm câu hỏi/câu hỏi
Mức độ liên quan kiểm soát việc một nhóm câu hỏi hoặc câu hỏi được hiển thị hay ẩn. Nếu kết quả của Biểu thức là "true" (tức là 1) thì phần tử sẽ được hiển thị. Ngược lại (nếu kết quả của Biểu thức là "false" (tức là 0)), phần tử sẽ bị ẩn.
Type | Hiển thị/ẩn | Tìm ở đâu | Ảnh chụp màn hình |
---|---|---|---|
Mức độ liên quan của nhóm câu hỏi | nhóm câu hỏi | Tạo/Chỉnh sửa nhóm câu hỏi -> "Phương trình liên quan:" | 30px |
Câu hỏi Mức độ liên quan | câu hỏi | Tạo/Chỉnh sửa câu hỏi -> "Phương trình liên quan:" | 30px |
Độ liên quan của câu hỏi con | câu hỏi phụ | Chỉnh sửa câu hỏi phụ -> "Phương trình liên quan:" | 30px |
Xác thực
Mục đích: Xác thực dữ liệu đầu vào/hành động đối với câu hỏi/câu hỏi phụ/câu trả lời
Xác thực kiểm soát xem thông tin đầu vào của người trả lời vào câu hỏi hoặc hành động có hợp lệ hay không. Nếu kết quả của biểu thức là "true" (tức là 1), lớp "tốt" sẽ được áp dụng cho phần tử và thông báo xác thực. Mặt khác, nếu kết quả của biểu thức là "false" (tức là 0)), lớp "lỗi" sẽ được áp dụng cho phần tử và thông báo xác thực. Bạn có thể khai báo kiểu cho các lớp này trong template.css.
Type | Xác thực | Tìm ở đâu | Ảnh chụp màn hình |
---|---|---|---|
Xác thực câu hỏi | câu hỏi | Tạo/Chỉnh sửa câu hỏi -> "tab logic" - > "Phương trình xác thực câu hỏi" | 30px |
Xác thực câu hỏi con | câu hỏi con | Tạo/Chỉnh sửa câu hỏi -> "tab Logic" -> " Phương trình xác thực câu hỏi con" | |
Xuất văn bản
Mục đích: (Làm gì đó) và viết ra một số văn bản
Một biểu thức có thể được sử dụng để viết ra một số văn bản. Ví dụ: bạn có thể kiểm tra hoặc tính toán một cái gì đó và chỉ định kết quả đầu ra tùy thuộc vào kết quả kiểm tra hoặc tính toán. Nó cũng có thể được sử dụng để chèn nội dung câu hỏi, câu trả lời, loại câu hỏi, ... của câu hỏi được sử dụng trước khi sử dụng Biểu thức. Đầu ra văn bản có thể được sử dụng ở mọi nơi có văn bản được hiển thị và có thể trả về mọi loại kết quả.
Trường hợp sử dụng | Description |
---|---|
Micro may đo | Điều chỉnh văn bản, ví dụ: viết "Mr" hoặc "Mrs" tùy theo câu hỏi về giới tính được hỏi trước đó |
Tính toán | Tính một giá trị và viết nó ra, ví dụ: "Thu nhập của gia đình bạn là xxx" |
Reference | Chèn văn bản từ một phần tử, ví dụ: "Tên bạn là xxx. Bạn bao nhiêu tuổi?" |
Lưu trữ câu trả lời
Mục đích: (Làm gì đó,) (viết một số văn bản) và lưu trữ một cái gì đó trong cơ sở dữ liệu
Loại câu hỏi phương trình có thể được sử dụng để lưu trữ nội dung nào đó trong cơ sở dữ liệu. Bạn có thể làm điều gì đó với Biểu thức, hiển thị câu hỏi Phương trình (tương tự như hiển thị văn bản) và lưu trữ kết quả của Biểu thức trong cơ sở dữ liệu. Nó lưu trữ câu trả lời vào bảng phản hồi. Sau đó, kết quả có thể được sử dụng trong tính năng thống kê hoặc cũng có thể được nhập vào một trong các định dạng do chức năng xuất LimeSurvey cung cấp.
Ví dụ về biểu thức
Chèn câu trả lời từ câu hỏi trước
Purpose | Chèn câu trả lời từ câu hỏi trước |
Type | Reference |
Ví dụ | Câu hỏi một (mã câu hỏi " Q00"): Bạn sống ở thành phố nào? Câu hỏi thứ hai (mã câu hỏi "Q01") Bạn đã sống ở THÀNH PHỐ bao lâu rồi? Việc cần làm: Nên sử dụng câu trả lời của câu hỏi một thay vì "THÀNH PHỐ" trong câu hỏi thứ hai. |
Expression | {QOO} |
Description | Câu trả lời được cung cấp trong Q00 thay thế trường Q00 từ câu hỏi thứ hai |
Các bước | Tạo/Chỉnh sửa câu hỏi thứ hai Chèn "Bạn đã sống ở {QOO} (năm) được bao lâu?" vào trường văn bản câu hỏi |
File:Biểu thức đơn giản tên thành phố.png |
Sử dụng câu hỏi phương trình ẩn để tự động điền câu trả lời
Vấn đề: Hãy tưởng tượng bạn có hai câu hỏi Q1 và Q2. Q1 hỏi người trả lời về độ tuổi của họ. Q2 chia người trả lời thành 3 nhóm: tuổi dưới 20, tuổi 20, tuổi lớn hơn 20. Vì vậy, Q2 nên sử dụng các giá trị “1”, “2”, “3” tương ứng với các điều kiện trên. Ngoài ra, chúng ta không nên quên ẩn Q2 (câu hỏi sẽ không được hiển thị trong khảo sát nhưng các giá trị sẽ thông qua "quy trình nền" trong bảng phản hồi).
Để điền vào cơ sở dữ liệu bằng loại câu hỏi Phương trình:
- Đầu tiên, tạo một câu hỏi có mã Q1 làm câu hỏi nhập số.
- Sau đó tạo một câu hỏi khác có mã Q2 làm câu hỏi phương trình .
- Trong chương tab "Cài đặt hiển thị" của Q2:
- đặt trường "Luôn ẩn câu hỏi này" là "Bật"
- nhập vào trường "Phương trình" biểu thức:
{if(Q1.NAOK < 20, "1", if(Q1.NAOK > 20, "3", "2"))}
Tạo trang tóm tắt bằng cách sử dụng trình giữ chỗ
Hướng dẫn này trình bày cách bạn có thể tạo một cái nhìn tổng quan ở cuối cuộc khảo sát, liệt kê tất cả các câu hỏi và câu trả lời thông qua phần giữ chỗ ExpressionScript. Nó cũng chỉ ra cách thực hiện giới hạn cái nhìn tổng quan như vậy chỉ ở những câu hỏi đã được trả lời.
Bạn có thể tải xuống ví dụ của chúng tôi từ đây: Ví dụ khảo sát về người giữ chỗ khảo sát.
Các loại câu hỏi đang được sử dụng ở đây:
1. Câu hỏi một lựa chọn / văn bản đơn/câu hỏi số
- Danh sách (thả xuống)
- Danh sách (radio) [L]
- Có/Không [Y]
- Văn bản dài tự do [T ]
- Văn bản tự do ngắn [S]
- Nhập số [N]
- Phương trình [*]
2. Câu hỏi với câu hỏi phụ
- Nhiều văn bản ngắn [Q]
- Trắc nghiệm [M]
- Array [F]
- Array (Có/Không/Không chắc chắn) [C]!N !*Array (lựa chọn 10 điểm) [B]
3. Câu hỏi có 2 thang đo
- Array thang đo kép [1]
4. Câu hỏi với thang đo X và Y
- Array (Số) [:]
5. Mặt nạ câu hỏi
- Hiển thị văn bản [X]
Trong ví dụ đơn giản này, tổng quan của chúng tôi sẽ là một danh sách đơn giản với:
- Nội dung câu hỏi: Câu trả lời của người dùng
Câu hỏi một lựa chọn/văn bản đơn/câu hỏi số
Đối với tất cả các loại câu hỏi này, Limesurvey sẽ lưu trữ một câu trả lời duy nhất:
- Danh sách (thả xuống)
- Danh sách (radio)
- Danh sách có nhận xét
- 5 điểm lựa chọn
- Có/Không
- Văn bản ngắn tự do
- Văn bản dài tự do!N !*Văn bản miễn phí rất lớn
- Nhập số
- Phương trình
- Ngày
- Giới tính
Giả sử mã câu hỏi của câu hỏi là q1, chúng ta có thể tham khảo nội dung câu hỏi và câu trả lời bằng cách sử dụng:
- {q1.question}: {q1.shown}
Ví dụ:
- Bạn bao nhiêu tuổi?: 25
Nếu bạn muốn kiểm tra xem câu hỏi đó đã được trả lời chưa, bạn có thể đặt câu lệnh IF xung quanh đầu ra của mình:
{if(!is_empty(q1),join("- ",q1.question,": ",q1.shown),"")}
Điều này "dịch" thành: NẾU câu hỏi có mã q1 không trống, xuất ra "- " VÀ văn bản câu hỏi VÀ ": " VÀ văn bản câu trả lời (hàm join() nối các phần tử dưới dạng một chuỗi mới; ELSE: không xuất ra gì (" " có nghĩa là chuỗi trống).
Câu hỏi có câu hỏi phụ
Đối với tất cả các loại câu hỏi này, LimeSurvey sử dụng các câu hỏi phụ:
- Multiple short text
- Multiple choice
- Multiple choice with comments
- Array
- Array (5 point choice)
- Array (10 point choice)
- Array (Yes/No/Uncertain)
- Array (Increase/Same/Decrease)
- Array by column
Assuming the question code of the question is q2 and the subquestions are numbered SQ001, SQ002, (auto-numbering done by LimeSurvey), we can reference the question text and answer using:
- {q2_SQ001.question}: {q2_SQ001.shown}
- {q2_SQ002.question}: {q2_SQ002.shown}
For multiple choice questions it makes sense to now show the text of the ticked subquestion but to show a Y for each selected option:
- {q2_SQ001.question}: {q2_SQ001}
- {q2_SQ002.question}: {q2_SQ002}
...
Note that currently it is not possible to output the question text of questions with subquestions, see this feature request.
Example 1 (assuming question type is multiple choice)
- Do you know these car brands?
-- Mercedes: Y
-- Audi: N
-- Volvo: Y
If you want to output checked items only you can put an IF statement around your output and check for the checkbox value:
{ if( q2_SQ001=="Y", join( "- ", q2_SQ001.question, ": ", q2_SQ001.shown ), "" ) }
Use the listifop function if you want to output a list of only the selected items, eg: Mercedes, Volvo
{ listifop( 'value', '==', 'Y', 'question', ', ', that.q2.sgqa ) }
Where that.q2 expands to all of q2's subquestions. See self, this and that for more detail.
Example 2 (assuming question type is Array (10 point choice))
- Please rate the quality of the car brands below on a scale from 1=very bad to 10=very good?
-- Mercedes: 7
-- Audi: 9
-- Volvo: 9
If you want to output rated items only you can put an IF statement around your output and check if the current sub question was answered by using:
{ if( ! is_empty( q3_SQ001 ), join( "- ", q3_SQ001.question, ": ", q3_SQ001.shown ), "" ) }
Use the listifop function if for example you want to only output a list of the selected items greater than eight, eg: Audi / Volvo
{ listifop( 'value', '>', 8, 'question', ' / ', that.q3.sgqa ) }
Question with two scales
Let's assume that the following codes are being used:
- Question code: q4
- Subquestion codes: SQ001, SQ002, ...
- Answer codes scale 1: A1, A2, ...
- Answer codes scale 2: B1, B2, ...
Example for referring to the answer of the third subquestion and second scale: q4_SQ003_1 - Question 4, subquestion 3, second scale.
Let's output the results for both scales and the first two subquestions:
- {q4_SQ001_0.question}: {q4_SQ001_0.shown} / {q4_SQ001_1.shown}
- {q4_SQ002_0.question}: {q4_SQ002_0.shown} / {q4_SQ002_1.shown}
To output the subquestion text, you need to add the scale ID to the placeholder (though the texts are the same for both scales). So instead of {q4_SQ001.question} we have to use {q4_SQ001_0.question} or {q4_SQ001_1.question}.
If you want to export/display the results of subquestions with at least one answer only, use this syntax for each subquestion:
{if(count(q4_SQ001_0,q4_SQ001_1)>0,join("- ",q4_SQ001_0.question,": ",q4_SQ001_0.shown," / ",q4_SQ001_1.shown),"")}
Question with X and Y scales
This applies to all matrix questions which allow an answer for every cell (not just every row as shown previously):
- Array Texts
- Array Numbers
Assumed codes used:
- Question code: q5
- Subquestion codes: SQ001, SQ002, ...
- Answer codes: A1, A2, ...
To refer to the result of a certain subquestion from a certain column, you need to use QuestionCode . '_' . SubQuestionCode . '_' . AnswerCode. Example for referring to the answer of the third subquestion and second column: q5_SQ003_A2.
Let's output the results for columns 1-3 of the first two subquestions:
- {q5_SQ001_A1.question}: {q5_SQ001_A1.shown} | {q5_SQ001_A2.shown} | {q5_SQ001_A3.shown}
- {q5_SQ002_A1.question}: {q5_SQ002_A1.shown} | {q5_SQ002_A2.shown} | {q5_SQ002_A3.shown}
Since for these question types each cell (combination of X axes and Y axes) equals one answer option, a test for existing data needs to be done for each cell. Example:
{if(!is_empty(q5_SQ001_A1),join("- ",q5_SQ001_A1.question,": ",q5_SQ001_A1.shown),"")}
Hide question if answer from previous question is empty
Purpose | Hide question if answer from previous question is empty |
Type | Question Relevance |
Example | Question one: question code "name", question text "What's your name?" Question two: question text "{name}, how old are you?" To do: Hide question two if the textfield of question one is empty |
Expression | !is_empty(name) |
Description | is_empty() determines whether a variable is considered to be empty. The "!" negates the result. So if the variable is not empty the Expression will be true and the question is shown |
Steps | Create/edit question two Insert "!is_empty(name)" into "Relevance equation:" |
Sample File | Hide_question_if_empty_question_group.zip |
Hide question group if answer from previous question is Yes or No
Purpose | Hide question group if answer from previous question is Yes or No |
Type | Question group Relevance |
Example | Page one, Question Group one, Question one: question code "PET", question text "Do you have a pet?" -Yes -No Page two, Question Group two: Title "About your pet(s)" To do: Show/Hide question group two if answer from question one is Yes/No |
Expression | PET == "Y" |
Description | PET is the question code for the question you want to check the answer. If you don't use a suffix EM will use "Qcode.code". So you compare the answer code from the PET question to the value "Y". If the participant answers "Yes" the Expression is true and the question group "About your pet(s)" will be shown. |
Steps | Create/edit question group two Insert "PET == "Y"" into "Relevance equation:" |
Sample File | Hide_question group_if_answer_from_previous_question_is_Yes_or_No.zip |
Display value of a multiple answer input question field
Purpose | Display value of a multiple answer input question field |
Type | Reference |
Example | Question one: question code "AskChildAge", question text "How old are your children?". Subquestions codes -Child1 -Child2 -Child3 - ChildXXX Question two: question code "ReportChildAge" question text "About your first child: - CHILD1 is AGE1." |
Expression | {AskChildAge_Child1.question}, {AskChildAge_Child1.value} |
Description | You want to use the value of a subquestion in a following question. You can access the subquestion value with this kind of expression: QcodeQuestion_QcodeSubquestion.value |
Steps | Create/edit the second question Insert this text in the description: "About your first child: - {AskChildAge_Child1.question} is {AskChildAge_Child1.value}." |
Sample File | Display_value_of_a_multiple_answer_input_question_field.zip |
Validate number of boxes ticked per row for an "Array (Numbers) Checkbox" question
Purpose | Validate number of boxes ticked per row |
Type | Validation |
Example | Question of type "Array Numbers (Checkbox Layout)" |
Expression | sum(...) |
Description | (sum(Test_A_1, Test_A_2, Test_A_3, Test_A_4, Test_A_5) <= X) determines whether at least X checkboxes in row A are checked. If you want to check all three rows (A, B, C), you can connect the expression using "&&": (sum(Test_A_1, Test_A_2, Test_A_3, Test_A_4, Test_A_5) <= X) && (sum(Test_B_1, Test_B_2, Test_B_3, Test_B_4, Test_B_5) <= X) && (sum(Test_C_1, Test_C_2, Test_C_3, Test_C_4, Test_C_5) <= X) |
Steps | Create/edit question of type "Array Numbers (Checkbox Layout)". Insert the above expression into "Question validation equation" at the advanced question settings (you might have to adjust variable namings!). |
Sample File | Validate number of boxes ticker per row for an Array (Numbers) Checkbox.lss |
Calculate difference between two dates
Purpose | Calculate difference between two dates |
Type | Relevance / Equation question type / Validation |
Example | Question one (date/time, code: DOB): What is your date of birth? Question two (date/time, code: datetoday): What is the date today? Question three (boilerplate): You are XXXX days old. To do: Calculate and display the number of days between the date given in question 1 and the question 2. |
Expression | {(strtotime(datetoday)-strtotime(DOB))/60/60/24} |
Description | strtotime calculates the number of seconds between the 1st of January 1970 and the given date. The above expression calculates the number of seconds between the two given dates. The term "/60/60/24" just calculates the number of days from the number of seconds. Instead of asking for the "datetoday", you can also use strtotime('now') or simply time(), which directly returns the number of seconds from January 1970 until now (i.e. the time the survey was taken). Thus you could quickly figure out the age of a person in years with the equation {(time() - strtotime(DOB)) / 60 / 60 / 24 / 365.25} In any of these cases, it is critical that the date is entered in a proper format, otherwise the strtotime() function will not work right. |
Steps | Create two date questions (for the date of birth and for today's date) and a boilerplate question. In the question text of the boilerplate question insert: "On {datetoday} you were {(strtotime(today)-strtotime(dob))/60/60/24} days days old." Please note: The function strtotime can work with MANY but not all date formats. If you run into problems set your survey's date format to mm/dd/yyyy or yyyy-mm-dd or dd.mm.yyyy" |
Sample File | Date_difference.zip |
Using ExpressionScript for Assessments
Here comes another example on how to use the ExpressionScript with Array type questions and assessments:</ br>
Let's say you have 2 array questions and you want to save the results of the calculation data to your database. It is actually simple, you will need to create and test your arrays and submit a dummy response to see if it works and gives you the results in the completed page.
Implementation details:
- add a question of type equation
- add the following line assuming that Q1 is your array question code while Q2 is the second one:
{sum(Q1_SQ001.value,Q2_SQ001.value)}
Note that SQ001 is the default code for any subquestion. If you change the subquestion code, adjust the equation above accordingly.
Using em_validation_q in array
You can use the question validation equation to control an array with any condition.
Implementation details:
- for the first array : array of single choice
- Question code is ARRAY
- Sub question code are SQ01,SQ02,SQ03 and SQ04
- update the Whole question validation equation and put
!is_empty(ARRAY_SQ01) and !is_empty(ARRAY_SQ03)
- for the second array : array of text
- Question code is ARRAYTEXT
- Sub question at Y axis code are SY01,SY02,SY03, and SY04
- Update the Whole question validation equation and put
count(self.sq_SY01 >= 1) and count(self.sq_SY03 >= 3)