isEmailTaken, isUsernameTaken and two non-standard ways to use them

The two functions are more related to the respondent recruitment surveys and are used to check if any previous respondents have registered with the same email address or user name. They are not really known, but they’re really powerful.

The power comes from the the fact they give you access to the global data, from inside a respondent link. I always wished for some Confirmit internal functions to call and get access to other individuals responses, from inside a script. I know there are all kind of alternatives from a simple API app, or even using a scripting extension, but nothing I know that’s already available in Confirmit. (not sure if there’s anything planned for Confirmit 16).

Anyways, we have these two associated with their question IDs “email” and “username” and as I said, here are two simple scenarios that demonstrate how we can use them in a regular survey.

A first scenario would be an open link survey, let’s say we have it distributed to a number of websites and later in the survey or at the end, we collect their email address for another follow up (right after this first survey) and you don’t have time to collect all the emails and sort/eliminate duplicates and so on.

It’s nothing easier than creating an open end question with “email” as questionID, make it look nice, one row etc
then add a condition node, and call the function

!isEmailTaken( f("email").get())

depending on the logic, you can use a redirect to the second survey or just terminate.

The second example is a little bit more complex and is outlined below:

We want to give 100 free Amazon vouchers or another electronic incentive to the first 100 respondents who complete the study. We can even add a note it in the invitation letter, to boost the response rate… (First 100 respondents get a 5.00$ voucher etc).

The issue is that we need to assign an unique voucher number to a respondent who completes the study. Forget the idea of pre-assigning them when they start, we may or not have enough vouchers to use, and who will stay to sort everything after all?

function vouchers(){
var labelsArr=f("vouchers").domainLabels();
/*the vouchers is a multi randomized question with the vouchers as answers
//if more values are required, you can always create a set, and use a standard randomize script, you can find in any scripting manuals
//vouchers and username are hidden question
*/
f("username").set(labelsArr[0]);
var found = false;
var counter=1;
while (found==false && counter<labelsArr.length){
	if(isUsernameTaken(f("username").get())){
		f("username").set(labelsArr[counter]);
		counter++;
	}
	else found =true;
}
return found;
}

you may call the function from a condition node or script node then redirect/or not the respondent to Amazon and claim their free voucher

As a last note, these are working as global variables, it doesn’t matter what the respondent status is, the functions will check even if the respondent has the incomplete status.

Confirmit surveys jQuery lightBox ready

This is something that will make both your clients and respondents happy.

There shouldn’t be too much to say about how this works, I’m sure you already know.

It’s good to have something like this in surveys, where you have to display lots of images, and for a great user experience, just make sure the thumbnails have the same size (height and width).

To make it work, download the plugin, here’s one link http://leandrovieira.com/projects/jquery/lightbox/

Add the lines below inside your theme

 
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/jquery.lightbox-0.5.js"></script>
<link rel="stylesheet" type="text/css" href="css/jquery.lightbox-0.5.css" media="screen" />
<script type="text/javascript">$(function() {$('[rel*=lightbox]').lightBox();});</script>

And use it like below. You can have it working in the question text, or in the answers.

 
<a href="image1.jpg" rel="lightbox" title="Some title here"><img src="thumb_image1.jpg" width="60" height="60" alt="" border="0" /></a>

Survey Layouts, WI Templates or both?

In the latest Confirmit versions the WI Template is no longer supported, is this supposed to be good or bad? Wondering what the true reason is, anyways, seems like we should say good bye to WI.

I enjoyed working with WI, for a number of reasons, it was pretty neat, easy to use, and had the option to add the code directly in there. What I didn’t like was the fact that the elements (inputs and all the other primitives) were rendered without a class, name or id (some were) so it was a bit challenging to traverse and work with that structure.

A couple of issues I see with the Layouts:

– The Survey Layouts is more complex, not a bad thing, but I can’t see someone stay and change each of the styles manually, using the interface.

– It allows you to insert your own java scripts, and CSS in clear, directly in the page or even using the external link to JS (only one external link is not always enough) and CSS.

– It may be designed for non-technical users, but not sure what’s the percentage of people that use Confirmit to design and script a survey, without any basic knowledge of CSS, html or JavaScript, and an interface, with predefined values and lists can’t just keep up with all the changes, hacks and all the new properties new browsers are now supporting.
Here's a tip, if you work on creating a theme, need to define some new styles, and plan to use an external CSS file, don't bother defining them in Confirmit, just name them (Style name), and use them in the CSS when defining the associated styles.

-You can’t just add your own meta tags, the system will have them deleted, you have to use the provided “meta tags” tab where you can choose from the existing ones or just define one as you wish. The only difference here is that you only got the option to add a named meta tag. If you want to have a http-equiv or else you can’t, and don’t tell me is it the same as using a named tag, and since HTML5 there are 5 (content, http-equiv, name, scheme and charset)

-You can’t have styles named like “text-anothertext”, if you do so, you get an error saying "Style name contains invalid characters.Remember that a style name must be all lower case, cannot contain white spaces or start with a numeric character."

On the other hand, working with Layouts seems scary in the beginning but after you get used with them you can really enjoy it.

Randomly respondent allocation controlled by quota

Just finished a study today for one of my clients and he asked if it’s possible to expose his respondents to three different brands, with a max of 500 per each.

The easiest method we can think off is by pre-setting a background single variable; we have 500 per each times 3 so we need 1500. (that’s after screenings – if any).
To have a round number, of course depending of the projected incidence as well, let’s say we may size the sample to 2400 people.
Now randomly have a background single variable set, let’s call it brandAllocation, with precodes from 1 to 3.
we’ll get 800 people with brandAllocation set to 1, 800 people with brandAllocation set to 2 and so on.

The issue is you can’t control them, so you may end up in loosing sample, I mean valid respondents get screened out because of quota, and may end up in not having the required number of completes on one or even all three brands.

This situation can be avoided if we have some controlled allocation, based on quota.

First, we need to have the same brandAllocation question, this time is hidden and the answers randomized. Why randomized? It’s easier to let Confirmit randomize it for us.
Nest step is to create a quota and drag this single question inside and specify the limits for each brand you need the respondents to be exposed.

Here is the function I used. Just place it in a script node.

function checkQuotaSingle(questionId,quotaName){
	var qIdDomainValArr = f(questionId).domainValues();
	f(questionId).set(qIdDomainValArr['0']); 
	var tempVal = f(questionId).get(); 
	var foundBool = false;

	for (var i = 0; i < qIdDomainValArr.length; i++) {
		if(qf(quotaName))f(questionId).set(qIdDomainValArr[i]);
		else { foundBool = true; break;}
	}
return foundBool;
}

The usage it's simple, after the screening questions, have a condition node with the function call

!checkQuotaSingle('q1','quota1') 

then
Stop (quota full)

The advantages are:
you can control the limits for each of the brands, so if you change your mind during the field you can easily do it.
the sample (as calculated earlier) would be enough to fill the quotas up, and actually even less sample would be needed.

Redirect to a different project or web application, and capture data back

Here is a technique I used in various projects I was working on, where I had to link to a different project, modules or third party applications, pass some data and collect other data back.

Start by creating a script node with the content below:

var applicationUrl="the_application_url";
var theRespondentUrl=HttpUtility.UrlEncode(GetRespondentUrl()+"&__qid=backFromApp");
//or since Confirmit15 GetRespondentUrl("backFromApp");
var x,y="";//here some variables and values, you can take those from other questions as you wish
var additionalVariables="&x="+x+"&y="+y;
Redirect(applicationUrl+"?linkBack="+theRespondentUrl+additionalVariables,true);

Next, add an info question, with the ID backFromApp, and here is the place where we expect to have the respondent returned,

<input type="hidden" name="dataCaptured" id="dataCaptured">
<script type="text/javascript">
function getUrlVariables(){ 
  var variablesUrl = [], variableNameValue; 
   var variablePair = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); 
    for(var i = 0; i < variablePair.length; i++)    { 
       variableNameValue = variablePair[i].split('='); 
       variablesUrl.push(variableNameValue[0]);  
       variablesUrl[variableNameValue[0]] = variableNameValue[1]; 
   }
  return variablesUrl;
}

document.ctlform.dataCaptured.value=getUrlVariables()[ 'oneInParticular'];//store data in hidden form element, dataCaptured
document.ctlform.submit();//go to the next question
</script>

Please make sure you use the right variable name, since it’s case sensitive.

A script node follows the info question above, and stores the data back in Confirmit, let’s say you have an open end with the id “dataCaptured”

f('dataCaptured').set(Request('dataCaptured'));

On the other end (in the external app, or even Confirmit project) you only need to capture the link, store it, append the data and redirect the respondent back.

Avoid getting the same respondent entering multiple times an open survey – cookies

When it’s possible to have a survey deployed on different sites, you may end up having same people entering multiple times.

Or let’s say you may have a category survey and you want to make sure people can’t participate within one month from the time they have completed a same category survey.

You are able to control this using the browsers cookies.
Here are two functions one to write and the other one to check if there are any cookies

function WriteCookie(category){
	var mycookie : Object = new HttpCookie(category);
	var now : DateTime =  DateTime.Now; 

	mycookie.Path = "/";
	mycookie.Value = CurrentPID()+"|"+category;
	mycookie.Expires = now.AddMonths(1); 
	Response.Cookies.Add(mycookie);
}


function ReadCookie(category){
	var mycookie : Object = Request.Cookies(category);

	if(mycookie != null && mycookie.Name==category) return true;
	else return false;
}

Now, when is the best time to write the cookie out? Best would be at the time the panelist gets the status ‘complete”, just call the function from a script node

WriteCookie('category1');

To check if the cookie is already set, right when the survey starts, you can add a condition node like

if ReadCookie('category1')
then
 

Another usage of cookies is not only checking the cookie name but checking the values we’ve stored,
So now we store here the ProjectID and the category string:

mycookie.Value = CurrentPID()+"|"+category;

you also can read it

myCookieValue=myCookie.Value;

and parse it or split it by “|”
then you can check the values form there.

myCookieValues=myCookie.Value.split('|');

Ugly errors in Confirmit… and what can we do

I’m sure you may already know how “nice” the errors look like especially when you get a long answer grid, unanswered.

Here’s one
confirmit grid error

Just imagine how would look if the answer text is longer and there are even more in the list…

Remember what I said in some earlier posts, don’t let Confirmit run it for you, you take control over it. So now, the first thing would be to remove the default, generic error message, “Please review your responses on this page….etc” You can easily remove it from the theme or from script

Honestly, I don’t see any good reason to have it.

Now let’s make the second one look nicer, or straight to the point, why do we need to tell what answers are missing, I know there’s an option to highlight the missing ones so we can use that to give them a visual.

Anyways, just call these two functions from the inside “Validation” area

 ClearErrorMessage(); //this clears the generic "page" message
 ClearQuestionErrorMessage(); //this removes the question specific error message

The next step would be to define our own error message, something like:

SetQuestionErrorMessage(CurrentLang(),"Please enter one answer for each row");

If you’re looking to automate more you may combine the first two in a custom function and call it as you wish

then for the second one, in case you have plenty of languages you may come with a way to read them from a question label, so you may have everything ready with just one function call

Very custom pages in Confirmit

You know what happened these days? I had a request from one of my clients to build a very custom question.

Forget about thinking 3DGrids can work, it was a very custom one, with lots of drop downs, open ends, text areas, and some radio buttons. And everything on the same page!

I thought, using Confirmit default question type I can’t even get close.

So what I did is I took everything offline, built the html structure, with all the elements, css styles and everything, then just put it in a Info question type. Right in the question text area.

OK so now I had it look as my client wished.
Looked good, but then I also had to take care of saving data too.

Right after the info node I placed a script calling the request function from Confirmit.
Request(“custom_variable_name”)

Can do the same with Request.QueryString() parsing the entire string.

So everyone was happy!

Script to delay advancing to the next question

If you ever wondered how we make sure a product picture was seen before answering the follow up questions here’s a script you can use:

What it does it’s hiding the “navigationarea” then after 3 seconds, it shows it back, so that the user can click on the next button.
Three seconds, I think it’s enough, if not you can increase the time to whatever seems right for you (if you need 5sec you change below the time to 5 x 1000 = 5000 ms)

$(function() {
	$('.navigationarea').hide();
	setTimeout("showButtons()",3000);
});
function showButtons(){
 $('.navigationarea').show();
}

You may have more alternatives in regards to the navigation area or the buttons. You can, let’s say, just disable them instead..\

3d grids numeric with autosum on rows

Is it again about a 3d-grid, now with numeric open end boxes

Everyone, I suppose, knows that I can have the autosum feature enabled for columns. What if I need an autosum on rows?

Here’s a quick script I wrote that takes care of this.

$(".confirmit-grid tbody tr")
.each(function(index){
	var row=index+1;
	var last=$(this).find("input:text").length;
	$(this).find("input:text")
	.each(function(index){
		$(this).keyup(function(){
			if(index+1!=last){
				var sum=0;
				$(".confirmit-grid tr:eq("+row+") input:text").not(':last').each(function(){sum+=parseInt($(this).val()-0);});
				$(".confirmit-grid tr:eq("+row+") input:text").last().val(sum);
			}
		});
	});
});