I'm building a personality-type quiz and having difficulty tailoring the results page as I'd like it to. The if statement, contained in the display_scenario function, isn't working. I want it to generate a different final message depending on the value of the countValue variable but it's not working. If you are able to help me understand why it's not working, I'd appreciate it.
The key pieces of code are below. It's also in place on Codepen: http://codepen.io/msummers40/pen/eZaePe
Essentially, the quiz:
- asks people a series of questions
- each answer has a numeric weight assigned to it
- this numeric weight is tallied in the countValue variable
- I want to use the countValue variable as a way to generate one of four final pages
I've tried to set up an if statement at the end of the quiz but it's just not working and I'm unsure of how to get this to work - it seems to be building the final view regardless of what's in the if statement.
If you are able to help, thank you.
<body>
<!-- QUIZ BEGINS -->
<div id="wrapper">
<h2 id="cyoaHeader">TITLE HERE<br><small>SUBHED</small></h2>
<div id="quizImage"> </div>
<div id="prompt"> </div>
<div id="options"> </div>
<div id="buildingStatus"> </div>
</div>
<div id="addLinks"> </div>
<!-- QUIZ ENDS -->
<script>
// JSON for quiz
// Contains the questions, images and variable to give answers weight/direction
var story = {
intro: {
prompt: 'You need to get up and out and get on with a big task - what song would propel you out of bed?',
quizImage: '<img id="quizImage" src="https://upload.wikimedia.org/wikipedia/commons/a/ab/Semi-nude_woman_getting_out_of_bed_(rbm-QP301M8-1887-265a~5).jpg"><br />',
options: [{
name: 'Song 4',
path: 'questionTwo',
addition: 4
}, {
name: 'Song 3',
path: 'questionTwo',
addition: 2
}, {
name: 'Song 2',
path: 'questionTwo',
addition: 3
}, {
name: 'Song 1',
path: 'questionTwo',
addition: 1
}]
},
questionTwo: {
prompt: 'Sentence.<br/><br/>Question 2?',
quizImage: '<img id="quizImage" src="http://www.allgifs.com/wp-content/uploads/2013/09/pancake.gif">',
options: [{
name: 'A',
path: 'result',
addition: 4
}, {
name: 'B',
path: 'result',
addition: 3
}, {
name: 'C',
path: 'result',
addition: 2
}, {
name: 'D',
path: 'result',
addition: 1
}]
},
result: {
prompt: 'This is the default statement on the results page. I need to make it tailored to the countValue variable',
quizImage: '<img id="quizImage" src="http://viralgifs.com/wp-content/uploads/2014/03/cat_did_u_forget.gif">',
options: [{
name: 'FINAL CTA',
path: 'intro',
addition: 0
}]
}
};
//establishing counter for weighted answer
var countValue = 0;
console.log(countValue);
var additionInt = 0;
console.log(additionInt);
// Option is an object with properties {name and path objects, addition array}
function display_scenario(options) { //value passed had been chosen_options
var option_name = options.name;
var option_path = options.path;
var additionInt = options.addition;
countValue += additionInt;
// countValue = (additionInt + countValue);
console.log(additionInt);
console.log(countValue);
var scenario = story[option_path];
// Clear the #prompt, #quizImage, #options, #addLinks, #buildingStatus divs before writing new ones in if statment below -- GROUP THESE IN A FUNCTION BEFORE GO LIVE
jQuery('#prompt').empty();
jQuery('#quizImage').empty();
jQuery('#options').empty();
jQuery('#addLinks').empty();
jQuery('#buildingStatus').empty();
// THIS IF ELSE STRUCTURE DOESN'T SEEM TO BE WORKING - I'M TRYING TO SET IT UP SO THAT IT DISPLAYS ONE OF FOUR OPTIONS, DEPENDING ON THE VALUE OF THE countValue VARIABLE. ATM ONLY THREE OPTIONS ARE IN PLACE; NONE ARE WORKING.
// Create a <p> to display what the user has chosen if option_name is not null and append it to the #prompt <div>
if (options.name != 'result') {
jQuery('<p>').html('<i>You selected <b>' + option_name + '</b></i><br><p>And the running total is ' + countValue + '</p>').appendTo('#buildingStatus');
// Append the scenario's prompt
jQuery('<p>').html(scenario.prompt).appendTo('#prompt');
// Appending an image
jQuery('<p>').html(scenario.quizImage).appendTo('#quizImage');
// Appending links in the addLinks div
jQuery('<div>').html(scenario.addLinks).appendTo('#addLinks');
} else if (options.name == 'result' && countValue<17) {
jQuery('<p>').html('<i>Yay! This option worked. You selected <b>' + option_name + '</b></i><br><p>And the running total is ' + countValue + '</p>').appendTo('#buildingStatus');
// Append the scenario's prompt
jQuery('<p>').html(scenario.prompt).appendTo('#prompt');
// Appending an image
jQuery('<p>').html(scenario.quizImage).appendTo('#quizImage');
// Appending links in the addLinks div
jQuery('<div>').html(scenario.addLinks).appendTo('#addLinks');
} else {
jQuery('<p>').html('<i>Yay! This option worked. You selected <b>' + option_name + '</b></i><br><p>And the running total is ' + countValue + '</p>').appendTo('#buildingStatus');
// Append the scenario's prompt
jQuery('<p>').html(scenario.prompt).appendTo('#prompt');
// Appending an image
jQuery('<p>').html(scenario.quizImage).appendTo('#quizImage');
// Appending links in the addLinks div
jQuery('<div>').html(scenario.addLinks).appendTo('#addLinks');
};
// Append the options into the #options <div>
// We want to loop through all the options and create buttons for each one. A regular for-loop would not suffice because adding a button is not asynchronous. We will create an asynchronous loop by using recursion
function add_option_button(index) {
if (index === scenario.options.length) {
// Base case
return;
}
var option = scenario.options[index];
// Create a <button> for this option and append it to the #options <div>
jQuery('<button>')
.html(option.name)
.click(function(e) {
// This is an onclick handler function. It decides what to do after the user has clicked on the button.
// First, prevent any default thing that the button is going to do, since we're specifying our own action for the button
e.preventDefault();
// We'll want to call display_scenario() with this option
display_scenario(option);
})
.appendTo('#options');
// Add the next option button
add_option_button(index + 1);
}
add_option_button(0);
}
// This function waits until the document is ready
jQuery(document).ready(function() {
// Start the quiz
display_scenario({
name: null,
path: 'intro',
addition: 0
});
});
</script>
</body>
</html>
I think you need to recalculate the sum whenever the user changes something, apart from displaying the scenarios everytime. Split the display_scenario function into one to display the options, and into separate logic to sum up all options choosen.
Related
Good evening, I currently save the value of a field of the grid in an item (P5_VALUE),send it to another page (page 6) and store it in an item (P6_VALUE) through a button
Action: Redirect to Page in this application.
Target: Page in this application , Page: 6, set Items: NAME: P5_VALUE, VALUE: P6_VALUE, Action: Reset Pagination. This is the url that is generated: http://ip:port/ords/app/system/page?p5_value=61&clear=RP&session=12518184703789
But now I want to do the same with APEX$ROW_SELECTOR. With this code I have been able to add an action to the grid and get the value of the field but I do not know how to send it to the other page and assign the value to the other item
var view = apex.region("ig-emp").widget().interactiveGrid("getViews", "grid"),
menu$ = view.rowActionMenu$;
menu$.menu("option").items.push({
type:"action",
label:"Get Emp No",
icon: "fa fa-close",
action: function(menu, element) {
var record = view.getContextRecord( element )[0];
var val1 = view.model.getValue(record, "EMPNO");
}
});
Por favor su ayuda, gracias
Use the below approach to achieve this:
Let me start by adding some more lines to your code.
var view = apex.region("ig-emp").widget().interactiveGrid("getViews", "grid"),
menu$ = view.rowActionMenu$;
menu$.menu("option").items.push({
type:"action",
label:"Get Emp No",
icon: "fa fa-close",
action: function(menu, element) {
var record = view.getContextRecord( element )[0];
var val1 = view.model.getValue(record, "EMPNO");
apex.page.submit({
request:"NAVIGATE",
set:{"P1_EMPNO":val1},
showWait: true
});
}
});
Note: in the above code replace P1_EMPNO with your page item name.'
Create a Branch -> Type: Page or URL(Redirect).
Select the page number to redirect and set the value of the current page item to the new page item. Refer below screen shot for example.
In the Server-side condition, select the Type as Request = Value and provide the value as NAVIGATE. Refer below screen shot.
I have an angular page that displays a list of items. It iterates over the list and displays it in a div. Here's the HTML code for that:
<div ng-repeat="item in items">
<div class="item-title-section">
<h1>{{item.text}}</h1>
</div>
<div class="item-special-section"
ng-show="item.type == 'FooB' ||
item.type == 'FooC' ||
item.type == 'FooD'">
<div>
<h2>Speical</h2>
<p>Type Section</p>
</div>
<div>
<span>{{item.text}}</span>
</div>
</div>
</div>
The item-title-section always shows. But I only want the item-special-section to show if the current item is of type B, C, or D. The problem here is if the list contains all 3 items I just want the div to be printed once but the text of each item printed. So in this case:
{
{
type: FooA,
title: FooA,
text: "Some text for this element"
},
{
type: FooB,
title: FooB,
text: "Some text for this element"
},
{
type: FooC,
title: FooC,
text: "Some text for this element"
}
}
The item-special-section div prints twice. Is there a way in angular to statically create an html element, meaning if it's created create it only once?
So one workaround I have figured out for your problem is to allocate the logic for showing only one special item to a separate function attached to the $scope. I have created a Plnkr Example to help demonstrate my explanation.
HTML
<div class="item-special-section"
ng-show="showSpecialSection(item.type)">
<p>I'm a special case!</p>
<p>{{item.text}}</p>
</div>
In the HTML we only allow that element to show if showSpecialSection returns true and we pass in the item.type.
JavaScript
// Define out specialItems
$scope.specialItems = ['FooB', 'FooC', 'FooE'];
// Create an array to stash the first item that fulfills
// the requirement in showSpecialSection
$scope.allowedItem = [];
$scope.showSpecialSection = function(item) {
// First we check if the item is in our defined list
// of special items
if ($scope.specialItems.indexOf(item) != -1) {
// Next depending on if allowedItem has anything,
// we either add it to allowedItem or check if it is
// already inside allowedItem
if ($scope.allowedItem.length == 0) {
$scope.allowedItem.push(item);
return true;
}
else if ($scope.allowedItem.indexOf(item) != -1) {
return true;
}
}
// return false if all other logic checks failed
return false;
}
Please let me know if this works out for you, and comment if you have questions. Cheers ~
I have selected tag input and I can choose multiple items using MagicSuggest plugin.
The problem is that the value that I get after the choice is a string separated without a comma.
Like:
MVCPHPASP.Net
I want to change it to:
MVC,PHP,ASP.Net
The result that I get when I choose multiple items :
The string that I get when I alert :
So how can I do that?
The right way is to get the data using the plugin's API, not weird parsing.
According the docs you can use the function .getSelection() to get the selected items.
var ms = $('#ms-getValue').magicSuggest({
data: [
{
id: 1,
name: 'Paris'
},
{
id: 2,
name: 'New York'
},
{
id: 3,
name: 'Gotham'
}
]
});
function getValues() {
// array
var selected = ms.getSelection();
alert(selected.map(function(item) {
return item.name;
}).join(','));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="http://nicolasbize.com/magicsuggest/lib/magicsuggest/magicsuggest.css" rel="stylesheet" />
<script src="http://nicolasbize.com/magicsuggest/lib/magicsuggest/magicsuggest.js"></script>
<div id="ms-getValue"></div>
<button onclick="getValues()">Get Values</button>
Update The result is an Array. So, to get the first (for example) selected object you do: selected[0].name
Update 2
To show all the selected values separated by comma:
selected.map(function(item) {
return item.name;
}).join(',')
I'm creating a tag suggestions function, depending of a category. So, I have a select box with a bunch of categories, when I select a category, I want to display the sub-categories (using an array obviously) in a list. Here's what I have now:
<select id="categorySelect">
<option value="6">Animal</option> //the value here is the category id
<option value="12">Music</option>
</select>
<ul id="suggestedTags">
</ul>
my JSON array:
var tagsMakers= [
{ category: 'Animal', suggestedTags: [
{ name: 'cat'},
{ name: 'dog' },
{ name: 'rabbit'}
]},
{ category: 'Music', suggestedTags: [
{ name: 'rock' },
{ name: 'rap' }
]}
];
$("#categorySelect").change(function(){
});
I'm still learning array manipulations, and I don't know where to start!
In words the logic is:
When I select a category, I want to display every suggested tags for that category in the li below. I also want to be able to chose multiple categories, so if I select both categories, I want the suggested tags for both to show.
Anyone have a little time to help?
Yeah, first bind an event to the select tag, and based on the value, display the list. Also remove the JSON structure, and build a hash instead:
tagMakers = {'Animal': ['Cat','Dog','Rabbit'], 'Music': ['rock','rap']}
$("#categorySelect").change(function() {
$("#suggestedTags").empty();
$(this).find(":selected").each(function() {
var selected = $(this).text();
$.each(tagMakers[selected].function(i,n) {
$("#suggestedTags").append("<li>"+n+"</li>");
});
});
});
Your array of tags doesn't have the category id, so I'll use the category name here. But, as a good practice, better if you put the category id in the categories array. Better yet if you use a object hash instead of an array.
function getCategoryByName(name){
//search in array.
for(var i = 0, len = tagsMakers.length; i < len; i++)
{
if (tagsMakers[i].category === name)
{
// found.
return tagsMakers[i];
}
}
// do not exists
return;
}
$("#categorySelect").change(function(){
// get the selected value
var current = $(this).val(),
suggestedTags = $("#suggestedTags"),
category;
// we do not have the category id on 'tagsMakers', so
// we need the category name.
current = $("option[value="+current+"]", this).text();
//search in array.
category = getCategoryByName(current);
//populate the suggested tags
suggestedTags.empty()
$.each(category.suggestedTags, function(i, tag) {
$("<li>" + tag.name + "</li>").appendTo(suggestedTags);
});
});
jsFiddle: http://jsfiddle.net/vcZnu/
EDIT: If you can change your categories array by an object hash (better), so you can use the solution provided by #CupidVogel, otherwise use this, which resolve your problem as asked in your question.
I'm using the code below to insert content into a page. I need to insert some variables in the text to generate some dynamic values and am unsure how to do this. Can someone tell me what I'd need to change?
Here's a slimmed down example of how I'm storing the data in my JS:
var fruit = {
'apples': {
'goldenDelicious' : {
color: 'yellow',
sale: 'A sale of $XXXXX (need to insert a number in here). Be sure to buy some before they are all gone!',
link: {
linkText: ('This company sells this for $XXXXX (eed to insert a price here). Click here to visit their site.'),
url: 'I NEED TO INSERT THE URL HERE'
}
}
}
}
Here's an example of how I'm calling it: (it's more dynamic than this, but you get the idea)
var fruitType = 'apples';
var fruitVariety = 'goldenDelicious';
fruit[fruitType][fruitVariety], function () {
// do something
});
So what I'd like is to be able to insert values like a price, sale, and URL into the object.
There are a bunch of ways to do this. If you're going to be doing a lot of this type of replacement, you'll probably want to look at a templating engine. I've been using Trimpath, and am happy with it.
If you don't want to get that fancy yet, put your own placeholder tokens in the string and then replace them.
var fruit = {
'apples': {
'goldenDelicious' : {
color: 'yellow',
sale: 'A sale of PLACEHOLDER_1. Be sure to buy some before they are all gone!',
link: {
linkText: ('This company sells this for PLACEHOLDER_2. Click here to visit their site.'),
url: 'I NEED TO INSERT THE URL HERE'
}
}
}
}
fruit.apples.goldenDelicious.sale = fruit.apples.goldenDelicious.sale.replace("PLACEHOLDER_1", "the real value");