- Posts: 10099
- Thank you received: 3589
Welcome to the LimeSurvey Community Forum
Ask the community, share ideas, and connect with other LimeSurvey users!
Combined Array with large free text comment fields
- tpartner
- Offline
- LimeSurvey Community Team
Less
More
5 years 11 months ago #168789
by tpartner
Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Replied by tpartner on topic Combined Array with large free text comment fields
Let's refresh the thread.
Exactly what behaviour do you want and what have have you tried (including any code).
Exactly what behaviour do you want and what have have you tried (including any code).
Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
- duvemyster
- Offline
- Senior Member
Less
More
- Posts: 60
- Thank you received: 6
5 years 11 months ago #168863
by duvemyster
Replied by duvemyster on topic Combined Array with large free text comment fields
Good thinking. The goal is an array that has a comment button on each row, enabling respondents to selectively choose which rows to comment on. The sample code below and attached merges the two posts containing code in this thread, plus a couple of minor sizing differences reflected. This works in Version 2.73.1+171220.
There may be a few themes that simply need to be expressed differently for this to work in 3.x? Feel free to point out starter info on that. Of course there might also be a better way to accomplish this in 3.x.
In 2.x, the code below is meant to applied to the help field of the array questions, with separate comment questions following corresponding to each row of the array.
There may be a few themes that simply need to be expressed differently for this to work in 3.x? Feel free to point out starter info on that. Of course there might also be a better way to accomplish this in 3.x.
In 2.x, the code below is meant to applied to the help field of the array questions, with separate comment questions following corresponding to each row of the array.
Code:
<script type="text/javascript" charset="utf-8"> $(document).ready(function() { // Identify the questions var qArray = $('#question{QID}'); var arrayLength = $('tr.answers-list', qArray).length; var qComments = qArray.nextAll('.text-long:lt('+arrayLength+')'); // Add some classes qArray.addClass('array-with-comments-question'); $(qComments).each(function(i) { $(this).addClass('comments-question index-'+i); $(this).append('<div class="modal-footer file-upload-modal-footer"><button class="comment-btn btn btn-success" type="button">Save changes</button></div>'); }); // Insert the comments buttons $('table.questions-list col', qArray).removeAttr('width'); $('table.questions-list thead tr', qArray).append('<td />'); $('tr.answers-list', qArray).each(function(i) { $(this).append('<td><button class="comment-button" style="width:86px" type="button" data-index="'+i+'">Comments</button></td>'); }); // Put the comments questions into modal dialogs $(qComments).dialog({ autoOpen: false, width: 372, modal: true, resizable: false, draggable: false, closeOnEscape: true }); // Click events for comments buttons $('.comment-button').click(function() { var thisIndex = $(this).attr('data-index'); $('.comments-question.index-'+thisIndex).dialog('open'); }); $('.comment-btn').click(function() { $(qComments).dialog('close'); }); // Interrupt the Next/Submit function (to put comments back in the form) $('#movenextbtn, #movesubmitbtn').bind('click', function () { qComments.hide(); $('#limesurvey').append(qComments); }); }); </script>
Attachments:
The topic has been locked.
- tpartner
- Offline
- LimeSurvey Community Team
Less
More
- Posts: 10099
- Thank you received: 3589
5 years 11 months ago - 5 years 7 months ago #168906
by tpartner
Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Replied by tpartner on topic Combined Array with large free text comment fields
Okay, here is updated JavaScript for 3.x.
[EDIT]24/08/2018 - Submit function modified to fix "Save and Resume Later" bug.[/EDIT]
Sample survey attached:
[EDIT]24/08/2018 - Submit function modified to fix "Save and Resume Later" bug.[/EDIT]
Code:
<script type="text/javascript" charset="utf-8"> $(document).on('ready pjax:scriptcomplete',function(){ // Identify the questions var qArrayID = {QID}; var qArray = $('#question'+qArrayID); var arrayLength = $('tr.answers-list', qArray).length; var qComments = qArray.nextAll('.text-long:lt('+arrayLength+')'); // Add some classes qArray.addClass('array-with-comments-question'); $(qComments).each(function(i) { $(this).addClass('comments-question index-'+i).css({ 'position': 'absolute', 'left': '-9999em' }); }); // Insert the comments buttons $('table.questions-list colgroup', qArray).append('<col />'); var tableWidth = $('table.questions-list:eq(0)', qArray).width(); var answerWidth = $('col.ls-col-odd:eq(0)', qArray).width(); var answerWidthPercent = (answerWidth/tableWidth)*100; var answersLength = $('col.ls-col-odd, col.ls-col-even', qArray).length; var answerWidthPercent2 = (answerWidthPercent*answersLength)/(answersLength+1) $('table.questions-list col', qArray).removeAttr('width'); $('table.questions-list col:not(.col-answers)', qArray).css('width', answerWidthPercent2+'%'); $('table.questions-list col:not(.col-answers)', qArray).css('width', 'auto'); $('table.questions-list thead tr', qArray).append('<td />'); $('tr.answers-list', qArray).each(function(i) { $(this).append('<td class="answer-item">\ <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#comments-'+qArrayID+'-'+(i+1)+'" data-backdrop="static" data-keyboard="false">Comments</button>\ </td>'); }); // Handle comments $(qComments).each(function(i) { // Create modals $('body').append('<div class="modal comments-modal" id="comments-'+qArrayID+'-'+(i+1)+'" tabindex="-1" role="dialog">\ <div class="modal-dialog" role="document">\ <div class="modal-content">\ <div class="modal-header">\ <h5 class="modal-title">'+$('.ls-label-question', this).html()+'</h5>\ </div>\ <div class="modal-body">\ </div>\ <div class="modal-footer">\ <button type="button" class="btn btn-primary" data-bs-dismiss="modal">Okay</button>\ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Clear</button>\ </div>\ </div>\ </div>\ </div>'); // Move textareas into modals $('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('textarea', this)); // Modal button events $('#comments-'+qArrayID+'-'+(i+1)+' .modal-footer .btn-secondary').on('click', function(e) { $('#comments-'+qArrayID+'-'+(i+1)+' textarea').val(''); }); }); // Interrupt the Next/Submit function (to put comments back in the form) $('#limesurvey').submit(function(e) { $('.comments-modal').each(function(i) { var qID = $('textarea:eq(0)', this).attr('id').split('X')[2]; $('#question'+qID+' .answer-item:eq(0)').append($('textarea:eq(0)', this)); }); }); }); </script>
Sample survey attached:
Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Attachments:
Last edit: 5 years 7 months ago by tpartner.
The following user(s) said Thank You: DenisChenu, duvemyster, krosser
The topic has been locked.
- duvemyster
- Offline
- Senior Member
Less
More
- Posts: 60
- Thank you received: 6
5 years 11 months ago #168925
by duvemyster
Replied by duvemyster on topic Combined Array with large free text comment fields
Thank you @tpartner ! This exceeded my expectation all around. It is elegant and works very smoothly. It can also be used with multiple array questions in the same group without anything needed to be renamed.
A brief note to any others who utilize this in 3.x: Be sure to apply it to the question field of the array, not the help field.
A brief note to any others who utilize this in 3.x: Be sure to apply it to the question field of the array, not the help field.
The topic has been locked.
- duvemyster
- Offline
- Senior Member
Less
More
- Posts: 60
- Thank you received: 6
5 years 5 months ago - 5 years 5 months ago #175971
by duvemyster
Replied by duvemyster on topic Combined Array with large free text comment fields
How can the solution in #168906 above be adjusted to use "list with comments" in the modal window, in place of "long free text"? This would be useful in categorizing the comments.
An initial stab is below (starting from #168906 above), but it loses the value of the 2nd of the 3 list items:
* Change ".text-long" to ".list-with-comment" in "var qComments" under "// Identify the questions."
* Pull the list in under "// Move textareas into modals" by adding the following:
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('ul', this));
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('li', this));
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('input', this));
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('label', this));
* Add ".substring(0,4)" to the end of "var qID" under "// Interrupt the Next/Submit function."
* And add the following under under "// Interrupt the Next/Submit function:"
$('#question'+qID+' .answer-list:eq(0)').append($('input:eq(0)', this)); // This 1st list item.
$('#question'+qID+' .answer-list:eq(0)').append($('input:eq(1)', this)); // This 3rd list item?
$('#question'+qID+' .answer-list:eq(0)').append($('input:eq(2)', this)); // Not working.
Any thoughts?
An initial stab is below (starting from #168906 above), but it loses the value of the 2nd of the 3 list items:
* Change ".text-long" to ".list-with-comment" in "var qComments" under "// Identify the questions."
* Pull the list in under "// Move textareas into modals" by adding the following:
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('ul', this));
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('li', this));
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('input', this));
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('label', this));
* Add ".substring(0,4)" to the end of "var qID" under "// Interrupt the Next/Submit function."
* And add the following under under "// Interrupt the Next/Submit function:"
$('#question'+qID+' .answer-list:eq(0)').append($('input:eq(0)', this)); // This 1st list item.
$('#question'+qID+' .answer-list:eq(0)').append($('input:eq(1)', this)); // This 3rd list item?
$('#question'+qID+' .answer-list:eq(0)').append($('input:eq(2)', this)); // Not working.
Any thoughts?
Last edit: 5 years 5 months ago by duvemyster. Reason: readability
The topic has been locked.
- duvemyster
- Offline
- Senior Member
Less
More
- Posts: 60
- Thank you received: 6
5 years 5 months ago #175974
by duvemyster
Replied by duvemyster on topic Combined Array with large free text comment fields
Update to last post above: The last three lines should have ".answer-item" rather than ".answer-list". Also, pulling in 'ul' takes care of 'li', 'input', and 'label', so those lines aren't needed.
Here is the updated text:
How can the solution in #168906 above be adjusted to use "list with comments" in the modal window, in place of "long free text"? This would be useful in categorizing the comments.
An initial stab is below (starting from #168906 above), but it loses the value of the 2nd of the 3 list items:
* Change ".text-long" to ".list-with-comment" in "var qComments" under "// Identify the questions."
* Pull the list in under "// Move textareas into modals" by adding the following:
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('ul', this));
* Add ".substring(0,4)" to the end of "var qID" under "// Interrupt the Next/Submit function."
* And add the following under under "// Interrupt the Next/Submit function:"
$('#question'+qID+' .answer-item:eq(0)').append($('input:eq(0)', this)); // This 1st list item.
$('#question'+qID+' .answer-item:eq(0)').append($('input:eq(1)', this)); // This 3rd list item?
$('#question'+qID+' .answer-item:eq(0)').append($('input:eq(2)', this)); // Not working.
Any thoughts?
Here is the updated text:
How can the solution in #168906 above be adjusted to use "list with comments" in the modal window, in place of "long free text"? This would be useful in categorizing the comments.
An initial stab is below (starting from #168906 above), but it loses the value of the 2nd of the 3 list items:
* Change ".text-long" to ".list-with-comment" in "var qComments" under "// Identify the questions."
* Pull the list in under "// Move textareas into modals" by adding the following:
$('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('ul', this));
* Add ".substring(0,4)" to the end of "var qID" under "// Interrupt the Next/Submit function."
* And add the following under under "// Interrupt the Next/Submit function:"
$('#question'+qID+' .answer-item:eq(0)').append($('input:eq(0)', this)); // This 1st list item.
$('#question'+qID+' .answer-item:eq(0)').append($('input:eq(1)', this)); // This 3rd list item?
$('#question'+qID+' .answer-item:eq(0)').append($('input:eq(2)', this)); // Not working.
Any thoughts?
The topic has been locked.
- tpartner
- Offline
- LimeSurvey Community Team
Less
More
- Posts: 10099
- Thank you received: 3589
5 years 5 months ago #175982
by tpartner
Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Replied by tpartner on topic Combined Array with large free text comment fields
Can you attach a sample survey (.lss file) containing only the relevant questions?
Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
The topic has been locked.
- duvemyster
- Offline
- Senior Member
Less
More
- Posts: 60
- Thank you received: 6
5 years 5 months ago #175988
by duvemyster
Replied by duvemyster on topic Combined Array with large free text comment fields
Yes. Thank you for looking at this. A draft lss file for Combined Array with List with Comments modal windows is attached. This draft only retains selections of the 1st and 3rd categories in the list with comment entries. It loses selections of the 2nd category in list with comment entries.
Attachments:
The topic has been locked.
- tpartner
- Offline
- LimeSurvey Community Team
Less
More
- Posts: 10099
- Thank you received: 3589
5 years 5 months ago - 5 years 5 months ago #176025
by tpartner
Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Replied by tpartner on topic Combined Array with large free text comment fields
The script below will place the list-with-comments questions in modals.
Note, if you allow backwards navigation in the survey, you will need to disable AJAX in the theme options for this workaround to behave correctly.
Sample survey attached:
Note, if you allow backwards navigation in the survey, you will need to disable AJAX in the theme options for this workaround to behave correctly.
Code:
<script type="text/javascript" charset="utf-8"> $(document).on('ready pjax:scriptcomplete',function(){ console.log(new Date()); // Identify the questions var qArrayID = {QID}; var qArray = $('#question'+qArrayID); var arrayLength = $('tr.answers-list', qArray).length; var qComments = qArray.nextAll('.list-with-comment:lt('+arrayLength+')'); // Add some classes qArray.addClass('array-with-comments-question'); $(qComments).each(function(i) { $(this).addClass('comments-question index-'+i).css({ 'position': 'absolute', 'left': '-9999em' }); }); // Insert the comments buttons if($('button[data-bs-toggle="modal"]', qArray).length == 0) { $('table.questions-list colgroup', qArray).append('<col />'); var tableWidth = $('table.questions-list:eq(0)', qArray).width(); var answerWidth = $('col.ls-col-odd:eq(0)', qArray).width(); var answerWidthPercent = (answerWidth/tableWidth)*100; var answersLength = $('col.ls-col-odd, col.ls-col-even', qArray).length; var answerWidthPercent2 = (answerWidthPercent*answersLength)/(answersLength+1) $('table.questions-list col', qArray).removeAttr('width'); $('table.questions-list col:not(.col-answers)', qArray).css('width', answerWidthPercent2+'%'); $('table.questions-list col:not(.col-answers)', qArray).css('width', 'auto'); $('table.questions-list thead tr', qArray).append('<td />'); $('tr.answers-list', qArray).each(function(i) { $(this).append('<td class="answer-item">\ <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#comments-'+qArrayID+'-'+(i+1)+'" data-backdrop="static" data-keyboard="false">Comments</button>\ </td>'); }); // Handle comments $(qComments).each(function(i) { // Create modals $('body').append('<div class="modal comments-modal" id="comments-'+qArrayID+'-'+(i+1)+'" tabindex="-1" role="dialog">\ <div class="modal-dialog" role="document">\ <div class="modal-content">\ <div class="modal-header">\ <h5 class="modal-title">'+$('.ls-label-question', this).html()+'</h5>\ </div>\ <div class="modal-body">\ </div>\ <div class="modal-footer">\ <button type="button" class="btn btn-primary" data-bs-dismiss="modal">Okay</button>\ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Clear</button>\ </div>\ </div>\ </div>\ </div>'); // Move list-with-comments questions into modals $('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('div.answer-container', this)).append($('<div class="clearfix" />')); // Modal button events $('#comments-'+qArrayID+'-'+(i+1)+' .modal-footer .btn-secondary').on('click', function(e) { $('#comments-'+qArrayID+'-'+(i+1)+' input:radio').each(function(i) { $(this).prop('checked', false); checkconditions($(this).attr('value'), $(this).attr('name'), 'radio'); }); $('#comments-'+qArrayID+'-'+(i+1)+' textarea').val('').trigger('change'); }); }); // Interrupt the Next/Submit function (to put comments back in the form) $('#limesurvey').submit(function(e) { $('.comments-modal').each(function(i) { var qID = $('input:radio:eq(0)', this).attr('name').split('X')[2]; $('#question'+qID).append($('div.answer-container', this)); }); }); } }); </script>
Sample survey attached:
Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Attachments:
Last edit: 5 years 5 months ago by tpartner.
The following user(s) said Thank You: duvemyster
The topic has been locked.
- krosser
- Offline
- Elite Member
Less
More
- Posts: 222
- Thank you received: 10
5 years 2 weeks ago - 5 years 2 weeks ago #182636
by krosser
Hi Tony!
Could you please test the script again, as the Next/Submit part is still not working properly. It is kinda buggy. When used in an active survey with tokens, then it does not allow both 'Resume later' link or 'Index menu' to save or change groups. Only the Next button works. Also, when you click on the Previous button to check that page, sometimes you see another column created and what was written in text boxes is lost (see the screenshot below).
I have several surveys that rely on these workarounds and it will be a disaster.
If you manage to correct that it would help a lot, since this problem occurs in all other similar scripts. For example, the list-with-comments questions in modals that you posted the last here.
I have tested in LS 3.15 & 16.
Many thanks in advance!
EDIT: I have also found that the issue occurs when there are at least two of such a question on the same page.
I have created a text survey where one of the issues happens - the Resume later and Index menu do not work unless you click on Next afterwards. But it doesn't clear the text when you then click on Previous, like in other cases. It is strange that it behaves differently.
monitoringhsd.limequery.com/681749?token=TEST&newtest=Y
I'm using the latest LS 3.22 hosted on LS servers, not installed locally.
Replied by krosser on topic Combined Array with large free text comment fields
tpartner wrote: Okay, here is updated JavaScript for 3.x.
[EDIT]24/08/2018 - Submit function modified to fix "Save and Resume Later" bug.[/EDIT]
Code:<script type="text/javascript" charset="utf-8"> $(document).on('ready pjax:scriptcomplete',function(){ // Identify the questions var qArrayID = {QID}; var qArray = $('#question'+qArrayID); var arrayLength = $('tr.answers-list', qArray).length; var qComments = qArray.nextAll('.text-long:lt('+arrayLength+')'); // Add some classes qArray.addClass('array-with-comments-question'); $(qComments).each(function(i) { $(this).addClass('comments-question index-'+i).css({ 'position': 'absolute', 'left': '-9999em' }); }); // Insert the comments buttons $('table.questions-list colgroup', qArray).append('<col />'); var tableWidth = $('table.questions-list:eq(0)', qArray).width(); var answerWidth = $('col.ls-col-odd:eq(0)', qArray).width(); var answerWidthPercent = (answerWidth/tableWidth)*100; var answersLength = $('col.ls-col-odd, col.ls-col-even', qArray).length; var answerWidthPercent2 = (answerWidthPercent*answersLength)/(answersLength+1) $('table.questions-list col', qArray).removeAttr('width'); $('table.questions-list col:not(.col-answers)', qArray).css('width', answerWidthPercent2+'%'); $('table.questions-list col:not(.col-answers)', qArray).css('width', 'auto'); $('table.questions-list thead tr', qArray).append('<td />'); $('tr.answers-list', qArray).each(function(i) { $(this).append('<td class="answer-item">\ <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#comments-'+qArrayID+'-'+(i+1)+'" data-backdrop="static" data-keyboard="false">Comments</button>\ </td>'); }); // Handle comments $(qComments).each(function(i) { // Create modals $('body').append('<div class="modal comments-modal" id="comments-'+qArrayID+'-'+(i+1)+'" tabindex="-1" role="dialog">\ <div class="modal-dialog" role="document">\ <div class="modal-content">\ <div class="modal-header">\ <h5 class="modal-title">'+$('.ls-label-question', this).html()+'</h5>\ </div>\ <div class="modal-body">\ </div>\ <div class="modal-footer">\ <button type="button" class="btn btn-primary" data-bs-dismiss="modal">Okay</button>\ <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Clear</button>\ </div>\ </div>\ </div>\ </div>'); // Move textareas into modals $('#comments-'+qArrayID+'-'+(i+1)+' .modal-body').append($('textarea', this)); // Modal button events $('#comments-'+qArrayID+'-'+(i+1)+' .modal-footer .btn-secondary').on('click', function(e) { $('#comments-'+qArrayID+'-'+(i+1)+' textarea').val(''); }); }); // Interrupt the Next/Submit function (to put comments back in the form) $('#limesurvey').submit(function(e) { $('.comments-modal').each(function(i) { var qID = $('textarea:eq(0)', this).attr('id').split('X')[2]; $('#question'+qID+' .answer-item:eq(0)').append($('textarea:eq(0)', this)); }); }); }); </script>
Sample survey attached:
Hi Tony!
Could you please test the script again, as the Next/Submit part is still not working properly. It is kinda buggy. When used in an active survey with tokens, then it does not allow both 'Resume later' link or 'Index menu' to save or change groups. Only the Next button works. Also, when you click on the Previous button to check that page, sometimes you see another column created and what was written in text boxes is lost (see the screenshot below).
I have several surveys that rely on these workarounds and it will be a disaster.
If you manage to correct that it would help a lot, since this problem occurs in all other similar scripts. For example, the list-with-comments questions in modals that you posted the last here.
I have tested in LS 3.15 & 16.
Many thanks in advance!
EDIT: I have also found that the issue occurs when there are at least two of such a question on the same page.
I have created a text survey where one of the issues happens - the Resume later and Index menu do not work unless you click on Next afterwards. But it doesn't clear the text when you then click on Previous, like in other cases. It is strange that it behaves differently.
monitoringhsd.limequery.com/681749?token=TEST&newtest=Y
I'm using the latest LS 3.22 hosted on LS servers, not installed locally.
Last edit: 5 years 2 weeks ago by krosser. Reason: extra details...
The topic has been locked.
- tpartner
- Offline
- LimeSurvey Community Team
Less
More
- Posts: 10099
- Thank you received: 3589
5 years 2 weeks ago #182649
by tpartner
Cheers,
Tony Partner
Solutions, code and workarounds presented in these forums are given without any warranty, implied or otherwise.
Replied by tpartner on topic Combined Array with large free text comment fields
Disable AJAX in the survey theme options.
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: DenisChenu, krosser
The topic has been locked.
- krosser
- Offline
- Elite Member
Less
More
- Posts: 222
- Thank you received: 10
5 years 2 weeks ago #182663
by krosser
I'm using the latest LS 3.22 hosted on LS servers, not installed locally.
Replied by krosser on topic Combined Array with large free text comment fields
Thanks, Tony! Disabling AJAX has solved the issue with creating extra copies of the column, but it didn't solve the issue with Resume later & Question Index when there are two questions with this workaround in the same question group. Please see the link to an active survey or the attached copy. Do 'Resume later' and 'Question Index' work for you?tpartner wrote: Disable AJAX in the survey theme options.
I'm using the latest LS 3.22 hosted on LS servers, not installed locally.
The following user(s) said Thank You: duvemyster
The topic has been locked.