jquery not showing live data unless refresh [duplicate] - javascript

This question already has an answer here:
refresh jquery data constantly
(1 answer)
Closed 8 years ago.
I am trying to count the amount of dropdowns that have a specific item selected in them. I have my code below, but it works like this:
select options in the drop downs, press refresh page, selected items in drop down remain there, and the script reads the amount of times each were selected.
The dropdown boxes are listed on the page with questions. there are about 100 dropdowns. every drop down has the same options.
this is a repeating code that lists all the drop down selections on the right side of the page, and shows the number of how many times each was used next to it. it works, just not dynamically. I want it to work instantly when an item is selected, without having to make selections and then refresh.
<%
mySQL="SELECT * FROM admins WHERE area="&parea&" AND type>2"
call getFromDatabase(mySQL, rstemp4, "addscheduleform5.asp")
do while Not rstemp4.EOF
pempidw=rstemp4("idadmin")
pempname1=rstemp4("firstname")
%>
<%=pempname%>=
<script type="text/javascript">
var scheduled = $("select").filter(function() {
return $(this).val() == "<%=pempidw%>";
});
document.write(scheduled.length);
</script>
<%rstemp4.movenext
loop%>
EXAMPLE:
For example, if you have 5 dropdowns. so if you select
X, A, B, X, A
in the drop downs, the code reads
X=2 A=2 B=1
Now it works, if you make your dropdown selections, and refresh the page, the drop down selections remain the same, and the code reads the amount of times each were selected.
Now if you change your first option from
X to A,
then the code still reads:
X=2 A=2 B=1
unless you refresh the page, then you see:
X=1 A=3 B=1.
For those that don't know asp, this javascript function has nothing to do with my site being asp. the "<%=pempidw%>" simply displays a number on the loaded page, referencing the select value.
see below what the loaded script would appear as.for reference on what "<%=pempidw%>" means only
<option value="2">2</option>
<script type="text/javascript">
var scheduled = $("select").filter(function() {
return $(this).val() == "2";
});
document.write(scheduled.length);
</script>

Given document.write really isn't a good way of doing this, I'm going to (for the sake of the example) place a <span id="result"></span> on thepage we can [re]reference with the output.
Having said that, the test code should be wrapped in a function so we can re-use it. Currently it's only executing on the initial visit to the page. To correct that, we're also going to execute our new function on a change to any of the dropdowns.
function getSelectedValues(){
var matches = $('select').filter(function(){
return $(this).val() == '<%=pempidw%>';
}).length;
// here's where we just update that new <span>
$('span#result').text(matches);
}
// call it on initial page visit
getSelectedValues();
// and here we bind to the change event for the selects
// and re-call our above function.
$('select').on('change', getSelectedValues);

Related

Clear dropdown Select2 populated from JSP / Ajax with a button only works once

I have a page in which to make a query to the database, 12 filters are applied (each filter corresponds to a select2 dropdown).
When the page loads, the selects are filled by default with data from the java controller.
Example from a jsp page:
<select id="selectFPA" name="selectFPA" form="formResult" class="form-control">
<option selected>All the results</option>
<c:forEach items="${fpaList}" var="fpaList">
<option><c:out value="${fpaList.fpaname}" /></option>
</c:forEach>
</select>
But, if the user selects any value in any of the filters, all the filters are updated based on the chosen selection, through an AJAX call.
For example, suppose we have two select filters (dropdown):
Select 1 (Animal group):
- Birds
- Mammals
Select 2 (Animal name):
- Parrot
- Dog
If the user chooses mammals, an AJAX function will be called that will query the database and update the content of the select 2, eliminating the Parrot option. (And so on with up to 12 filters).
The problem comes when I want to clear the applied filters and return to the original select content (the content that appears by default every time the page is loaded from the java controller).
I have tried many things, from similar Stackoverflow questions without success.
The last thing I tried was:
Save the initial content of the select in a variable:
const fpa = $("#selectFPA").find("option").clone();
Onclick event (Reset filters button)
$("#ResetFilters").on("click",function() {
//first we empty the content
$('#selectFPA').empty().trigger('change.select2');
//original value injection
$("#selectFPA").html(fpa),
$('#selectFPA').trigger('change.select2')
})
This works fine if I press the button once, if I press the button a second time, the selects randomly select different values by default and they behave strangely.
I know this is a very specific question, but could someone help me? What am I doing wrong?
Thank you.
I think as per this answer you cannot create constant in jquery that's the reason only first time it works and next time it doesn't .Alternate, solution might be assign that clone value to some div and fetch it anytime when needed.Like below :
//call when page loads for the first time
$(document).ready(function() {
//cloning
var fpa = $("#selectFPA").find("option").clone();
//assigning value to div
$("#abc").html(fpa);
$("#ResetFilters").on("click", function() {
//getting clone value from div
var c = $("#abc").find("option").clone();
//first we empty the content
// $('#selectFPA').empty().trigger('change.select2');
//original value injection
$("#selectFPA").html(c);
//$('#selectFPA').trigger('change.select2')
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="selectFPA" name="selectFPA" form="formResult" class="form-control">
<option selected>All the results</option>
<option>1</option>
<option>2</option>
</select>
<button id="ResetFilters">Reset</button>
<div id="abc" style="display:none"></div>

How can I get my drop down to select a value after re-loading it via javascript

I have an application that allows users to edit the reason and next action for a selected receiving discrepancy via 2 drops downs. One of the drop downs is simply hard coded directly into the HTML the 2nd one is being loaded via a quick JavaScript based on what value is in 1st drop down.
The first drop down has 14 options for reasons, each of which has 6-12 options for action steps. If user changes first drop down reason selection, it has to go back to SQL db and retrieve the appropriate list of action step options to use for 2nd drop down.
All of that works.
The problem I'm having is when the user first selects a discrepancy to edit. At that time it loads the view and based on the value stored on SQL DB it sets the value of the 1st drop down, and then runs java to first empty, then append new list of options to 2nd drop down.
What I can NOT get to work is having it set the value of the 2nd drop down, after that java is ran to create list of options, once again trying to set it based on the value stored on SQL DB for that discrepancy.
If I hard code the 2nd list of options the same as first list, and don't have it use java to re-load it until the first drop down is changed, then I can set the value the same way I do the first one. The problem there is then the 2nd drop down would have about 30-40 options listed, until you change first drop down - only 6-12 of which would be accurate for that specific reason selected.
The way I originally set the 2 drop down values, when both lists were hard coded (still works on first drop down):
<script>
// script to set drop down values to those stored on DB after document finished loading
document.getElementById("ReasonDD").value = "#Model.DiscReason";
document.getElementById("NextActionDD").value = "#Model.NextAction";
</script>
Script used to change 2nd drop down if first one is changed (again works fine):
$(function () {
$("#ReasonDD").change(function () {
var option = $(this).val();
$("#NextActionDD").empty();
var url = "GetActionValues?selectedOption=" + option;
$.post(url, function (actValues) {
$.each(actValues, function (i, actValue) {
$("#NextActionDD").append($('<option></option>').val(actValue).html(actValue));
});
});
});
});
This script is one being ran when discrepancy is first selected, it is correctly loads 2nd drop down but I've tried all 3 shown ways both together and individually to set the value but none have worked so far. The console.log shown has a valid choice equal to one of the values loaded into 2nd drop down:
$(function () {
var reasonLoad = "#Model.DiscReason";
if (reasonLoad > "") {
var option = reasonLoad;
$("#NextActionDD").empty();
var url = "GetActionValues?selectedOption=" + option;
$.post(url, function (actValues) {
$.each(actValues, function (i, actValue) {
$("#NextActionDD").append($('<option></option>').val(actValue).html(actValue));
});
});
console.log("#Model.NextAction");
$("#NextActionDD").val = "#Model.NextAction";
$("#NextActionDD").value = "#Model.NextAction";
document.getElementById("NextActionDD").value = "#Model.NextAction";
}
});
I've now also tried Rajesh G's idea of:
$('#NextActionDD option[#Model.NextAction]').attr('selected','selected');
I added it directly after my console.log("#Model.NextAction") and instead of and commented out the other 3. Ran 2 test with both and 2 with it instead of console.log line, total of 4 tests.
On 2 tests with console.log on the console showed the "#Model.NextAction" values to be "Other" and "Wait for Vendor Response" but then gave the same error message all 4 times (both times with console.log and both times with it replaced) of:
Error: Syntax error, unrecognized expression: #NextActionDD option[Close Discrepency]
Although Close Discrepancy isn't the #Model.NextAction value, but was the last option appended to the list of options for the #NextActionDD dropdown

Dynamically remove A LOT of <options> from <select>

Does anyone have any solution to improve the speed when deleting/adding <option> from a <select> when it has 60k+ elements?
I've a form with two <select>, let's call them selectA and selectB. I want the values of selectB to change when selectA is changed. Like (code not functional, just for idea):
if selectA = option1
then selectB.options = [opt1_1, opt1_2, opt1_3, ...]
else if selectA = option2
then selectB.options = [opt2_1, opt2_2, opt2_3, ...]
...
I have a (quite huge) variable that gives me the list of option for selectB associated with selectA value.
I've found many example for that kind of thing and it works on small examples. For now, I've something like :
$(document).ready(function() {
$("#selectB").html("<option value='' slected='selected'>Choose SelectA first</option>");
$("#selectA").change(function() {
var val = $(this).val();
var options = //... string generated with all <option></options> depending on $val
$("#selectB").html(options)
});
});
Here comes the mess, as selectB is a list of IPv4 that can contain a full /16. So that's 60k+ elements to handle (ouch ^^ ). And that's why I don't want to have every option in the select but instead "pre-select" with selectA and then "sub-select" with selectB.
I want to have all possible IPs initially in the HTML form because of the following reason : Even if JS is not enabled, the user must be able to choose one IP (the server checks that the choice from selectA and selectB corresponds). And only if JS is enabled I remove everything from selectB and add only the values I want when selectA is changed. So you might say that anyway a user with no JS can't event choose an option without loading 1GB+ RAM of options and wait 5-10 min for every option to be loaded, but I also want the page to works if there is only a few options to display like 1k.
I've to admit I was amazed my browser (FF) handles the creation of the page quite quickly. But when JS delete all the options, everything freezes on :
$("#selectB").html("<option value='' slected='selected'>Choose SelectA first</option>");
What I've managed to debug is that what takes time is when the browser needs to unload/delete every options. Actually creating them is not that slow.
So I would like to know if there is a faster solution than what I'm doing right now. How can I speed up the deletion of all <option> in selectB ?
Any suggestion is welcome from a simple change in JS to change the whole structure of HTML to not use <select> but something else (I don't know).

Prematurely exiting a Loop and Merge block in Qualtrics

I'm currently working on a Qualtrics survey in which respondents have to solve a long list of anagrams, and then answer some demographic questions.
To make the anagram part easier, I've used a Loop and Merge block: the first field is the anagram to be solved, the second field is the solution of the anagram, and the survey can therefore check the answer of the respondent against the solution for each anagram.
As it is, the survey is working perfectly: however, I'd like to allow respondents to prematurely exit the loop by typing "EXIT" in the response field, and to redirect them to the next question block (the demographic questions).
This is typically something that is achieved using "Skip" logic: however, skipping to the end of the block does not do the trick (the loop restarts). I managed to redirect them to the end of the survey, but not to the demographic question block.
Is there a way to use javascript to jump to the demographic block or exit the loop and merge block prematurely? Am I missing a Qualtrics option that would do the trick?
If this is still relevant to you: I needed the same functionality and this is how I solved it: First, I define a helper variable, call it EndLoop, which I initialize to 0. Then I set up a function to change the value of EndLoop to 1 after people hit a button, additionally I add a display logic to the question in the loop showing them only if EndLoop is still 0 and hiding the questions as soon as EndLoop is 1.
This is a step-by-step instruction and the javascript and html code.
The bold stuff is what you need to do, the bulletpoints a more detailed instruction how to do it.
1. Before your loop-and-merge define an embedded data field called EndLoop and initialize it as 0.
Go to the Survey Flow Panel
Add a new element > select embedded data field
Name the field 'EndLoop'
Set its value t0 the number 0 by click on the link "set value now"
Make sure you move it before the merge-and-loop block
2. For each item in the loop set a display logic to show them conditional on 'EndLoop' = 0
Go to the options menu of each question in the loop
Select "add display logic"
Select "Embedded Data" from the first dropdown menu
A new type field opens > as name type EndLoop + select "is equal to" + type 0 as value
3. Insert a customized button into the page where people should be able to opt-out. The button runs a user-defined function called setEndLoop() onclick.
Click on the question where the button should appear
On the top-right of the question text select "html view"
The code I used is:
<input id="css-class-mybutton" onclick="setEndLoop()" value=" done " type="button">
If you want to change the button text, change the " done " in value = " done "
4. Define the function setEndLoop() using custom javascript to change the value of EndLoop to 1 and emulate a next button click
Go to the options menu of each question in the loop
Select "add JavaScript"
The code I used is:
/* Get the EndLoop variable */
var EndLoop = "${e://Field/EndLoop}";
Qualtrics.SurveyEngine.addOnload(function(){
/* hide previous and next button */
$('NextButton') && $('NextButton').hide();
$('PreviousButton') && $('PreviousButton').hide();
/* Function: on click on user-defined button -> change the field EndLoop */
var that = this;
setEndLoop = function(){
Qualtrics.SurveyEngine.setEmbeddedData('EndLoop', 1);
that.clickNextButton();
};
});
The button will not have the default style, thus, define a custom css to style your button to look like the buttons of your theme. The class name for the button I used here is id="css-class-mybutton", use .css-class-mybutton{ ... } in the css.
Hope that helps.
I know this is a bit late, but I had a similar issue and wanted to post an alternative solution. I used the loop and merge function, but I didn't want to have participants click on a button to exit the loop, instead I wanted to use a multiple choice question to exit the loop. This question was, "would you like to ask more questions?", with responses yes and no. If the participant selected "Yes" they would keep going through the loop and if they selected "No" they would exit the loop and go on to the next block of questions.
My first two steps are the same as those above.
1.Set up an Embedded data field named EndLoop and set the value to 1.
- in the survey flow panel select add an element. Then type in the name EndLoop.
- Then select set value now and set the value to 1.
- make sure that this is before your loop and merge block in the survey flow.
For each question in the loop and merge block use display logic to ensure that they only display when the embedded data element EndLoop is 1.
Now for the question "would you like to ask more questions?" add the following code in the add javascript area.
the javascript area can be found by clicking the advanced options button under the question number on the lefthand side of the screen. Select 'Add javascript...'
There will be some code already present...it should look like this:
Qualtrics.SurveyEngine.addOnload(function()
{
/Place Your Javascript Below This Line/
});
Basically I used event tracking to update the embedded data field EndLoop to the numerical value associated with the answer choice when the answer choice was selected. In this case the answer "Yes" had a value of 1 because it was the first option and "No" had a value of 2 because it was the second option. When "No" was selected, the embedded data field EndLoop was set to a value of 2. This then meant that none of the questions would display since they have display logic to ensure they only display when the EndLoop field is 1.
My entire code looks like this:
Qualtrics.SurveyEngine.addOnload(function ()
{
this.questionclick = function(event,element)
{
console.log(event, element);
if (element.type == 'radio')
{
var choiceNum = element.id;
if (choiceNum == 2)
{
Qualtrics.SurveyEngine.setEmbeddedData("EndLoop", choiceNum);
}
}
}
});
I used the second solution. Here's a minor correction for the script:
I wrote element.id.split('~')[2] instead of element.id, and it worked!
Qualtrics.SurveyEngine.addOnload(function ()
{
this.questionclick = function(event,element)
{
console.log(event,element);
if (element.type == 'radio')
{
var choiceNum = element.id.split('~')[2];
if (choiceNum == 2)
{
Qualtrics.SurveyEngine.setEmbeddedData("EndLoop", choiceNum);
}
}
}
});

JavaScript variable not global throughout AJAX refreshes?

I'm building a really simple quiz: http://fh80.student.eda.kent.ac.uk/fyp-assets/quiz/quiz.php
At the end of the quiz it should display how many you got right e.g 5/10.
One thing about it is that each question is pulled in via AJAX so every question is a different .php file. Also, for every question there is the question page and an answer page. E.g question1.php and question1a.php
I've created a variable on the page for the score:
/* Quiz Score */
var quizScore = 0;
When you load up question1.php through AJAX, there is this script:
document.getElementById("nextQuestion1a").onclick = function(){
var correctAnswer = document.getElementById("lightningbolt");
if (correctAnswer.checked){
quizScore = quizScore+1;
}else{}};
The correct answer has an ID of lightningbolt
<input type="radio" name="question1" value="lightningbolt" id="lightningbolt">Lightning Bolt<br>
So, when this input/radio button is checked it should follow the function and +1 to quizScore;
if (correctAnswer.checked){
quizScore = quizScore+1;
I think this isn't working, because the event handler for doing this is onClick of nextQuestion(ID) - this is the same button which launches the AJAX which takes you to the next page (in this case, clicking nextQuestion1a takes you to question1a.php)
So I am thinking I need to bind it different somehow. Like not on click of that button, but just on check of the radio button.
At the end of the quiz I output the score as such:
<h3>
You got
<script>document.write(quizScore);</script>
/10
</h3>
But this doesn't output any value, not even 0 as the variable was initialised.
ETA: the variable does exist on the page at all times. The variable is not declared within the refreshed content. So the variable is always there.

Categories