Welcome to the LimeSurvey Community Forum

Ask the community, share ideas, and connect with other LimeSurvey users!

how to compute (weighted) sumproduct from Array (numbers) answers

  • bebs
  • bebs's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
4 years 5 months ago #190498 by bebs
Hello.
I would like to associate weights to the 2 dimensions of a number array anwer, to be able to compute the total score of this answer by mutliplying the user answer with each of the axes corresponding value. What would be the possible/recommended way ?

I know it can be done in a spreadsheet, but am looking for a Limesurvey-only solution in this particular case. Creating a summary table with subtotal computation and final computation in EM is sensitive and error-prone, as you can see in the attached survey.



Example survey with 2 questions:

File Attachment:

File Name: limesurvey...rray.lss
File Size:37 KB
: 1 to ask about your food consumption habit (scales are 1: frequence of consumption, ranging from once a month to 3 times a day, and 2: food type).
Based on a standard price, question 2 then computes your food budget for the year.



My case has many more products, subcategories and different languages... so manually creating the summary question each time is too dangerous wrt updates.


Any ideas ? Would there be a better option with a temporary JS structure that would contain the weights, or other ?
Thanks in advance.
Berteh
The topic has been locked.
  • DenisChenu
  • DenisChenu's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
4 years 5 months ago #190501 by DenisChenu

bebs wrote: …
My case has many more products, subcategories and different languages... so manually creating the summary question each time is too dangerous wrt updates.


Any ideas ? Would there be a better option with a temporary JS structure that would contain the weights, or other ?
Thanks in advance.
Berteh

My opinion : if you don't know how to do it in JS : it's more complicated than in HTML directly …
I don't understand why a JS solutuon can be more easy than an HTML

Else, sometimes i use LibreOffice Calc to construct html lines …

Assistance on LimeSurvey forum and LimeSurvey core development are on my free time.
I'm not a LimeSurvey GmbH member, professional service on demand , plugin development .
I don't answer to private message.
The following user(s) said Thank You: bebs, gabrieljenik
The topic has been locked.
  • bebs
  • bebs's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
4 years 5 months ago - 4 years 5 months ago #190512 by bebs
Thanks Denis for looking into this.

It's not that I don't know how to do it in JS at all, I guess I could do it all with jQuery, it's more that I don't know how to be efficient with the internals of Limesurvey:

- is there already an internal JS object containing the current answers of the active group that I can use in the JS code I'd add to the question body, instead of having to dig the HTML ?
- is there a particular event I can hook on to run update code when the user changes one subquestion answer ?


> I don't understand why a JS solutuon can be more easy than an HTML

Maybe not more easy; but surely more intuitive to the final user if I can compute and show the total for each line directly in the table he uses to input his answers, and then uses these to compute the grand total in the next question instead of having to redo the whole table manually.
Last edit: 4 years 5 months ago by bebs. Reason: precision
The topic has been locked.
  • gabrieljenik
  • gabrieljenik's Avatar
  • Offline
  • Official LimeSurvey Partner
  • Official LimeSurvey Partner
More
4 years 5 months ago #190520 by gabrieljenik
For easier setup, you could create a question plugin/theme with:
- custom attribute for weight input
- custom JS to create the table.

Let me know if you need someone else doing that for you.

Thanks

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.

Checkout our Reporting Solutions and our plugin shop at www.encuesta.biz .

The following user(s) said Thank You: bebs
The topic has been locked.
  • bebs
  • bebs's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
4 years 5 months ago - 4 years 5 months ago #190540 by bebs
Thanks Gabriel.

Your post did point me in this direction. thanks.

I got the weights in data- attributes alright, on each subquestion, and created an extra column to host the subtotal... but cannot find how to update these when answers are provided:

Is there any way to use the EM 'short' notation dynamically in a subquestion answer ? i.e. to 'register' it using JS, since I cannot directly write it in the matrix using the editor (or is there a way I didn't discover yet?).

Or should I stick to jQuery, but then what event should I bind my "quantity" and "subtotal" update methods to ? $('input.numeric-item').change() does not seem to do the trick, as its .val() does not seem to always reflect the proper value.

Is there any documentation on the prefered way to dynamically update matrix answer in the 'new' LS design ? most I find online mention they are deprecated but don't give the recent good practice.

thanks for any hint.
Berteh.
Last edit: 4 years 5 months ago by bebs. Reason: precision
The topic has been locked.
  • Joffm
  • Joffm's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
4 years 5 months ago #190541 by Joffm
Hi, what I'd recommend:

1. You said there are many products. So it should be better to transpone the grid (frequency on x-axis)
2. Give a good explanation how to enter the data (not to get by one respondent"1 in "3x/day", 3 in "once a day", "21 in once a week" and "86 in once a month", what means the same.
3. You said "many languages", So I think there are different prices, maybe different currencies.
Create 2 (with currency 3) hidden questions of type "multiple numerical" (currency: "multiple short text") and enter as default answers the weights, the prices, the currency symbol for each language.

Now the formula is only: (with ww as code of weight question and pp as code of price question)
Code:
<tr>
      <td>{pp_B.question}</td>
      <td>B</td>
      <td>{Q1_1_B}</td>
      <td>{Q1_2_B}</td>
      <td>{Q1_3_B}</td>
      <td>{Q1_4_B}</td>
      <td>{round(sum(ww_1*Q1_1_B, ww_2*Q1_2_B, ww_3*Q1_3_B, ww_4*Q1_4_B))}</td>
      <td>{pp_B}</td>
      <td>{round(sum(ww_1*Q1_1_B, ww_2*Q1_2_B, ww_3*Q1_3_B, ww_4*Q1_4_B)*pp_B)}</td>
    </tr>
    <tr>
      <td>{pp_O.question}</td>
      <td>O</td>
      <td>{Q1_1_O}</td>
      <td>{Q1_2_O}</td>
      <td>{Q1_3_O}</td>
      <td>{Q1_4_O}</td>
      <td>{round(sum(ww_1*Q1_1_O, ww_2*Q1_2_O, ww_3*Q1_3_O, ww_4*Q1_4_O))}</td>
      <td>{pp_O}</td>
      <td>{round(sum(ww_1*Q1_1_O, ww_2*Q1_2_O, ww_3*Q1_3_O, ww_4*Q1_4_O)*pp_O)}</td>
    </tr>

and at the end
With a total estimated budget of
{round(sum(sum(ww_1*Q1_1_B, ww_2*Q1_2_B, ww_3*Q1_3_B, ww_4*Q1_4_B)*pp_B, sum(ww_1*Q1_1_O, ww_2*Q1_2_O, ww_3*Q1_3_O, ww_4*Q1_4_O)*pp_O, sum(ww_1*Q1_1_P, ww_2*Q1_2_P, ww_3*Q1_3_P, ww_4*Q1_4_P)*pp_P, sum(ww_1*Q1_1_W, ww_2*Q1_2_W, ww_3*Q1_3_W, ww_4*Q1_4_W)*pp_W, sum(ww_1*Q1_1_M, ww_2*Q1_2_M, ww_3*Q1_3_M, ww_4*Q1_4_M)*pp_M))} $/year

So only the product code has to be adapted.

4. You may place your "result table" into the help text area. And if you use the bootstrap layout it's not so bad.



Joffm

Volunteers are not paid.
Not because they are worthless, but because they are priceless
The following user(s) said Thank You: bebs, gabrieljenik
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
4 years 5 months ago #190545 by tpartner

Or should I stick to jQuery, but then what event should I bind my "quantity" and "subtotal" update methods to ? $('input.numeric-item').change() does not seem to do the trick, as its .val() does not seem to always reflect the proper value.

Try something like this:

Code:
$('input.numeric-item').on('keyup paste', function(e) {
  // Do something...
});

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The following user(s) said Thank You: bebs, gabrieljenik
The topic has been locked.
  • bebs
  • bebs's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
4 years 5 months ago - 4 years 5 months ago #190556 by bebs
Thanks for all the help.

In the end I created a few extra columns and 'data-' attributes in my number array to store the weights (i.e. _frequency and _price) and display subtotals (_subto) on each line.

These array cells are disabled via JS:
Code:
$('.autoVdA input[name$="_price"]').attr('disabled', 'disabled').addClass('price auto');

and get their value set by JS as well: (via input.val() method)
Code:
$('#'+subID+'_price').val(price);

I register a listener to update the subtotals when the user changes the matrix values:
Code:
$('.autoVdA table.subquestion-list input').change(function() {
      var subID = $( this ).attr('id').split("_")[0];
      (...)
      $('#'+subID+'_subto').val((qty * price).toFixed(1));
});

And this seems to work well on the current question: the subtotals are updated, and the EM shortnotation {Q_S_subto} is indeed working in the next question, same group, same page... but none of these automated values seem to be stored in the database: {Q_S_subto} is not set anymore in the followin group on the followin page.

How can I get values set dynamically to be stored properly ? should I put them in some other JS object ? or the hidden javaXXX inputs, or how ?
Last edit: 4 years 5 months ago by bebs. Reason: details
The topic has been locked.
  • tpartner
  • tpartner's Avatar
  • Offline
  • LimeSurvey Community Team
  • LimeSurvey Community Team
More
4 years 5 months ago - 4 years 5 months ago #190565 by tpartner
Regarding the data not being stored, it is probably because you disabled the inputs. Disabled inputs are ignored on form submission. Try using the readonly attribute instead:
Code:
$('.autoVdA input[name$="_price"]').prop('readonly', true).addClass('price auto');

Regarding your listener, I think if you also use the keyup event, the values will be updated as the respondent enters them, not only after focus is removed from the input.
Code:
$('.autoVdA table.subquestion-list input').on('keyup change', function(e) {
      var subID = $( this ).attr('id').split("_")[0];
      (...)
      $('#'+subID+'_subto').val((qty * price).toFixed(1));
});
(you could also add the paste event)

Cheers,
Tony Partner

Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Last edit: 4 years 5 months ago by tpartner.
The following user(s) said Thank You: bebs
The topic has been locked.
  • bebs
  • bebs's Avatar Topic Author
  • Offline
  • Junior Member
  • Junior Member
More
4 years 5 months ago #190584 by bebs
thank you Tony.

Indeed changing the input from disabled to readonly allowed the answer to be saved, wonderful !

and the keyup event is valuable improvement too, thanks for your time.
The topic has been locked.

Lime-years ahead

Online-surveys for every purse and purpose