ExpressionScript — prezentacja
From LimeSurvey Manual
Wprowadzenie
LimeSurvey korzysta z nowego modułu ExpressionScript (EM), który umożliwia LimeSurvey obsługę bardziej złożonych rozgałęzień, ocen, walidacji i dostosowywania. Zastępuje sposób, w jaki LimeSurvey zarządza Zastąpieniami, Warunki i Oceny na zapleczu. Przyspiesza także znacznie przetwarzanie, ponieważ eliminuje większość odczytów baz danych w czasie wykonywania. EM został opracowany przez dr Thomasa White'a (TMSWhite).
Kluczowe definicje
- Wyrażenie: Wszystko otoczone nawiasami klamrowymi:
- Pod warunkiem, że bezpośrednio po nawiasie otwierającym lub przed zamykającym nawiasem klamrowym nie ma spacji.
- Zawartość wyrażenia jest oceniana firmy EM, więc może zawierać formuły matematyczne, funkcje oraz złożone przetwarzanie ciągów i dat.
- Krawiectwo: Czasami nazywane „rurociągami”. Jest to proces warunkowej modyfikacji tekstu:
- Masz dostęp do wszystkich „pól zastępczych”, danych uczestników i danych odpowiedzi.
- Masz także łatwiejszy dostęp do pytań, odpowiedzi i ich właściwości.
- 'Relacja trafności: Nowy atrybut pytania kontrolujący widoczność pytania:
- Jeśli istnieje równanie trafności, pytanie jest wyświetlane tylko wtedy, gdy trafność ma wartość true.
- *Wewnętrznie wszystkie polecenia array_filter i array_filter_exclude stają się istotne na poziomie pytania podrzędnego.
- SGQA (jak nazywano zmienne w przeszłości) :
- Skrót od Survey-Group-Question-Answer
- Nazwy zmiennych SGQA wyglądają jak 123X5X382X971 i mogą zawierać sufiksy pytań podrzędnych.
- Te nazwy zmiennych są specyficzne dla bazowego S/Q/ Kody bazy danych G/A, dlatego często trzeba je zmieniać
- Równanie Typ pytania: Nowy typ pytania, który zapisuje obliczenia lub raporty do bazy danych:! N!#*To przypomina pytanie standardowe, ale jego zawartość jest zapisywana w bazie danych, nawet jeśli ustawisz opcję „Zawsze ukrywaj to pytanie”.
- Kod pytania: To jest preferowana nazwa zmiennej dla EM:
- Może to być nazwa opisowa wskazująca cel pytania, ułatwiająca odczytanie złożonej logiki.
- Prawidłowe kody pytań NIE powinny zaczynać się od cyfry, zatem w przypadku używania kodu pytania do ponumeruj swoje pytania, po prostu użyj „q1”, „q1a” lub „g1q2”.
- To właśnie stanie się nazwą zmiennej, jeśli eksportujesz dane do SPSS lub R. Jeśli więc przeprowadzasz analizę statystyczną, potrzebujesz do tworzenia wyłącznie unikalnych kodów pytań.
Czy muszę używać EM?
Krótka odpowiedź brzmi „nie”. Zależy to jednak w dużej mierze od złożoności ankiety, którą chcesz utworzyć.
Na przykład Edytor warunków obejmuje kilka podstawowych wyrażeń, które można zastosować do pytań w ankiecie. Edytor warunków jest jednak ograniczony. Dlatego zastosowano EM - poszerza on obszar możliwości personalizacji.
Czy mogę łączyć równania warunków i istotności?
Tak. W przypadku niektórych pytań możesz użyć Edytor warunków, a w przypadku innych Równania istotności.
W tym samym pytaniu nie można ustawić jednocześnie warunków i wyrażeń! Po ustawieniu warunku zastępuje on dowolne wyrażenie zapisane w polu równania istotności. Co więcej, pola Równanie istotności nie można już edytować ręcznie.
Istnieje jednak sposób użycia w pytaniu zarówno wyrażeń, jak i warunków. Jak wspomniano powyżej, warunek zastępuje pole równania istotności. Po zakończeniu sprawdź, jakie jest nowo utworzone równanie i skopiuj je do edytora tekstu. Usuń nowo utworzony warunek z Edytor warunków, a następnie zmodyfikuj pytanie, dodając wyrażenia oparte na warunkach z pliku edytora tekstu obok pozostałych wyrażeń, których chcesz użyć.
Jak wybrać pomiędzy Warunkami a Trafnością?
Oto lista zalet i wad każdego stylu:
Styl | Zalety | Wady |
---|---|---|
Warunki | 1. Niezłe GUI do tworzenia prostych warunków. 2. GUI dobrze udokumentowane i zrozumiałe przez zespół wsparcia |
1. Obsługuje tylko proste porównania i nie obsługuje dobrze warunków „AND” i „OR”. 2. Warunki kaskadowe działają nieprawidłowo 3. Powolny - intensywnie korzystający z bazy danych - może spowolnić długie ankiety. 4. Niektórzy zgłaszali problemy z warunkami przeładowania. 5. GUI nie skaluje się dobrze, gdy są dziesiątki, setki lub tysiące pytań. 6. Konwersja ankiet w formie papierowej może być powolna, ponieważ muszą one używać nazw SGQA. 7. Często potrzebny jest programista do tworzenia niestandardowego kodu logicznego potrzebnego do skomplikowanych rozgałęzień. |
Trafność | 1. Obsługuje bardzo złożoną logikę, w tym ponad 80 funkcji i operatorów matematycznych/łańcuchowych. 2. Doskonałe wsparcie dla logiki kaskadowej. 3. Szybko – bez dodatkowych połączeń z bazą danych, obsługując ankiety zawierające ponad 1000 pytań. 4. Nie ma problemów z przeładowaniem logiki, ponieważ nie wymaga ona kodów SGQA. 5. Skale podświetlania składni do ankiet zawierających ponad 1000 pytań. 6. Łatwy i szybki w użyciu dla grup chcących skomputeryzować istniejące ankiety w formie papierowej. 7. Z łatwością obsługuje częściowo ustrukturyzowane wywiady i badania epidemiologiczne bez konieczności korzystania z programisty. |
1. Brak GUI dla prostych warunków — zamiast tego wykorzystuje podświetlanie składni. |
{{Uwaga| Uwaga:
- Zalecamy użycie tego, co lepiej odpowiada Twoim potrzebom.
- Aby uzyskać bardziej szczegółowe wyjaśnienie funkcji EM, kliknij następujący [[EM i jego funkcje|link] ]}}
Pierwsze kroki
Najlepszym sposobem na rozpoczęcie pracy z EM jest:
- Zainstalowanie najnowszej stabilnej wersji z https://www.limesurvey.org/en/download.
- Zaimportuj i przejrzyj niektóre przykładowe ankiety.
- Przejrzyj przypadki użycia i instrukcje oraz krok- przykłady krok po kroku.
- Przejrzyj dokumentację EM (ta strona)
- Testy jednostkowe izolowanych wyrażeń (zaawansowane)
- pokazuje przykłady użycia wszystkich funkcji i operatorów EM oraz Wyniki PHP i JavaScript;
- zauważ, że istnieje kilka funkcji, które generują różne wyniki w wersjach PHP i JavaScript, więc ta strona pozwala odpowiednio zaplanować logikę EM.
- Testy jednostkowe izolowanych wyrażeń (zaawansowane)
Terminologia
Te słowa są powszechnie używane do opisu możliwości EM:
- Rozgałęzianie oparte na trafności - jeśli pytanie jest istotne, zadaj je, w przeciwnym razie nie (np. uczyń je niewidocznym i zaznacz ma wartość NULL w bazie danych). Pole Pola istotności możesz znaleźć w panelu edytora pytań, a także w panelu edytora grupy pytań. To drugie służy do zastosowania zestawu warunków do całej grupy bez konieczności kopiowania tego samego warunku do każdego pytania i/lub łączenia logiki warunkowej na poziomie grupy i pytania).
- Krawiectwo - Kiedy już wiesz, jakie pytania należy zadać, krawiectwo (czasami nazywane „lamowaniem”) określa, w jaki sposób należy zadać pytanie. Dzięki temu możesz obsługiwać nie tylko proste zastępowanie (takie jak {TOKEN:FIRSTNAME}), ale także koniugację czasowników i deklinację rzeczowników w oparciu o płeć lub liczbę tematów. Umożliwia także zmianę wiadomości dostarczanej respondentowi ankiety w oparciu o to, czy odpowiedział (lub jak odpowiedział) na inne pytania.
- 'Równania - EM dodaje nowy typ pytania o nazwie Równanie, które przechowuje wynik wyrażenia. Wyniki równania są obliczane i zapisywane w bazie danych, nawet jeśli ukryjesz je na stronie. Służą zatem do ukrytych obliczeń scoringowych, nawigacji w oparciu o złożone równania, ocen i raportów, które będą generowane i przechowywane w bazie danych.
Trafność i trafność kaskadowa
Każdy typ pytania ma teraz opcję Trafność, która kontroluje, czy pytanie jest wyświetlane, czy nie. EM przetwarza każde równanie istotności w kolejności, w jakiej pojawiają się w ankiecie. Jeśli wyrażenie jest prawdziwe (lub brakuje go w celu obsługi starszych ankiet), pytanie zostanie wyświetlone. Jeśli nie jest to istotne, pytanie zostanie ukryte, a wartość w bazie danych będzie wynosić NULL. Jeżeli w danej grupie nie ma odpowiednich pytań, cała grupa zostanie pominięta.
Co więcej, jeśli którakolwiek ze zmiennych w wyrażeniu jest nieistotna, wówczas wyrażenie zawsze ma wartość fałszywą. Umożliwia to „kaskadowe dopasowanie”, dzięki czemu nie trzeba pisać bardzo długich równań trafności dla każdego pytania.
Załóżmy, że masz pięć pytań Q1-Q5 i chcesz wyświetlić tylko pytanie Q2, jeśli udzielono odpowiedzi na pytanie 1, i pytanie 3, jeśli udzielono odpowiedzi na pytanie 2 itd. Równania istotności mogą wyglądać następująco:
Kod pytania | Trafność | Pytanie |
---|---|---|
Q1 | 1 | Jak się nazywasz? |
Q2 | Q1 | {Q1}, ile masz lat? |
Q3 | Q2 | Więc masz {Q2} lat. Czy jesteś żonaty? |
Q4 | Q3 == "T" | {Q1}, jak długo jesteś żonaty? |
Q5 | Q4 | Ile masz dzieci, {Q1}? |
Trafność na poziomie grupy
ExpressionScript obsługuje także trafność na poziomie grupy. Ułatwia to implementację pętli. Załóżmy, że chcesz zebrać informacje od maksymalnie 10 podmiotów (takich jak produkty lub osoby w gospodarstwie domowym), gdzie najpierw określasz, ile podmiotów wymaga dalszych działań (na przykład poprzez zapytanie, ile osób mieszka w gospodarstwie domowym lub sprawdzenie, które z nich ulubione produkty z długiej listy). Wiedząc, ile podmiotów wymaga dalszych działań, możesz zastosować trafność na poziomie grupy, np. {count >= 1}, {count >=2}, ... {count >= 10} dla każdej z 10 grup obserwacji zadać pytania. W każdej grupie można zastosować logikę warunkową na poziomie pytania (np. pytania uzupełniające dotyczące płci lub wieku dla każdego przedmiotu). Równania dotyczące pytania i istotności na poziomie grupy są poddawane operacji AND w celu ustalenia, które z nich powinny zostać pokazane.
Aby sprawdzić taki przykład, zaimportuj następującą ankietę: Przykład ankiety Census.
Na poniższym zrzucie ekranu można zauważyć, że grupa „Osoba 1” jest wyświetlana (lub istotna), jeśli respondent mieszka co najmniej z innym konkubentem:
Krawiectwo/Wyszywanie
Wszystko w nawiasach klamrowych jest teraz traktowane jako wyrażenie (z jednym wyjątkiem opisanym poniżej). Wyrażenia mają dostęp do wszystkich pól i zmiennych LimeReplacementField (poprzez kilka aliasów), wszystkich typowych operatorów równań (matematycznych, logicznych i porównawczych) oraz do dziesiątek funkcji (które działają nawet dynamicznie po stronie klienta).
Korzystając z tych równań, możesz:
- Warunkowo wyświetlać respondentom dostosowane wiadomości na podstawie wcześniejszych odpowiedzi;
- Tworzyć oceny i wyświetlać wyniki ocen (lub warunkowo rozgałęziać lub wyświetlać wiadomości) na podstawie tych wyników , wszystko bez użycia samego modułu ocen;
- Odmieniaj czasowniki i odmieniaj rzeczowniki w pytaniach, odpowiedziach i raportach;
- Pokazuj podsumowania odpowiedzi przed stroną „Pokaż swoje odpowiedzi” na stronie koniec ankiety.
Równania
Dostępny jest nowy typ pytania o nazwie Równanie. Pomyśl o tym jako o Typ pytania z wyświetlaniem tekstu, z tą różnicą, że przechowuje wartość tego, co jest wyświetlane w bazie danych. Zatem jeśli tekst pytania dotyczącego równania zawiera obliczenie oceny, wartość ta będzie przechowywana w bazie danych w postaci zmiennej, która może być wyświetlana w statystykach publicznych lub prywatnych.
Składnia
Wszystko zawarte w nawiasach klamrowych jest teraz uważane za wyrażenie (z jednym wyjątkiem: „nie może być żadnych początkowych ani końcowych białych znaków” – jest to potrzebne, aby mieć pewność, że ExpressionScript nie będzie próbował przetwarzać osadzonego kodu JavaScript).
Należy pamiętać, że wyrażenia mogą obejmować wiele linii, pod warunkiem że po otwierającym nawiasie klamrowym lub przed zamykającym nawiasem klamrowym nie ma białych znaków. Jest to szczególnie przydatne w przypadku zagnieżdżonych instrukcji „if()”, takich jak ta:
{if(is_empty(PFTotals),
'',
if(PFTotals >= -5 && PFTotals <= -4,
'Bardzo miękkie',
if(PFTotals >= -3 && PFTotals <= -2,
'Miękkie',
if(PFTotals == -1,
'Nieco miękkie',
if(PFTotals == 0,
'Umiarkowane',! N! if(PFTotals == 1,
'Dość trudne',
if(PFTotals >= 2 && PFTotals <= 3,
'Trudne',
if(PFTotals >= 4 && PFTotals <= 5,
„Bardzo trudne”,
''
)
)
)
)
)
)
)
)}
ExpressionScript obsługuje następującą składnię:
- Wszystkie standardowe operatory matematyczne (np. +,-,*,/,!);
- Wszystkie standardowe operatory porównania (np. <,<=,==,!=,> ,>=, plus ich odpowiedniki: lt, le, eq, ne, gt, ge);
- Nawiasy (dzięki czemu można grupować podwyrażenia);
- Operatory warunkowe (np. &&,| | i ich odpowiedniki: i, lub);
- Ciągi z pojedynczym i podwójnym cudzysłowem (z których każdy może osadzić ciągi znaków z innym typem cudzysłowu);
- Operator przecinka (więc może mieć listę wyrażeń i po prostu zwrócić wynik końcowy );
- Operator przypisania (=);
- Predefiniowane zmienne (odnoszące się do pytań, atrybutów pytań i odpowiedzi) - np. kody SGQA;
- Predefiniowane funkcje (jest ich już ponad 80 i łatwo jest dodać kolejne).
Operatorzy
Składnia EM jest zgodna z normalnym pierwszeństwem operatora:
Poziom | Operator(y) | Opis |
---|---|---|
1 | () | nawiasy do grupowania lub wywoływania funkcji |
2 | ! - + | operatory jednoargumentowe: nie, negacja, jednoargumentowy plus |
3 | * / | razy, dzielenie |
4 | + - | plus , minus |
5 | < <= > >= lt le gt ge | porównania względne |
6 | == != równanie ne | porównania równości |
7 | i | logiczne AND |
8 | lub | logiczne OR |
9 | = | przypisanie operator |
10 | , | operator przecinka |
Ostrzeżenie dotyczące niezgodności numeru i ciągu znaków oraz porównania alfabetycznego/numerycznego
Jeśli chcesz porównać wartość za pomocą porównań względnych lub równościowych, zwróć uwagę na niedopasowania. Wartość wprowadzona przez użytkownika (lub podana poprzez kod odpowiedzi) może zostać użyta jako liczba, „jeśli jest to wyraźnie liczba”.
Jeśli otoczysz jedną z wartości znakiem "
, nastąpi porównanie tekstu/ciągu znaków miejsce. Jeśli chcesz porównać jako liczbę, nigdy nie otaczaj liczby znakiem "
.
Na przykład Q0.NAOK > "50"
jest prawdą, jeśli Q0.NAOK jest pytaniem numerycznym z wartością 9. Dzieje się tak, ponieważ operator >
przyjmie, że jest to porównanie alfabetyczne , a nie numeryczne .
Aby mieć pewność, że porównujesz wartości całkowite, możesz użyć intval(Q0.NAOK) > 50
. Pamiętaj tylko, jeśli Q0.NAOK nie jest liczbą (pustą lub ciągiem znaków), to intval(Q0.NAOK) === 0. Aby porównać wartości ciągów („A” < „B”) użyj strcmp bezpośrednio : strcmp(Q0.NAOK,"B")
lub strcmp(Q0.NAOK,"A5")
.
Uwaga dotycząca używania operatora przypisania (=)
Powinieneś unikać używania operatorów przypisania, chyba że jest to absolutnie konieczne, ponieważ mogą one powodować nieoczekiwane skutki uboczne. Na przykład, jeśli zmienisz wartość poprzedniej odpowiedzi, kaskadowa trafność i logika walidacji między tym pytaniem a bieżącym pytaniem nie zostaną ponownie obliczone, więc możesz otrzymać wewnętrznie niespójne dane (np. pytania, na które nie udzielono odpowiedzi, ale należy mają wartość NULL lub pytania, które zostały pominięte, ale należało odpowiedzieć). Ogólnie rzecz biorąc, jeśli chcesz przypisać wartość zmiennej, powinieneś utworzyć pytanie typu Równanie i użyć wyrażenia, aby ustawić jego wartość. Jednak w rzadkich przypadkach ludzie naprawdę potrzebują tego operatora, dlatego udostępniliśmy go.
Aby ostrzec Cię przed tym operatorem, w równaniach składniowych jest on pokazany czerwoną czcionką (aby nie pomylić go z „==”).
Używanie operatora przypisania
Główne powody, dla których możesz chcieć użyć operatora przypisania to:
- Musisz ustawić wartość domyślną za pomocą równania dla pytania, które nie akceptuje wartości domyślnych (takich jak radio list, gdzie interfejs użytkownika pozwala wybrać jedną z opcje odpowiedzi, ale nie pozwala na wprowadzenie równania). Jednak bądź ostrożny, ponieważ LimeSurvey nie będzie w stanie sprawdzić, czy Twoje równanie generuje jedną z dopuszczalnych odpowiedzi na to pytanie;
- Musisz na siłę zmienić odpowiedź na poprzednie pytanie w oparciu o późniejszą odpowiedź;
* itd...
Można w tym celu wykorzystać cały system zarządzania wyrażeniami. Lepiej jest użyć w tym celu Equation.
Kilka przykładów:
- Ustaw odpowiedź na pytanie z krótkim tekstem małymi literami:
{QCODE=strtolower(QCODE.NAOK)}
; - Ustaw domyślną odpowiedź na pytanie typu tablicowego na początku ankiety:
{Q1_SQ1=(is_empty(Q1_SQ1.NAOK),"A99",Q1_SQ1.NAOK)}
; - Ustaw domyślną odpowiedź na pytanie typu tablica tekstowa na początku ankiety:
{Q1_SQY1_SQX1 = (is_empty(Q1_SQY1_SQX1.NAOK),"Inserted answer", Q1_SQY1_SQX1.NAOK)}
; - Ustaw odpowiedź z warunkiem:
{QCODE=if(YesNo="Y","A1","")}
.
Bezpieczeństwo XSS
Gdy włączono XSS, nie można używać niektórych części systemu menedżera wyrażeń:
- rozpoczynanie znacznika HTML w wyrażeniu, ale kończące się na innym wyrażeniu;
- używanie złożonego wyrażenia w adresie URL .
<html>Przykłady i obejścia:
{if( 1 ,"","")}information{if( 1 ,"","")}
jest uszkodzona przez zabezpieczenia XSS, tutaj możesz użyć{if(1," ;
<strong>information</strong>","information")}
;
<a href="/script.php?value={if(QCODE == "Y","yes","no")}">next</a>
, here you can use an equation question because using a complete question code is OK :<a href="/script.php?value={EQUATION.NAOK}">next</a>
. information","information")}{if(1," ;
<a href="/script.php?value={if(QCODE == "Y","yes","no")}">next</a>
, here you can use an equation question because using a complete question code is OK :<a href="/script.php?value={EQUATION.NAOK}">next</a>
.
Dostęp do zmiennych
ExpressionScript zapewnia dostęp tylko do odczytu do dowolnych zmiennych, których możesz potrzebować. Dla kompatybilności wstecznej zapewnia dostęp do:
- TOKEN:xxx - wartość TOKENA (np. TOKEN:FIRSTNAME, TOKEN:ATTRIBUTE_5) (tylko dla 'nie ' ankieta anonimowa).
- INSERTANS:SGQA - wartość wyświetlana odpowiedzi (np. "Tak") - podobnie jak przy użyciu {QCODE.showown }.
- Wszystkie {XXX} wartości używane przez szablony.
- W tekście pytania możesz użyć {QID} zastąpionego identyfikatorem pytania i {SGQ} zastąpionego przez SGQA pytania.
Ponadto ExpressionScript umożliwia odwoływanie się do zmiennych za pomocą kodu pytania (kolumna „tytuł” w tabeli pytań w bazie danych). Jest to również etykieta zmiennej używana podczas eksportowania danych do SPSS, R lub SAS. Na przykład, jeśli masz pytania dotyczące imienia, wieku i płci, możesz nazwać te zmienne „imięm”, „wiek” i „płeć” zamiast „12345X13X22”, „12345X13X23”. ' i 12345X13X24. Ułatwia to każdemu odczytywanie i sprawdzanie logiki równań, a także umożliwia tasowanie pytań bez konieczności śledzenia numerów grup lub pytań.
Ważne: Bezpieczniej jest odwoływać się do zmiennych, które występują na poprzednich stronach lub w pytaniach.
Ponadto ExpressionScript umożliwia dostęp do wielu właściwości pytania:
Składnia | Znaczenie | Przykład | Przykład Wynik | ||||
---|---|---|---|---|---|---|---|
Qcode | alias dla Qcode.code | {implode(',',name,gender )} | 'Tom','M' | ||||
Qcode.code | wybrany kod odpowiedzi na pytanie, jeśli jest istotne (w przeciwnym razie puste) lub wartość tekstowa, jeśli nie jest to zakodowane pytanie | {implode(',',name.code,gender.code)} | 'Tom','M' | ||||
Qcode.NAOK | tak samo jak Qcode - zobacz dyskusję NAOK | {gender.NAOK} | 'M' | ||||
Qcode.value | wartość oceny dla pytania, jeśli jest istotne (w przeciwnym razie puste) lub wartość tekstowa, jeśli nie jest zakodowane pytanie | {gender.value} | '1' | ||||
Qcode.valueNAOK | tak samo jak Qcode.value - zobacz dyskusję o NAOK | {gender.valueNAOK} | '1 ' | ||||
Qcode.shown | wyświetlana wartość pytania | {implode(',',imię.pokazana,płeć.pokazana)} | - | Qcode.question | tekst pytania | {gender.question} | 'Jaka jest Twoja płeć?' |
Qcode.mandatory | czy pytanie jest obowiązkowe (T/N) | {gender.mandatory} | 'N' | ||||
Qcode.qid | wewnętrzny numer pytania (nie numer kolejny) | {gender.qid} | 337 | ||||
Qcode.type | typ pytania | {gender.type} | 'G' | ||||
Qcode.jsName | poprawna nazwa JavaScript na pytanie, niezależnie od tego, czy zadeklarowano je na tej stronie, czy poza nią | {gender.jsName} | 'java1827X3X337' | ||||
Qcode.gid | numer grupy wewnętrznej (nie numer kolejny) | {gender.gid} | 3 | ||||
Qcode.qseq | numer kolejny pytania, zaczynający się od 0 | {gender.qseq} | 5 | ||||
Qcode.gseq | numer kolejny grupy, zaczynając od 0 | {gender.gseq} | 1 | ||||
Qcode.relevanceStatus | czy pytanie jest aktualnie istotne (0 czy 1 ) | {gender.relevanceStatus} | 1 | ||||
Qcode.relevance | równanie trafności na poziomie pytania | {gender.relevance} | '!is_empty(name)' | ||||
Qcode.grelevance | równanie istotności na poziomie grupy | {gender.grelevance} | 'num_children >= 5' | ||||
Qcode.sgqa | wartość SGQA dla to pytanie | {gender.sgqa} | '1827X3X337' |
Problem z edytorem HTML
Jeśli używasz edytora HTML, niektóre znaki są zastępowane przez elementy HTML.
- & przez &
- < przez <
- > przez >
Jeśli używasz edytora HTML, musisz użyć :
- i for &
- lt for <
- le for <=
- gt for >
- ge dla >=
Zaleca się wyczyszczenie wyrażenia z kodu HTML występującego w wyrażeniu. Jeśli korzystasz z edytora HTML LimeSurvey, kliknij przycisk „Źródło” (znajdujący się w lewej górnej części edytora) i usuń wszystkie znaki niezwiązane z Twoim wyrażeniem (np.
,
, i tak dalej).
Nazewnictwo zmiennych Qcode
Oto szczegóły dotyczące tworzenia Qcode (i uzyskiwania dostępu do niektórych właściwości) według typu pytania. Ogólnie rzecz biorąc, kody Q są zbudowane jako:
Kod pytania. „_” . Identyfikator podpytania . „_” . Identyfikator skali
W przypadku „komentarza” i „innego” odpowiednimi kodami pytań są odpowiednio: „QuestionCode_comment” i „QuestionCode_other”.
Typ | Opis | Kod | SubQs | Opcje odpowiedzi | Skale | Kod odpowiedzi | Wyświetlona odpowiedź | Trafność |
---|---|---|---|---|---|---|---|---|
5 | 5 Przyciski opcji wyboru punktu | Q1 | 1-5 | {Q1} | {Q1.pokazane} | {Q1==3} | ||
B | Tablica (wybór 10 punktów) Przyciski opcji | Q2 | |1-10 | {Q2_L2} | {Q2_L2.pokazane} | {Q2_L2==7} | ||
A | Przyciski opcji Tablica (wybór 5 punktów) | Q3 | |1-5 | {Q3_1} | {Q3_1.pokazane} | {Q3_1>=3} | ||
1 | Tablica (Elastyczne etykiety) Podwójna skala | Q4 | sq1-sq5 | 0 :a1-a3 | 1:b1-b3 | {Q4_sq1_0} | {Q4_sq1_1.pokazane} | {Q4_sq1_1=='b2'} |
H | Tablica (elastyczna) - Format kolumny | Q5 | 1-5 | s,m,t | {Q5_1} | {Q5_1.pokazane} | {Q5_1=='} | |
F | Tablica (elastyczna) - format wierszy | Q6 | |1-5 | {Q6_F3} | {Q6_F3.pokazane} | {Q6_F3==4} | ||
E | Tablica (Zwiększ/Tak samo/Zmniejsz) Przyciski opcji | Q7 | 1- 7 | I,S,D | {Q7_4} | {Q7_4.pokazane} | {Q7_4=='D'} | |
: | Tablica (Multi Flexi) 1 do 10 | Q8 | ls1,do zrobienia ,ls2 | min,maks.,średnia | {Q8_ls1_max} | {Q8_ls2_avg.show} | {Q8_ls2_min==7} | |
; | Tablica (Multi Flexi) Tekst | Q9 | hp,st,sw | 1., 2., 3. | {Q9_hp_3rd} | {Q9_hp_3rd.pokazane} | {Q9_hp_3rd=='Peter'} | |
C | Tablica (Tak/Niepewne/Nie) Przyciski opcji | Q10 | 1-5 | T,N,U | {Q10_1} | {Q10_1.pokazane} | {Q10_3=='Y'} | |
X | Pytanie standardowe | Q11 | {Pokazane Q11} | |||||
D | Data | Q12 | {Q12} | {Q12.pokazane} | ||||
* | Równanie | Q13 | {Q13} | {Q13.pokazane} | {Q13>5} | |||
~124~ | Przesłanie pliku (rejestruje liczbę przesłanych plików) | Q14 | {Q14} | {Q14>0} | ||||
G | Lista rozwijana płci | Q15 | M,F | {Q15} | {Q15.pokazany} | {Q15=='M'} | ||
U | Duży dowolny tekst | Q16 | {Q16} | {Q16.pokazane} | {strlen(Q16)>100} | |||
I | Pytanie dotyczące języka | Q17 | {Q17} | {Q17.pokazane} | {Q17=='en'} | |||
! | Lista - menu rozwijane | Q18 | 1-5 | {Q18} | {Q18.pokazane} | {Q18==3} | ||
L | Lista rozwijana/lista przycisków radiowych | Q19 | AZ | {Q19} | {Q19.show} | {Q19=='X'} | ||
O | Lista z rozwijanym menu komentarzy/listą przycisków radiowych + obszar tekstowy | Q20 | AF | {Q20},{Q20comment} | {Q20.pokazane} | {Q20=='B'} | ||
T | Długi tekst dowolny | Q21 | {Q21} | {Q21.pokazane} | {strstr(Q21,'witaj')>0} | |||
M | Pole wyboru wielokrotnego wyboru | Q22 | | | {Q22_E}, {Q22_other} | {Q22_E.pokazane}, {Q22_other.pokazane} | {Q22_E=='Y'} | ||
P | Wielokrotny wybór z komentarzami Pole wyboru + Tekst | Q23 | AF | {Q23_D}, {Q23_Dcomment} | {Q23_D.pokazane} | {!is_empty(Q23)} | ||
K | Pytanie z wieloma liczbami | Q24 | ja, mama, tata | {Q24_self} | {Q24_self.show} | {Q24_self>30} | ||
Q | Kilka krótkich tekstów | Q25 | AF | {Q25_B} | {Q25_B.pokazane} | {substr(Q25_B,1,1)=='Q'} | ||
N | Numeryczny typ pytania | Q26 | {Q26} | {Q26.pokazane} | {Q26 > 30} | |||
R | Styl rankingu | Q27 | 1-4 | {Q27_1} | {Q27_1.pokazane} | {Q27_1==3} | ||
S | Krótki tekst dowolny | Q28 | {Q28} | {Q28.pokazane} | {Q28=='moje'} | |||
T | Przyciski opcji Tak/Nie | Q29 | {Q29} | {Q29.pokazane} | {Q29=='T'} |
Wykorzystanie NAOK
NAOK --> „Nie dotyczy” (NA) jest w porządku (OK)
Użycie NAOK oznacza, że wszystkie lub niektóre zmienne są nieistotne (np. „Nie dotyczy” (NA) jest w porządku (OK)).
Na przykład: count(Q1_SQ1,Q1_SQ2,Q1_SQ3,Q1_SQ4) podaj zawsze pusty ciąg znaków, jeśli filtrowane jest jedno pytanie podrzędne Q1. Aby policzyć liczbę sprawdzanych podpytań w takim pytaniu można liczyć(Q1_SQ1.NAOK,Q1_SQ2.NAOK ,Q1_SQ3.NAOK,Q1_SQ4.NAOK). Jeśli pytanie podrzędne jest ukryte, EM zwraca pusty ciąg znaków.
Bez NAOK, jeśli jedno pytanie lub jedno pytanie podrzędne jest ukryte, EM zwraca zawsze pusty ciąg znaków (tak samo, jak zwracanie fałszu).
.pokazane zawsze używają systemu NAOK (pusty ciąg znaków, jeśli jest ukryty), ale jeśli potrzebujesz kodu odpowiedzi: zawsze dobrze jest dodać .NAOK po kodzie pytania (z wyjątkiem sytuacji, gdy jest to potrzebne i wiesz, co robisz).
Więcej informacji można znaleźć w podsekcji Przesłanianie warunków kaskadowych.
Zarezerwowane zmienne „to”, „ja” i „tamto”
Dość często chcesz ocenić wszystkie części pytania, na przykład policzyć, na ile pytań podrzędnych udzielono odpowiedzi lub podsumować wyniki. Innym razem chcesz przetworzyć tylko określone wiersze lub kolumny pytania (np. uzyskać sumy wierszy lub kolumn i zapisać je w bazie danych). Te zarezerwowane zmienne sprawiają, że proces ten jest stosunkowo bezbolesny.
"Ta" zmienna
Zmienna „to” jest używana wyłącznie w opcjach „Równanie walidacji całego pytania” i „Równanie walidacji podpytania” (ta ostatnia nie jest możliwe z GUI). Rozwija się do nazw zmiennych każdej komórki w tych pytaniach. Jeśli więc chcesz mieć pewność, że każdy wpis jest większy niż trzy, ustaw „Równanie sprawdzania poprawności podpytania” na (to > 3).
"Zmienna własna"
Zmienne „ja” i „to” mają większe możliwości i służą jako makra, które są rozwijane przed przetwarzaniem równań. Możliwości składni zmiennej „self” są następujące:
- self
- self.sufiks
- self.podselektor
- self.sub- selektor.przyrostek
- sufiks to dowolny z normalnych przyrostków qcode (np. NAOK, wartość, pokazana)
- podselektor może być jedną z następujących opcji:
- komentarze - tylko pytania podrzędne będące komentarzami (np. wielokrotny wybór z komentarzem i lista z komentarzem);
- nocomments - tylko pytania podrzędne, które nie są komentarzami;
- sq_X - gdzie X jest identyfikatorem wiersza lub kolumny. Wybierane są tylko pytania podrzędne pasujące do wzorca X. Zauważ, że wyszukiwanie odbywa się na podstawie pełnego identyfikatora kodu, następnie sq_X dopasowuje i uwzględnia podpytania nX, X, Xn (np. jeśli używasz sq_1, uwzględniono podpytania a1, 1a, 1, 11 lub 001). Zwróć uwagę na typ pytania o podwójnej skali, gdzie kody pytań podrzędnych to QCODE_SQCODE_1 i QCODE_SQCODE_1 oraz na typ pytania rankingowego, gdzie kody pytań podrzędnych to QCODE_1, QCODE_2 ....
Przykłady:
- Czy udzielono odpowiedzi na jakąkolwiek część pytania? -> {count(self.NAOK)>0}
- Jaki jest wynik oceny tego pytania? -> {suma(wartość własna)}
Można ich także użyć do uzyskania sumy wierszy i kolumn. Załóżmy, że masz tablicę liczb z wierszami AE i kolumnami 1–5.
- Jaka jest suma całkowita? -> {sum(self.NAOK)}
- Jaka jest suma wiersza B? -> {sum(self.sq_B.NAOK)}
- Jaka jest suma kolumny 3? -> {suma(self.sq_3.NAOK)}
"Ta" zmienna
Zmienna „to” jest podobna do zmiennej „ja”, ale pozwala na odniesienie się do innych pytań. Jego składnia jest następująca:
- to.qnazwa
- tam.qnazwa.przyrostek
- to.qnazwa.podselektor' '
- to.qname.podselektor.sufiks
„qname” to nazwa pytania bez żadnych rozszerzeń podpytań. Stwórzmy więc pytanie „q1”, „q” reprezentujące również jego „qname”.
Examples:
- Has any part of question q1 been answered? -> {count(that.q1.NAOK)>0}
- What is the assessment score for q2? -> {sum(that.q2.NAOK)}
- What is the grand total of q3? -> {sum(that.q3.NAOK)}
- What is the total of row C in q4? -> {sum(that.q4.sq_C.NAOK)}
- What is the total of column 2 in q4? -> {sum(that.q4.sq_2.NAOK)}
The "self" and "that" variables can be used in any relevance, validation, or tailoring.
The one caveat is that when you use the Show logic file feature, it will show you the expanded value of "self" and "that". This lets you see the actual equation that will be generated so that you (and the EM) can validate whether the variables exist or not. This may seem confusing since you may see quite lengthy equations. However, if you edit the question, you will see the original equation using "self" and/or "that".
- you want to explicitly name each variable used in an equation, or
- use variables that do not have subquestions (e.g., single response questions). In those cases, prefixing a variable with "that" is overkill, and you run the risk of getting unexpected results.
Access to functions
The ExpressionScript provides access to mathematical, string, and user-defined functions, as shown below. It has PHP and JavaScript equivalents for these functions so that they work identically on server-side (PHP) and client-side (JavaScript). It is easy to add new functions.
Implemented functions
The following functions are currently available:
Function | Meaning | Syntax |
---|---|---|
abs | Absolute value | number abs(number) |
acos | Arc cosine | number acos(number) |
addslashes | Quote string with slashes | string addslashes(string) |
asin | Arc sine | number asin(number) |
atan | Arc tangent | number atan(number) |
atan2 | Arc tangent of two variables | number atan2(number, number) |
ceil | Round fractions up | number ceil(number) |
checkdate | Returns true(1) if it is a valid date in gregorian calendar | bool checkdate(month,day,year) |
convert_value | Convert a numerical value using a inputTable and outputTable of numerical values | number convert_value(fValue, iStrict, sTranslateFromList, sTranslateToList) |
cos | Cosine | number cos(number) |
count | count the number of answered (non-blank) questions in the list | number count(arg1, arg12, ..., argN) |
countif | Count the number of answered questions in the list equal to the first argument | number countif(matches, arg1, arg2, ... argN) |
countifop | Count the number of answered questions in the list which pass the criteria (arg op value) | number countifop(op, value, arg1, arg2, ... argN) |
date | Format a local date/time | string date(format [, timestamp=time()]) |
exp | Calculates the exponent of e | number exp(number) |
fixnum | Display numbers with comma as radix separator, if needed | string fixnum(number) |
floor | Round fractions down | number floor(number) |
gmdate | Format a GMT date/time | string gmdate(format [, timestamp=time()]) |
html_entity_decode | Convert all HTML entities to their applicable characters (always uses ENT_QUOTES and UTF-8) | string html_entity_decode(string) |
htmlentities | Convert all applicable characters to HTML entities (always uses ENT_QUOTES and UTF-8) | string htmlentities(string) |
expr_mgr_htmlspecialchars | Convert special characters to HTML entities (always uses ENT_QUOTES and UTF-8) | string htmlspecialchars(string) |
expr_mgr_htmlspecialchars_decode | Convert special HTML entities back to characters (always uses ENT_QUOTES and UTF-8) | string htmlspecialchars_decode(string) |
idate | Format a local time/date as integer | string idate(string [, timestamp=time()]) |
if | Excel-style if(test,result_if_true,result_if_false) | if(test,result_if_true,result_if_false) |
implode | Join array elements with a string | string implode(glue,arg1,arg2,...,argN) |
intval | Get the integer value of a variable | int intval(number [, base=10]) |
is_empty | Determine whether a variable is considered to be empty | bool is_empty(var) |
is_float | Finds whether the type of a variable is float | bool is_float(var) |
is_int | Find whether the type of a variable is integer | bool is_int(var) |
is_nan | Finds whether a value is not a number | bool is_nan(var) |
is_null | Finds whether a variable is NULL | bool is_null(var) |
is_numeric | Finds whether a variable is a number or a numeric string | bool is_numeric(var) |
is_string | Find whether the type of a variable is string | bool is_string(var) |
join (New in 2.0 build 130129) | Join elements as a new string | join(arg1, arg2, ... argN) |
list | Return comma-separated list of non-blank values | string list(arg1, arg2, ... argN) |
listifop (New in 3.16.1 ) | Return a 'glue'-separated list of the specified question property (retProp) from questions in the list which pass the criteria (cmpProp op value) | string listifop(cmpProp, op, value, retProp, glue, sgqa1, sgqa2, ... sgqaN) |
ltrim | Strip whitespace (or other characters) from the beginning of a string | string ltrim(string [, charlist]) |
max | Find highest value | number max(arg1, arg2, ... argN) |
min | Find lowest value | number min(arg1, arg2, ... argN) |
mktime | Get UNIX timestamp for a date (each of the 6 arguments are optional) | number mktime([hour [, minute [, second [, month [, day [, year ]]]]]]) |
modulo-function | The modulo function is not supported yet. You can use the floor() function instead | floor(x/y)==(x/y) |
nl2br | Inserts HTML line breaks before all newlines in a string | string nl2br(string) |
number_format | Format a number with grouped thousands | string number_format(number) |
pi | Get value of pi | number pi() |
pow | Exponential expression | number pow(base, exp) |
quoted_printable_decode | Convert a quoted-printable string to an 8 bit string | string quoted_printable_decode(string) |
quoted_printable_encode | Convert a 8 bit string to a quoted-printable string | string quoted_printable_encode(string) |
quotemeta | Quote meta characters | string quotemeta(string) |
rand | Generate a random integer, see this example | int rand() OR int rand(min, max) |
regexMatch | compare a string to a regular expression | bool regexMatch(pattern,input) |
round | Rounds a number to an optional precision | number round(val [, precision]) |
rtrim | Strip whitespace (or other characters) from the end of a string | string rtrim(string [, charlist]) |
sin | Sine | number sin(arg) |
sprintf | Return a formatted string | string sprintf(format, arg1, arg2, ... argN) |
sqrt | Square root | number sqrt(arg) |
stddev | Calculate the Sample Standard Deviation for the list of numbers | number stddev(arg1, arg2, ... argN) |
str_pad | Pad a string to a certain length with another string | string str_pad(input, pad_length [, pad_string]) |
str_repeat | Repeat a string | string str_repeat(input, multiplier) |
str_replace | Replace all occurrences of the search string with the replacement string | string str_replace(search, replace, subject) |
strcasecmp | Binary safe case-insensitive string comparison | int strcasecmp(str1, str2) |
strcmp | Binary safe string comparison | int strcmp(str1, str2) |
strip_tags | Strip HTML and PHP tags from a string | string strip_tags(str, allowable_tags) |
stripos | Find position of first occurrence of a case-insensitive unicode string (starting by 0, return false if not found) | int stripos(haystack, needle [, offset=0]) |
stripslashes | Un-quotes a quoted string | string stripslashes(string) |
stristr | Case-insensitive strstr | string stristr(haystack, needle [, before_needle=false]) |
strlen | Get string length | int strlen(string) |
strpos | Find position of first occurrence of an unicode string (starting by 0, return false if not found) | int strpos(haystack, needle [ offset=0]) |
strrev | Reverse a string | string strrev(string) |
strstr | Find first occurrence of a string | string strstr(haystack, needle[, before_needle=false]) |
strtolower | Make a string lowercase | string strtolower(string) |
strtotime | Parse about any English textual datetime description into a Unix timestamp | int strtotime(string) |
strtoupper | Make a string uppercase | string strtoupper(string) |
substr | Return part of an unicode string | string substr(string, start [, length]) |
sum | Calculate the sum of values in an array | number sum(arg1, arg2, ... argN) |
sumifop | Sum the values of answered questions in the list which pass the criteria (arg op value) | number sumifop(op, value, arg1, arg2, ... argN) |
tan | Tangent | number tan(arg) |
time | Return current UNIX timestamp | number time() |
trim | Strip whitespace (or other characters) from the beginning and end of a string | string trim(string [, charlist]) |
ucwords | Uppercase the first character of each word in a string | string ucwords(string) |
unique | Returns true if all non-empty responses are unique | boolean unique(arg1, ..., argN) |
Create new expression functions with plugin (New in 4.0.0 )
If you need a new function that doesn't exist in core, you can create one with a plugin. Such a new function is created using the expressionManagerStart event.
ExpressionScript knows which variables are local
In order to properly build the JavaScript for a page, EM needs to know which variables are set on the page, and what their JavaScript ID is (e.g., for document.getElementById(x)). It must also know which variables are set on other pages (so that it can ensure that the needed <input type='hidden' value='x'> fields are present and populated).
Cascading Conditions
If any of the variables are irrelevant, the whole equation will be irrelevant (false). For example, in the following table, N/A means that one of the variables was not relevant:
Operator | Example | a | b | Result |
---|---|---|---|---|
+ (unary) | +a | N/A | false | |
! | !a | N/A | false | |
== (or eq) | a == b | N/A | 5 | false |
== (or eq) | a == b | N/A | 0 | false |
== (or eq) | a == b | N/A | N/A | false |
!= (or ne) | a != b | N/A | 5 | false |
!= (or ne) | a != b | N/A | N/A | false |
!= (or ne) | a != b | N/A | 0 | false |
> (or gt) | a > b | N/A | 5 | false |
>= (or ge) | a >= b | N/A | 5 | false |
< (or lt) | a < b | N/A | 5 | false |
<= (or le) | a <= b | N/A | 5 | false |
and | a and b | N/A | 5 | false |
and | a and b | N/A | N/A | false |
or | a or b | N/A | N/A | false |
or | a or b | N/A | 5 | false |
+ | a + b | N/A | 5 | false |
* | a * b | N/A | 5 | false |
/ | a / b | 5 | N/A | false |
() | (a) | N/A | false | |
(exp) | (a && b) | N/A | 5 | false |
(exp) op (exp) | (b + b) > (a && b) | N/A | 5 | false |
function | sum(a,b,b) | N/A | 5 | false |
function | max(a,b) | N/A | 5 | false |
function | min(a,b) | N/A | 5 | false |
function | implode(', ',a,b,a,b) | N/A | 5 | false |
function | if(a,a,b) | N/A | 5 | false |
function | is_empty(a) | N/A | false | |
function | is_empty(a) | 0 (or blank) | true | |
function | !is_empty(a) | N/A | false |
Overriding Cascading Conditions
Say you want to show a running total of all relevant answers. You might try to use the equation {sum(q1,q2,q3,...,qN)}. However, this gets translated internally to LEMif(LEManyNA("q1","q2","q3",...,"qN"),"",sum(LEMval("q1"),LEMval("q2"),LEMval("q3"),...,LEMval("qN"))). So, if any of the values q1-qN are irrelevant, the equation will always return false. In this case, the sum() will show "0" until all questions are answered.
To get around this, each variable can have a ".NAOK" suffix (meaning that Not Applicable is OK) added to it. In such cases, the following behavior occurs. Say you have a variable q1.NAOK:
- q1 is not added to the LEManyNA() clause
- LEMval('q1') will continue to check whether the response is relevant and will return "" if it is not (so individual irrelevant responses will be ignored, but they will not void the entire expression).
So, the solution to the running total problem is to use the equation sum(q1.NAOK,q2.NAOK,q3.NAOK,...,qN.NAOK).
The use of the .NAOK suffix also lets authors design surveys that have several possible paths but then converge on common paths later. For example, say subjects answer a survey in a way that is outside the normal range of responses. The author could alert the subjects that they may not get valid results, and ask them whether they really want to continue with the survey. If they say "Yes", then the rest of the questions will be shown. The condition for the "rest of the questions" would check whether the initial responses were answered within the normal range OR whether the subject said "Yes" to the question that is only relevant if they answered outside the normal range.
How does ExpressionScript support conditional micro-tailoring?
Here is an example of micro-tailoring (where Question Type=='expr' means an Equation):
Question Code | Relevance | Question Type | Question |
---|---|---|---|
name | 1 | text | What is your name? |
age | 1 | text | How old are you? |
badage | !is_empty(age) | expr | {(age<16) or (age>80)} |
agestop | badage | message | Sorry, {name}, you are too {if( (age<16),'young',if( (age>80),'old','middle-aged') ) } for this test. |
kids | !badage | yesno | Do you have children? |
parents | 1 | expr | {!badage && kids=='Y'} |
numKids | parents | text | How many children do you have? |
kid1 | parents && numKids >= 1 | text | How old is your first child? |
kid2 | parents && numKids >= 2 | text | How old is your second child? |
kid3 | parents && numKids >= 3 | text | How old is your third child? |
kid4 | parents && numKids >= 4 | text | How old is your fourth child? |
kid5 | parents && numKids >= 5 | text | How old is your fifth child? |
sumage | 1 | expr | {sum(kid1.NAOK,kid2.NAOK,kid3.NAOK,kid4.NAOK,kid5.NAOK)} |
report | parents | text | {name}, you said you are {age} and that you have {numKids}. The sum of ages of your first {min(numKids,5)} kids is {sumage} |
To download the above survey example, click on the following link: Number of kids survey example.
All of these questions can be on a single page (e.g., in the same group), and only the relevant questions will be displayed. Moreover, as you enter the ages of children, the sum() expression in the last question will dynamically get updated.
ExpressionScript provides this functionality by surrounding each expression with a named <span> element. Every time a value changes, it recomputes the expression that should appear in that <span> element and regenerates the display. You can have dozens or even hundreds of such tailored expressions on the same page.
Syntax highlighting
To help with entering and validating expressions, the EM provides syntax highlighting with the following features:
Types and Meanings of Syntax Highlighting
Color | Sample | Meaning | Tooltip | Comments |
---|---|---|---|---|
tan background | Sample | the whole equation | none | Anything within curly braces that is recognized as an equation (e.g., there is no leading or trailing whitepace) will be color-coded with a tan background to help distinguish it from surrounding text |
bold red text | Sample | An error | Some explanation on error | Can be an unknow variable or an error in function. Survey is broken and the questions that rely on the respective expression will not be shown to the respondents. |
blue text | Sample | function name | meaning and allowable syntax | It refers to function names or things that should be functions since they are followed by an open parenthesis. They are displayed in bold blue text. Tooltips show the meaning and allowable syntax for the function. |
grey text | Sample | string | none | Single and double-quoted strings are shown in grey text. |
cyan text | Sample | variable set on the same page, | [name or SGQA code]: question; value; answerList showing codes for each value | Any variable that is set on the same page as the question you are currently editing is shown in cyan text (it can be updated in javascript). The tooltip shows its name (if you used INSERTANS:xxx) or its SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set). If the question type expects responses from an enumerated value set, the mapping of the codes to display values is shown. |
green text | Sample | variable set on a prior page | [name or SGQA code]: question; value; answerList showing codes for each value | Any variable that is set on a prior page is shown in bold green text. The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set). If the question type expects responses from an enumerated value set, the mapping of the codes to display values is shown. |
bold pink text | Sample | variable set on a later page in general : empty at survey start, but can be filled with index or move previous | [name or SGQA code]: question; value; answerList showing codes for each value | Any variable that is set on a prior page is shown in bold pink text. The tooltip shows its name (if you used INSERTANS:xxx) or SGQA code (if you used the new naming system), the actual question, and its current value (or blank if not set). If the question type expects responses from an enumerated value set, the mapping of the codes to display values is show. |
bold tan text | Sample | a lime replacement value | the value | Lime Replacement Strings (like {TOKEN:xxx}, {PRIVACY_MESSAGE}) are shown in bold tan text. |
red text | Sample | assignment operator (=) | warning message | If you use one of the assignment operator (=), that operator will be displayed in red text. This is meant to help prevent accidental re-assignment of values when you really meant to check whether a == b instead of setting the value of a = b. |
normal black text | Sample | punctuation | none | All other punctuation signs within the expression are shown as normal black text. |
red-boxed text | a bold red line surrounds the error | syntax error | description of the error | Any detected syntax errors are shown within red boxes. The tooltip shows the error. Examples include unmatched parentheses, use of undefined functions, passing the wrong number of arguments to functions, poorly structured expressions (e.g., missing operators between variables), trying to assign a new value to a read-only variable, trying to assign values to non-variables, or using unsupported syntax. Note that the syntax error dectection system may only report one error in an expression even if there are multiple errors; however, if any errors are detected, at least one error will be shown. |