Qualtrics using JavaScript library from someone else - chat simulator - javascript

I want to build a survey that contains a fake chat. The subject will be participating in the chat.
I found this beautiful library of a chat simulator and tried to use it in one of the questions as following:
upload to my library all the js and css that used through a source link.
add the jquery script to the js option of the question in onLoad() function:
Qualtrics.SurveyEngine.addOnReady(function()
{
jQuery(function($){
var count = 0;
var convForm = $('#chat').convform({eventList:{onInputSubmit: function(convState, ready) {
console.log('input is being submitted...');
//here you send the response to your API, get the results and build the next question
//when ready, call 'ready' callback (passed as the second parameter)
if(convState.current.answer.value==='end') {
convState.current.next = false;
//emulating random response time (100-600ms)
setTimeout(ready, Math.random()*500+100);
} else {
if(Array.isArray(convState.current.answer)) var answer = convState.current.answer.join(', ');
else var answer = convState.current.answer.text;
convState.current.next = convState.newState({
type: 'select',
noAnswer: true,
name: 'dynamic-question-'+count,
questions: ['This question state was built on your previous answer (you answered: '+answer+') and doesnt expect an answer'],
});
convState.current.next.next = convState.newState({
type: 'select',
name: 'dynamic-question-'+count,
questions: ['This question state was built on your previous answer (you answered: '+answer+')'],
answers: [
{text: 'Answer 1', value: '1'},
{text: 'Answer 2', value: '2'},
{text: 'END', value: 'end'}
]
});
//emulating random response time (100-600ms)
setTimeout(ready, Math.random()*500+100);
}
count++;
}}});
});
});
add to the header the <script src="<URL>"> </script> urls of the uploaded files to my library.
made a question through the rich content editor and edit the html:
<section id="demo">
<div class="vertical-align">
<div class="container">
<div class="row">
<div class="col-sm-6 col-sm-offset-3 col-xs-offset-0">
<div class="card no-border">
<div id="chat">
<form action="" method="GET" class="hidden">
<select data-conv-question="Hello! This is an example use of the plugin to dynamically generate questions (like using an API). This is the only question that was written on the initial HTML. To end the loop, select END." name="first-question">
<option value="understood">Understood</option>
<option value="okay">Okay, captain!</option>
</select>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
But its not working - just shows a broken chat...
Am I doing it the wrong way?
Is there an easy way to use such library in Qualtrics survey question?

The easiest way to solve this was by using styled tables in the rich content editor.
the dynamic chat was made by inserting the user`s response to the next table.

Related

How to replace JS variable with JSON file

I've been working on a website and am new to the website coding scene, my goal is to create a revolving text that goes between words sort of like a splash text on games like Minecraft. I know it's probably best to somehow create a way to connect to a JSON file to my JS one but not quite sure on how to do it. Can someone help?
This is my JS so far and the part of my site that shows the revolving text.
var landingswitchtext = [
'world',
'web',
'video',
'community',
'service',
'home',
'place',
'legacy',
'space',
'server'
];
textSequence(0);
function textSequence(i) {
if (landingswitchtext.length > i) {
setTimeout(function() {
document.getElementById("landing-text-switch").innerHTML = landingswitchtext[i];
textSequence(++i);
}, 2500); // 2.5s (in milliseconds)
} else if (landingswitchtext.length == i) { // Loop
textSequence(0);
}
}
<div class="landing-page">
<h1 class="landing-text">
<center>
building a
<br>
<br>
<span class="magic" id="landing-text-switch">sam</span>
<br>
<br>
for everyone.
</center>
</h1>
</div>
So, you need to have a JSON file and then import it in your script. For that, try the following script:
import * as data from './example.json';
And then use the variable data anywhere you want.

Use a JTable from a list in a for-each

I use Java Spring MVC in my webapplication. I need to make a table in JTable from a list that belongs to a Java Object (locally called table in for-each loop, as you can see below).
So for each table, there's a table.listOfThings (a java.util.List object) I have to show inside JTable.
HTML:
c:forEach var="table" items="${listOfTables}">
<div class="row">
<div class="col-lg-12 data-cell">
<div class="data-label">
<b><fmt:message key="thisTitle" />:</b>
<div id="jTableContainer"></div>
</div>
</div>
</div>
And the JS:
$(document).ready(function() {
readyTable();
)};
function readyTable(){
$('#jTableContainer').jtable({
title: 'List Title',
actions: {
listAction: ${table.listOfThings},
},
fields: {
Field: {
key: true,
title: 'Field',
width: auto;
}
});
$("#jTableContainer").jtable("load");
}
This way, JTable is always empty - it just display the title. How can I do it?
I know you can access response stuff in document ready, maybe try passing it to that function like readyTable(${table.listOfThings}); or maybe set a global variable which is given a value during ready(), have a play and use the debugger if you're using chrome, or console.log(${table.listOfThings}) in your ready() to see what's going on

How Can I use Javascript to loop through an array and change and add extra HTML that outputs some text with those values?

For Example, I am using an API that returns an JSON array of values and I want to output them to the page.
Here is the full code I am working with if anyone wants to try it out to see where I can get it to work.
I have created Some HTML for the layout of the values I want to output when a button is clicked like so:
<p class="txData">
<p id="txHash">Transaction ID: </p><br>
<p id="txTime">Time: </p><br>
<p id="txToken">Token Symbol: </p><br>
<p id="txTo">To: </p><br>
<p id="txFrom">From: </p><br>
<p id="txValue">Amount Transferred: </p><br>
<p>***********************************</p><br>
</p>
I then assign variables for those elements which I want to append to:
let txHash = document.querySelector('#txHash');
let txTime = document.querySelector('#txTime');
let txToken = document.querySelector('#txToken');
let txTo = document.querySelector('#txTo');
let txFrom = document.querySelector('#txFrom');
let txValue = document.querySelector('#txValue');
And I append the retrieved values from the API by doing:
txHash.insertAdjacentHTML('beforeend', jsonFile.result[0].hash);
txTime.insertAdjacentHTML('beforeend', jsonFile.result[0].timeStamp);
txToken.insertAdjacentText('beforeend', jsonFile.result[0].tokenSymbol)
txTo.insertAdjacentHTML('beforeend', jsonFile.result[0].to);
txFrom.insertAdjacentHTML('beforeend', jsonFile.result[0].from);
txValue.insertAdjacentHTML('beforeend', web3.utils.fromWei(jsonFile.result[0].value, 'ether'));
This works to output the values wanted for the first Transaction (index [0]).
How could I create a loop that would basically use the template HTML at the start but then output it for the next 5 elements in the array so that it would be the details for each new trasanction outputted in the same format, but without having to code it 5 times?
I'm new to HTML and Javascript so appreciate any help. Thank you.
First piece of advice, if you don't already know it, you should avoid using static id's in your html template if you plan to use it for displaying a list, because id's must be unique in a single html page.
Second one, you should use a framework to help you displaying your data as a list. If you know famous ones such as Angular or React. You can also use jQuery as someone has advised you.
Here is a little example with VueJS which allows you to define components with html templates. Then, you can use them in a loop with the for directive (please note I'm not a VueJS expert and you may find better solutions) :
<body>
<div id="app">
<div v-for="json in jsonFile">
<data-display v-bind:json="json"></data-display>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
var DataDisplay = {
props: ['json'],
template: '<div class="txData">\
<p>Transaction ID: {{json.hash}}</p>\
<p id="txTime">Time: {{json.timeStamp}}</p>\
<p id="txToken">Token Symbol: {{json.tokenSymbol}}</p>\
<p id="txTo">To: {{json.to}}</p>\
<p id="txFrom">From: {{json.from}}</p>\
<p id="txValue">Amount Transferred: {{json.value}}</p>\
<p>***********************************</p>\
</div>'
};
var vm = new Vue({
el: "#app",
data: {
jsonFile: [
{
hash: 'hash1',
timeStamp: 'timestamp1',
tokenSymbol: 'token1',
to: 'to1',
from: 'from1',
value: 'value1'
}, {
hash: 'hash2',
timeStamp: 'timestamp2',
tokenSymbol: 'token2',
to: 'to2',
from: 'from2',
value: 'value2'
}
]
},
components: {
'data-display': DataDisplay
}
});
</script>
</body>
Documentation used for the example :
https://v2.vuejs.org/v2/guide/components.html
https://v2.vuejs.org/v2/guide/list.html

I have two divs with the same ng-controller in AngularJS, how can I make them share information?

I have two different div tags in my html code referencing the same controller in AngularJS. What I suspect is that since these divs aren't nested they each have their own instance of the controller, thus the data is different in both.
<div ng-controller="AlertCtrl">
<ul>
<li ng-repeat="alert in alerts">
<div class="span4">{{alert.msg}}</div>
</li>
</ul>
</div>
<div ng-controller="AlertCtrl">
<form ng-submit="addAlert()">
<button type="submit" class="btn">Add Alert</button>
</form>
</div>
I know this could easily be fixed by including the button in the first div but I feel this is a really clean and simple example to convey what I am trying to achieve. If we were to push the button and add another object to our alerts array the change will not be reflected in the first div.
function AlertCtrl($scope) {
$scope.alerts = [{
type: 'error',
msg: 'Oh snap! Change a few things up and try submitting again.'
}, {
type: 'success',
msg: 'Well done! You successfully read this important alert message.'
}];
$scope.addAlert = function() {
$scope.alerts.push({
type: 'sucess',
msg: "Another alert!"
});
};
}
This is a very common question. Seems that the best way is to create a service/value and share between then.
mod.service('yourService', function() {
this.sharedInfo= 'default value';
});
function AlertCtrl($scope, yourService) {
$scope.changeSomething = function() {
yourService.sharedInfo = 'another value from one of the controllers';
}
$scope.getValue = function() {
return yourService.sharedInfo;
}
}
<div ng-controller="AlertCtrl">{{getValue()}}</div>
<div ng-controller="AlertCtrl">{{getValue()}}</div>
If I understand the question correctly, you want to sync two html areas with the same controller, keeping data synced.
since these divs aren't nested they each have their own instance of the controller, thus the data is different in both
This isn't true, if you declare the controllers with the same alias (I'm using more recente angular version):
<div ng-controller="AlertCtrl as instance">
{{instance.someVar}}
</div>
<div ng-controller="AlertCtrl as instance">
{{instance.someVar}} (this will be the same as above)
</div>
However, if you WANT them to be different and comunicate each other, you will have to declare different aliases:
<div ng-controller="AlertCtrl as instance1">
{{instance1.someVar}}
</div>
<div ng-controller="AlertCtrl as instance2">
{{instance2.someVar}} (this will not necessarily be the same as above)
</div>
Then you can use services or broadcasts to comunicate between them (the second should be avoided, tough).

How do I reuse HTML User Interface elements?

I have the following HTML:
<div id="addFieldUI" style="display: none">
<div>
Field Name:
<input type="text" />
</div>
<div>
Field Value
</div>
<div>
Data Type:
<select>
<option>Price</option>
</select>
</div>
I would like to reuse the HTML in at least two other jQuery modals. If I use $('#otherElem').html($('#addFieldUI').html()) to insert the HTML into an HTML element I have the problem of duplicate elements if I use input ids for the fields. Should I rather use input names? Should I use a 'script' code block instead of a div? How do I create reusable HTML?
EDIT
I am aware of jQuery data templates but in this case I just want to reuse HTML within MODAL dialogs. E.g. if I used the same form for creating and editing data.
Something like this, perhaps:
var counter = 0;
$('#otherElem').html(
$('#addFieldUI')
.clone()
.attr('id', 'addFieldUI-' + counter++)
.html()
);
You can use a class name as a hook, and than before appending to the other div use Js to dynamically add IDs
There is a library called jQuery Templates and you can always give that a go, I used often in ASP.NET MVC, but works everywhere.
in Git you have some demos
example:
<script id="movieTemplate" type="text/x-jquery-tmpl">
<li>
<b>${Name}</b> (${ReleaseYear})
</li>
</script>
<ul id="movieList"></ul>
<script type="text/javascript">
var movies = [
{ Name: "The Red Violin", ReleaseYear: "1998" },
{ Name: "Eyes Wide Shut", ReleaseYear: "1999" },
{ Name: "The Inheritance", ReleaseYear: "1976" }
];
$( "#movieTemplate" ).tmpl( movies ).appendTo( "#movieList" );
</script>

Categories