Commit cf6ce3a4 authored by Jacek Bzdak's avatar Jacek Bzdak

Four qualtrics posts.

parent 6b63bf5d
Pipeline #68860967 passed with stages
in 3 minutes and 15 seconds
How to generate sprite image for javascript app
===============================================
:date: 2019-06-13
:slug: node-sprites
:tags: sprite,css,webdev,javascript
Composite sprite images are one of the optimization methods for displaying images.
Many small files are compressed to single larger file when using it you gain:
* One big request instead of many small requests;
* Possibly better compression;
In my case, I needed to rapidly display one of about 100 images, and I would
need to be sure that image is cached by the browser, as total display time
of the image is less than 0.3sec (so any network roundtrips would just totally
destroy the experiment.
To my astonishment, it turned out that there was no simply googleable cli
tool that would take a folder with images and output composite sprite image
and a CSS file.
The ``spritesmith-cli`` tool
----------------------------
To create sprite image you can use node package named ``spritesmith-cli``,
apart from the cli, you'll need to install proper "engine" to actually do the
image manipulation, I choose ``pixelsmith`` which has no external dependencies
and uses native nodejs APIs.
So the install command is:
.. code-block:: bash
# Please take care when installing packages globally,
# I installed it in a docker container so any rogue package
# won't directly harm my OS (unless it leverages docker exploits)
npm install -g spritesmith-cli pixelsmith
Then you need to create a configuration file named ``.spritesmith.js``
.. code-block:: javascript
'use strict';
module.exports = {
src: 'images/*.{png,gif,jpg}',
destImage: './glyphs.png',
destCSS: './glyph.css',
imgPath: '/assets/glyph.png',
padding: 2,
algorithm: 'binary-tree',
engine: 'pixelsmith',
cssOpts: {
cssClass: function (item) {
return '#glyph-' + item.name;
}
}
};
Then assuming that images are in the ``images`` folder, after calling
``spritesmith`` command you'll get ``glyphs.png`` file that contains the images
and ``glyphs.css`` that contains the CSS.
Optimize the generated png
--------------------------
Generated ``.png`` file was not really optimized, so I just ran ``optipng`` on it
which decreased the image size to 50% of the original.
How to inject a Javascript SPA to qualtrics survey
==================================================
:date: 2019-06-23
:slug: qualtrics-spa
:tags: webpack,qualtrics,webdev,javascript
Sorry, just don't. It won't work, it will be painful. You can integrate
your Single Page App (SPA) using ``iframe`` (this has its own caveats though
namely resizing).
I got an error with ``webpackJsonp`` not having the proper type, I would guess
that ``Qualtrics`` used their own webpack code (this is sensible for their scale)
and somehow I got version mismatch, or just one can't have two webpack apps
applications on the same site (which is also sensible). Life is tough without
proper namespaces.
.. note::
If you managed to avoid iframes do let me know! I'll happily update this post and link to your solution :)
If this sound like black magic (or just something you'd rather avoid doing),
do get in touch I might help you with whatever you need :). My address is ``[email protected]``.
\ No newline at end of file
How to establish two way communication with iframe
==================================================
:date: 2019-06-23
:slug: two-way-communication-with-iframe
:tags: iframe,webdev,qualtrics,javascript
This post is part of the series documenting a qualtrics project.
Right now we have a single page embedded inside a qualtrics survey, and
we want to communicate with the ``iframe``, that contains static HTML file.
One way communication
---------------------
For one way communication you can use ``#fragment`` part of URL, that is
the part after ``#``. See `the Wikipedia article on URLs
<https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax>`__.
The fragment part of URL is not sent to the server and is handled
entirely client-side. You can access it using ``window.location.hash``
variable.
I did not implement communication this way, so I'll leave it to you to
implement the details.
Two way communication
---------------------
I needed two-way communication between the Qualtrics page (the page that
embeds the ``iframe``) and the ``iframe`` itself. Communication between
hosting page and the iframe is quite restricted, especially if both
pages have different origins.
To communicate between the frames you'll need to use `window.postMessage
<https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage>`__ API,
this API allows you to safely send messages between frames even if origin mismatches.
Let's assume that the hosting page has the following iframe declaration:
.. code-block:: html
<iframe id="studyFrame" src="https://somemeUrl">
</iframe>
Hosting page communication part
*******************************
To send messages from the hosting page to the iframe, you'll need to:
.. code-block:: javascript
var targetOrigin = "*";
var frame = window.frames['studyFrame'].contentWindow;
frame.postMessage({"message": "hello"}, targetOrigin);
To receive messages from the iframe you'll need to:
.. code-block:: javascript
function receiveMessage(event) {
// if (event.origin !== "http://example.org:8080")
// return;
}
window.addEventListener("message", receiveMessage);
Hosting page communication part
*******************************
To receive messages inside the iframe you'll need to:
.. code-block:: javascript
function receiveMessage(event) {
// if (event.origin !== "http://example.org:8080")
// return;
if (event.data['message'] === "hello"){
// Do stuff
}
}
window.addEventListener("message", receiveMessage);
To send messages from the iframe you'll need to:
.. code-block:: javascript
var targetOrigin = "*";
window.parent.postMessage({
"type": "finished",
"success": success,
"data": data,
}, targetOrigin)
On inter-frame communication security
*************************************
In the examples above I have omitted some important security details,
notably, you should:
* send proper ``targetOrigin``, this allows the browser to block sending the message,
if for some (presumably evil) actor updated frame URL.
* verify ``event.origin`` when receiving the message, this will allow you to discard
messages sent by malicious actors.
How to store results of javascript study in Qualtrics survey
============================================================
:date: 2019-06-23
:slug: how-to-store-results-from-a-javascript-study-in-qualtrics
:tags: webdev,qualtrics,javascript
To store results from a custom javascript study in Qualtrics you'll need to:
1. Create (empty) "Embedded data" where results will be stored;
2. In the JavaScript code store to this embedded data;
3. Figure out with your client how to extract the data for them :)
Create "Embedded data"
----------------------
1. Open your survey in the Qualtrics UI.
2. Click on Survey Flow
3. Click "Add new Element" -> "Embedded Data"
4. Set a name for this element, like: ``study-data``
5. Set value to `{}`
.. figure:: {filename}/images/0027-qualtrics-embedded-data.png
:width: 100%
Your "Embedded Data" node should look like that
6. Make sure this is the first node in the survey;
Write to this Embedded data node
--------------------------------
When your study is done just:
.. code-block:: javascript
var data;
// data = load from your study
Qualtrics.SurveyEngine.setEmbeddedData("study-data", data);
Final note
----------
If this sound like black magic (or just something you'd rather avoid doing),
do get in touch I might help you with whatever you need :). My address is ``[email protected]``.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment