I have a large set of embedded data fields that are called rnd1, rnd2, rnd3 etc. In a certain question block, I stored to each of these a certain value (each a different random number).
I also have a Loop and Merge question block, and in each round, I would like to access the stored data of a different field (i.e. in the 1st round I'd like to access whatever is in rnd1, in the 2nd round access rnd2 etc.) Can this be done in Qualtrics?
I tried something like:
Qualtrics.SurveyEngine.addOnload(function()
{
var trialNum = this.questionId.split('_')[0]; // getting the loop's current round number
var EDname = "rnd"+trialNum; // name of desired EF field
var rndNum = "${e://Field/" + EDname + "}"; // this is where I'd like stored the right ED value
// some more code that uses rndNum
});
but this does not work. It seems that while EDname gets the right string, I cannot access the value of that embedded field this way (though var rndNum = "${e://Field/rnd1} does work and returns the right value, so the problem seems to be in the looping strucutre).
If I cannot loop over the different fields in the JS code for some reason, is there another clever way to get that done in Qualtrics? For example, I thought it may be possible to use the different field names in the Loop and Merge section as "Field 2", but this seem to require me setting manually each and every ED field name.
Thanks.
Piped embedded data fields are resolved on the server before the page gets sent to your browser. So, it is impossible to dynamically create an embedded data field name and resolve it on the client side with JavaScript.
The way you are doing it with a loop & merge field is the best way.
Related
So i've been asked to remake some registration forms. The way its supposed to work is, that an interpreter chooses X amount of languages in the first select box. Then based on the selections of languages, the user must specify from which languages they can translate from/to.
I want to store this data in a key/value array, with the key being "LanguageFrom" and Value being another array, of "LanguagesTo". This is how i have solved this:
function btnTest() {
var fromArray = $('.freelancerLanguagesFrom').map(function() {
return $(this).val();
}).get();
var toArray = $('.freelancerLanguagesTo').map(function() {
return $(this).val();
}).get();
var tempArray = {};
tempArray[fromArray] = toArray;
}
This method is being called with an "onclick" function in the html part. The user should specify which languages he can translate to for each of the chosen languages in the first box,
I am aware that this probably isn't the ideal approach, but im still an inexperienced developer, and i'd love to hear your take on another approach.
Now comes my problem:
1) How do i make it so the array wont overwrite the existing array with each button click, and instead just add to the array?
2) How do i process this array on the server side (php), so that i can store the values in my database?
3) Is it possible to skip the flow where the user has to press the save(gem) button after each language he has chosen?
edit: Question 1 and 3 are now solved, my only problem is accessing the array i made in js, on the php side
1) tempArray exists only in the scope of the btnTest() function. Declare it outside (in the global scope), initialize it as {} and don't reset it every time you click the button. The way you get the fromArray variable may require some tweaking depending on whether the "from" list can accept a multiple selection or not.
2) Ajax may help. Create a php endpoint to receive the request and call it using ajax. You can work on the array using JSON. Send your data using JSON.stringify(tempArray) and read it using json_decode() in your php script, or simply set the request headers as "application/json" to have it done automatically for you.
3) I personally wouldn't automate this process. Let's say I have 4 languages, Italian, English, French and Chinese.
I have selected a desirable state of languages I can handle:
Italian -> English, French
But I also know how to translate French in Italian so I click, in the from list, French, and I get
French -> English
Which is an undesirable state, for me, because I don't know how to do that. Especially if I were to select many languages, I'd get, inbetween 2 states I want to save, an indefinite amount of states I don't want to save.
If you still want to do so, you need to move the even listener from the button to the list(s), with the onchange event.
I'd also suggest you do your event binding trough jQuery, if you aren't already.
Hope this helped.
I have a table in a form with a list of products where there is an input for each (let's call it 'pc'). Each input is named as 'pc' and product id with an id as the same. IE: 'pc100', 'pc101', etc. Each input has an onkeyup event to call a function to populate a price where I pass the product id (onkeyup='myfunction(100) The function receives the id but I cannot configure the javascript to that id. I will have the rest of the code as long as I can get the dynamic variable name. The internet is full of all kinds of things like eval() and window[] and I have tried every possible combination I can think of/find. I know it's possible to get this to work. So...how can I get this alert to work?
Most the results I will give me 'pc100' when I need 'Heres my test'
function myfunction(idpro) {
var pc331 = 'Heres my test';
alert( "pc" + idpro );
}
Don't use dynamic variable names. Do use look-ups in data structures:
function f(id) {
var pc = {
331: "Here's my test"
}
console.log(pc[id]);
}
Dynamic variables are a huge problem, especially from a security perspective. If you were naive and used eval someone could construct an id value that executes arbitrary JavaScript and then you have an XSS problem.
I am trying to manipulate a row using javascript in an older version of pentaho 4.4) and getting some strange results that I can't explain / don't understand what Pentaho is doing
var test = 'field';
Alert (this[test]); //--> Undefined
Alert (this['field']); // --> Expected result
Alert (this[test]); //--> Expected Result
For some reason, the initial request for this[test] is undefined until I use the literal string reference making it impossible to dynamically drive the process (i.e. I can't access row information by references).
Any ideas as to why? Is it simply how Pentaho deals with variables? Effectively I want my end result to allow me to change the row value at any given position. Either:
row[test] = 'New value
or
this[test] = 'New Value
or
this[test].setValue('New Value');
However, none of the above work, without replacing the values making it a very static process.
As far as I can see, Kettle does not add a field to the script's scope, unless the field is contained as a substring in the script source code (it should add even if the field mentioned in the comment). See determineUsedFields() and addValues() methods (https://github.com/pentaho/pentaho-kettle/blob/4.4.0/src/org/pentaho/di/trans/steps/scriptvalues_mod/ScriptValuesMod.java#L106).
So, the exact script you've provided, actually, produces either three defined values, or three undefined values, depending on whether the field exists or not. I was able to reproduce your issue only after I've removed strings with the field name from the code completely, and passed the field name in another field.
So, one way to manipulate row values could be to mention all field names in the script (e.g. in a comment), then try to use setValue as you have tried (seems to work in compatibility mode only).
Another possible way is to use the row array variable to get values and getInputRowMeta().indexOfValue(fieldName) to get the index of the field, e.g:
var idx = getInputRowMeta().indexOfValue(fieldName)
// WARNING: you may assign value of any type this way
// and the value will not be converted to a type defined
// in the field's ValueMeta:
row[idx] = 'New value'
However, this approach bypasses type conversions, which are usually performed while passing JavaScript values outside of the JS step in getValueFromJScript() method.
For example, the following code will put invalid value in the output, and you may not even notice it until some subsequent step will handle the value in some improper way:
// Let's assume that fieldName is name of the 0th input field.
// I'd expect, that the value would remain the same
// but in fact the `fieldName` references some wrapper oject
// which looks similar to its value
// but has a different type
row[0] = fieldName;
In subsequent JS step:
for(var i = 0; i < row.length; i++) {
Alert(row[i]) // alerts same value as the input, e.g. 'test'
Alert(row[i].class) // alerts undefined. While expected is 'java.lang.String'
// Some other subsequent steps may crash once this value encountered
}
How can I change or update a data set's query after a parameter has been passed in BIRT report designing?
Detailing:
I've got a query that looks like this:
WHERE ?
That parameter marker can hold different values, after user input parameter, it would look like this e.g.:
WHERE column_name = 1
or
WHERE column_name = 2
or even
WHERE column_name IN (1,2)
I created a Report Parameter(RP) for that Data Set Parameter(DSP) and after trying for hours, I couldn't get to change it.
I tried:
Creating all sorts of javascript expressions on both, RP and DSP
Creating a RP that would change the value of the first RP and back to previous step
Editing the Property Binding, though I couldn't figure it out how exactly it should be done.
Just to make it clear, I'm designing a report and not integrating the runtime to an existing application.
I hope this is clear enough, I'm still editing the question so if you need more information just let me know.
Thanks
Assuming that you are on an Oracle DB (other systems may behave differently) you should be aware that a bind variable (in JDBC speech: the question mark) can replace a scalar value only, e.g. a string or a number.
But you want something like a list of numbers as input.
Thus a bind variable won't help you in this case.
Probably the easiest way to achieve what you want is this:
In your query, write:
WHERE column_name in (1) -- $REPLACE_THIS$
Note that I am using a comment in the query as a marker.
Then, in the query's beforeOpen event, modify the query text like this:
// construct a comma-separated string representation of your list
// based on your report parameter (exercise left to the reader)
// var replacement = my_to_sql_csv(params["my_report_parameter"].value);
// for demonstration use:
var replacement = "1,2";
// modify the `IN` expression inside the SQL
this.queryText = this.queryText.replaceAll("(1) -- $REPLACE_THIS$", "(" + replacement + ")";
That's it.
I am using Greasemonkey/Tampermonkey to visit pages and make a change to a 100-element table based on what's on the current page.
Short term storage and array manipulation works fine, but I want to store the data permanently. I have tried GM_getValue/GM_setValue, GM_SuperValue, localStorage, and indexedDB, but I am clearly missing something fundamental.
Nothing seems to allow me to write the array into the permanent storage and then read it back into a variable where I can access each element, such that variablename[32] is actually the 32nd element in the table (Well, 33rd if you start counting at zero, which I do).
I need access to the entire 100-element table while the script is running, because I need to output some or all of it on the page itself. In the most basic case, I have a for loop which goes from 0 to 99, printing out the value of variablename[i] each time.
I have no predisposition to any method, I just want the frickin' thing to work in a Greasemonkey/Tampermonkey script.
Towards the top of the script I have this:
for (var i = 0; i <= 99; i++) {
currentData[i] = localStorage.getItem(currentData[i]);
}
The purpose of the above section is to read the 100 entries into the currentData array. That doesn't actually work for me now, probably because I'm not storing things properly in the first place.
In the middle, after modifying one of the elements, I want to replace it by doing this:
localStorage.setItem(
currentData[specificElementToChange], differentStuff);
The purpose of the above is to alter one of the 100 lines of data and store it permanently, so the next time the code at the top is read, it will pull out all 100 entries, with a single element changed by the above line.
That's the general principle.
I can't tell if what I'm doing isn't working because of some security issue with Firefox/Chrome or if what I want to do (permanently storing an array where each time I access a given page, one element changes) is impossible.
It's important that I access the array using the variable[element] format, but beyond that, any way I can store this data and retrieve it simply is fine with me.
I think you're going about this wrong. LocalStorage stores strings so the simplest way to store an array in LocalStorage is to stringify it into JSON and store the JSON. Then, when reading it back, you parse the JSON back into an array.
So, to read it in, you do this:
var currentData = JSON.parse(localStorage.getItem("currentData") || "[]");
To save your data, you do this:
localStorage.setItem("currentData", JSON.stringify(currentData));
Working demo: http://jsfiddle.net/jfriend00/6g5s6k1L/
When doing it this way, currentData is a variable that contains a normal array (after you've read in the data from LocalStorage). You can add items to it with .push(), read items with a numeric index such as:
var lastItem = currentData[currentData.length - 1];
Or, change an item in the array with:
currentData[0] = "newValue";
Of course, it's just a normal array, so you can use any array methods on it.