Welcome, Guest
Username: Password: Remember me

TOPIC: Notes on creating custom question types (based on existing types)

Notes on creating custom question types (based on existing types) 3 years 1 week ago #69223

  • gskramer
  • gskramer's Avatar
  • OFFLINE
  • Fresh Lemon
  • Posts: 16
  • Karma: 0
I recently needed to create some questions that would automatically pre-fill with values submitted from comparable questions in previously submitted surveys, so we could have a serial set of entries of the same questions over time, preserving an historical record. The basic procedure was:
  • One token attribute holds the Survey ID of the survey from which values are to be taken, which I call the Reference Survey
  • One token attribute holds a match value: We're looking for the most recent submission of the Reference Survey that has a matching token attribute.
  • Once the correct lime_tokens record has been identified from the Reference Survey, we grab the value from the corresponding lime_survey record that has the same question title as the current question, and use it to prefill the question in the survey.
To accomplish this, I created pre-fill varieties of some standard question types: long free text (T), short free text (S), and date (D). After some trial and error discovering where the Limesurvey code needed to be modified to accomodate the new types, I made a checklist that may be helpful to others (file names are with reference to Limesurvey v 1.9+ - I think the function names are the same in all recent versions):

• common_functions.php, getqtypelist(): Add the custom Q type to the main array; since my types were variants on existing types, I just copied and pasted the array elements for the existing types, changing the type letter and name.
• activate_functions.php, activateSurvey(): This is the function that creates the lime_survey_nnnnn table when the survey is activated. You must modify it to handle your custom type, otherwise it will be defaulted to a char(5)(!) in the database table.
• common_functions.php, questionAttributes(): This defines what question attributes may be defined in the Limesurvey admin when you create questions of each type - since I was basing on existing types, I just added the type letters for my custom types to the attributes used by the base types. NOTE (IMPORTANT!) that the 'hidden' attribute must be defined for every new question type, else Limesurvey will crash when it executes the survey (at least in v1.9+); the 'page_break' attribute must be defined for every type to prevent crashing when you generate a printable version of the survey.
• common_functions.php, question_class(): Add your custom types IF you want them to be styled using classes in template.css and print_template.css of the template used for survey. If creating a type that's a variant on an existing type, you probably want to edit this so the variant uses same class as the base type.

Those are the base essentials, but any of the following may be needed depending on the specifics of your custom type:

○ common_functions.php, getextendedanswer(): Type-specific formatting of answers for printed output (see printanswers.php): Plain-text values do not need to be recognized here, but anything more format-specific does.
○ qanda.php, retrieveJSidname(): Type-specific handling for conditional questions - may need to cover this if using custom type in a condition (either as question with a condition, or referenced by a condition)
○ qanda.php, create_mandatorylist(): Probably need to cover this one if a custom type may be mandatory and it's not a plain-text or date type, which fall under the default clause.
○ qanda.php, mandatory_popup(): May also be important if a custom type may be mandatory
○ Export_data_*.php: A set of scripts that handles survey data export to various formats - exports may act funny or fail is custom type not handled here.
○ Surveytable_functions.php,m s
○ Questionhandling.php: I didn't touch this, but see function questionjavascript() - looks like this does some type-specific stuff for the Admin interface.

Note: On request, I'm glad to provide details of how the previous values were inserted to the questions at run-time, but it isn't the main topic here.
Last Edit: 3 years 1 week ago by gskramer. Reason: new info
The administrator has disabled public write access.

Re: Notes on creating custom question types (based on existing types) 3 years 1 week ago #69231

  • Mazi
  • Mazi's Avatar
  • NOW ONLINE
  • LimeSurvey Team
  • Posts: 5425
  • Thank you received: 307
  • Karma: 252
Thanks for this detailled feedback!

Implementing a new question type really is a mess, I have to admit that. Besides the files you mentioned, there are other parts of the code that should support the new question type, such as statistics, printable survey, various export options just to name a few.

We are currently porting the Limesurvey code to an MVC framework to make it easier to add new features later on. Furthermore we are planning to make each question type an object, but this takes some time and we lack the ressources because we do all the work in our free time.

Another note about your approach: It might be easier to use an Ajax call within the survey to query another database. I did this for a customer some weeks ago and it worked fine. You can then use Javascript to read out the returned data and pre-populate some form elements.

Best regards/Beste Grüße,
Dr. Marcel Minke
(Limesurvey Head of Support)
Need Help? We offer professional Limesurvey support
Contact: marcel.minke(at)limesurvey.org'"
The administrator has disabled public write access.

Re: Notes on creating custom question types (based on existing types) 3 years 1 week ago #69241

  • gskramer
  • gskramer's Avatar
  • OFFLINE
  • Fresh Lemon
  • Posts: 16
  • Karma: 0
Hello Mazi,

Thanks for your additions - I just discovered the need to handle the printable survey, and added that to my notes. Thanks also for the suggestion re Ajax - in this case, the pre-existing values are in the same survey database, so I just leverage the same database connection used for the active survey.

Maybe you can help with a problem I'm having? This concerns my prefill version of the Date type. In the do_date() function, the normal code to display the date value is:

if (trim($_SESSION[$ia[1]])!='')
{
$datetimeobj = new Date_Time_Converter($_SESSION[$ia[1]] , "Y-m-d");
$dateoutput=$datetimeobj->convert($dateformatdetails);
}
else
{
$dateoutput='';
}

My modification is below. get_prefill_value() is the function that looks up a prefill value, based on globals set for the current question:

if (trim($_SESSION[$ia[1]])!='')
{
$datetimeobj = new Date_Time_Converter($_SESSION[$ia[1]] , "Y-m-d");
$dateoutput=$datetimeobj->convert($dateformatdetails);
}
else if ($isPrefill) { // If not, check for a prefill value to use
$prefillDate = get_prefill_value();
if (strlen($prefillDate) > 0) {
$datetimeobj = new Date_Time_Converter($prefillDate, "Y-m-d");
$dateoutput=$datetimeobj->convert($dateformatdetails);
}
else {
$dateoutput='';
}
}
else // Default fallback from original code
{
$dateoutput='';
}

When you run the survey, it does correctly pull the dates from the previous submission and displays them in the survey's date format, which is "mm/dd/yyyy" - however, the record is saved with all the dates as "0000-00-00". Any idea what I'm doing wrong? It must have something to do with the date type conversion, but I'm not sure what.
Last Edit: 3 years 1 week ago by gskramer.
The administrator has disabled public write access.

Re: Notes on creating custom question types (based on existing types) 3 years 1 week ago #69329

  • Mazi
  • Mazi's Avatar
  • NOW ONLINE
  • LimeSurvey Team
  • Posts: 5425
  • Thank you received: 307
  • Karma: 252
How does the "$_SESSION[$ia[1]]" look like when echoing it?

It's definitely a date conversion issue but I would need to set up your code locally which is a little beyong the free support because it takes some time to set it all up and debug this.

Best regards/Beste Grüße,
Dr. Marcel Minke
(Limesurvey Head of Support)
Need Help? We offer professional Limesurvey support
Contact: marcel.minke(at)limesurvey.org'"
The administrator has disabled public write access.

Re: Notes on creating custom question types (based on existing types) 3 years 1 week ago #69410

  • gskramer
  • gskramer's Avatar
  • OFFLINE
  • Fresh Lemon
  • Posts: 16
  • Karma: 0
Hi Mazi,

I thank you for taking the time to look at this, and agree that setting up the code locally would be way beyond the call of free support! So, any insight you could give would be appreciated:

In any given survey, the first time the code executes, it correctly inserts the $prefill value. So, for example:
- $_SESSION[$ia[1]] = null
- Prefill value = "2011-11-10"
- String inserted to field = "11/10/2011" (correct)

Now, you save the group (e.g., click the Next button), then navigate back to the group. Now:
- $_SESSION[$ia[1]] = "0000-00-00"
- No prefill value, since a session value already exists
- String inserted to field = "11/30/1999"
- Value saved to lime_survey table = "0000-00-00"

Any ideas? Thanks again!
The administrator has disabled public write access.

Re: Notes on creating custom question types (based on existing types) 3 years 1 week ago #69454

  • gskramer
  • gskramer's Avatar
  • OFFLINE
  • Fresh Lemon
  • Posts: 16
  • Karma: 0
Hi Mazi,

Good news, I figured it out! There were two changes required:

(1) After retrieving my prefill date from the database into $prefillDate, ALSO write that value into the session variable - since that's what Limesurvey will use to write it back out to the table.
(2) In save.php, modify every place where it does special processing for type 'D' so it does the same thing for for my custom date type.

I wanted to modify my original forum post to add new knowledge, such as this - but it looks like it can't be edited once a reply thread exists. Can you suggest another place to post this info where it would be of use to others? I was thinking of Workarounds, though this doesn't seem like a "workaround" in the usual sense - but maybe that's the most appropriate place?

Thanks again,
Gordon
The administrator has disabled public write access.

Re: Notes on creating custom question types (based on existing types) 3 years 6 days ago #69506

  • Mazi
  • Mazi's Avatar
  • NOW ONLINE
  • LimeSurvey Team
  • Posts: 5425
  • Thank you received: 307
  • Karma: 252
Thanks for your feedback. You can add that at the workarounds, I think ti is the best place because the forum is wiped out regularly.

Best regards/Beste Grüße,
Dr. Marcel Minke
(Limesurvey Head of Support)
Need Help? We offer professional Limesurvey support
Contact: marcel.minke(at)limesurvey.org'"
The administrator has disabled public write access.
Moderators: ITEd
Time to create page: 0.111 seconds
Donation Image