Beginner stuck on jQuery/JS and would love some assistance - javascript

I'm trying to build a quiz app using JavaScript, jQuery, html, and CSS. I'm trying to get the questions and answer choices to load and am having trouble.
Can anyone help me with editing the "generateQuestion" function in my JS file: https://github.com/em-ilylewis/Quiz-App/blob/master/store.js.
Here is the html as well: https://github.com/em-ilylewis/Quiz-App/blob/master/question-page.html.

Going line by line in the comments above the generateQuestion function should help break it down:
1. get the object from the store at the questionNumber index
Since STORE is an array, you can access individual items in that array like so:
// This will get you the FIRST item in your STORE array.
STORE[0]
And since we already know that the questionNumber variable is set to 0 (on line 77) you can do this:
// This will get you the FIRST item in your STORE array.
STORE[questionNumber]
2. use jQuery to select the element with the class questionBox
// This is correctly targeting the questionBox element
$(".questionBox")
3. use the html function on the jQuery element from the previous step to fill that element with the question string from the object you got out of the store
- Now you can use object-dot notation to access an object's values using its key property, like so:
// This will get you the first item's "question" in your STORE's array (assuming it is still 0).
$(".questionBox").html(STORE[questionNumber].question);
Unfortunately, this only solves your problem for getting the first item in your STORE array. So you'll likely want to pass in the index of the STORE array by using arguments from your generateQuestion function, like so:
// "index" is an argument of generateQuestion.
function generateQuestion(index) {
$(".questionBox").html(STORE[index].question);
$(".answerChoiceBox").html(STORE[index].choices);
}
generateQuestion(0); // Passing in 0 as a parameter of generateQuestion will get you the FIRST question in your array.
generateQuestion(1); // ...SECOND question
generateQuestion(2); // ...THIRD question

Related

Return object bound to a dynamic element when label for object is also dynamic

I am using CKEditor. Within my page, the user can dynamically add/remove the element containing the WYSIWYG ckeditor text editor.
CKEDITOR.instances returns an object which contains within it all the ck_editor objects on my page.
When the user clicks the add button, then the following code successfully grabs that element:
CKEDITOR.instances[“my_textarea_0_body"]
The issue is when the user clicks delete to remove that element, and then reclicks add. I now want to grab that new ckeditor element on the page. However, now I need to grab it with this:
CKEDITOR.instances[“my_textarea_1_body"]
Notice that the number changed. So, the user is able to toggle the add/remove of this element any number of times. Example: if they did it 100 times I would need to have a way to grab that object like so:
CKEDITOR.instances[“my_textarea_100_body"]
The problem is that I never know what that number will be. That number is vital for me to create the string in order to grab the appropriate object.
Question: How can I grab this dynamically labeled object that is contained within the CKEDITOR.instances object? I know that my desired object will always be the LAST object appended within that CKEDITOR.instances object.
I assume that CKEDITOR.instancess a kind of a map (dictionary), so you can get all key names by Object.keys(). And then select the last/first/ or n-th instance name.
var mapping_length = Object.keys(CKEDITOR.instances).length;
var object_label = Object.keys(CKEDITOR.instances)[mapping_length - 1];
CKEDITOR.instances[object_label];
This will return the desired object from within that dictionary object.
Regex indeed is your friend here. /^CKEDITOR\.instances\["my_textarea_\d+_body"\]$/.test(str) should get the job done. (if you copy and paste any of your initial examples to test, it will fail however since you've got an angled quote illegal character in there)
console.log(/^CKEDITOR\.instances\["my_textarea_\d+_body"\]$/.test('CKEDITOR.instances["my_textarea_0_body"]'))
I think I understand what you're getting at though - you know the vague structure of the key, but not exactly what it will be when you're trying to retrieve it. In that case, you'd want to search through the keys of the CKEDITOR.instances object for any that match that pattern. So, let matchingKeys = Object.keys(CKEDITOR.instances).filter(key => /^my_textarea_\d+_body$/.test(key)). That will return a set of all keys that match that pattern.
You can create a helper function which checks for a regex match. The regex for that field should be:
my_textarea_\d+_body
Then you can modify/add the new object key to instances

How To Get javascript Array in Code behind

This is javascript array
var data =['athar','naveed','123','abx'];
Now I want to access this array in code behind array or list variable. Don't want to use Hidden field.
If you want to use in anyother javascript function,you can simply use data[0] to access first element i.e.,athar.
data.length will give you the count of values present in the array.

javascript removing item from an array, splice

I'm making a small appwith localstaorage (not implemented yet): you type a note int the text area and it is display in a list
the note are stacked in an object called notes (for localstorage in the future);
But my problem is : I can add a note, but when I try to remove on of them, I have to remove my li and the related note object in the 'notes' array, so i decided to use splice method, but it works in a strange way...
when i click 'close', it works fine one or two times but at a moment the array stays with one or two object in it...
I tried different ways to solve the problem but without success...
Here is the fiddle : http://jsfiddle.net/h8hg6/1/
thanks for your help
I have made some modifications to your fiddle that I think solve the problem. Essentially you were using .splice incorrectly, and your Array was falling out of sync with your note elements. I've replaced your array with an numeric-based object because it is much easier to deal with. Here are some of the relevant changes:
http://jsfiddle.net/h8hg6/2/
var notes = {}; // notes is now an object instead of an array
// snip
var number = jQuery(this).parents('li').data('number');
delete notes[number]; // this is how you remove properties from an object
// snip
var note = {
color: color,
text: text
};
notes[i] = note; // add this object as a property of the notes object
i++;
The problem is that your call to splice uses the value of the queue variable to determine the index of the element that will be removed in the notes array. Right here:
notes.splice(queue, 1);
Since the queue value is always increasing (right here):
function addNoteToPage(){
i++;
...
jQuery('ul#notes li:first').before('<li data-queue="'+ i +'">'+ note.text +' <a href=""#>CLOSE</a>
You hit a moment where you call splice on an non-existing index of the notes array and nothing is removed as a result. Basically, you end up with an out-of-sync notes array.
You need to make sure that the value of the data-queue attribute coincides with the real index of the element in the notes array so that your call to splice(queue,1) always succeeds and removes the appropriate array element.
With that said, if above answer works for you, I'd go with that one. I just wanted to give you more insight on what was going on...

KnockoutJS: Update/Insert data to a viewModel using mapping

I've been trying to figure this out for quite some time now. I couldn't find anything that addresses this problem, but please correct me if I'm wrong.
The problem:
I have data from a JSON API comming in, with an nested array/object structure. I use mapping to initially fill the model with my data. To update this, I want to extend the model if new data arrives, or update the existing data.
As far as I found out, the mapping option key, should do this trick for me, but I might have misunderstood the functionality of the mapping options.
I've boiled down the problem to be represented by this example:
var userMapping = {
key: function(item) {
return ko.utils.unwrapObservable(item.id);
}
};
// JSON call replaced with values
var viewModel = {
users: ko.mapping.fromJS([], userMapping)
};
// Should insert new - new ID?
ko.mapping.fromJS([{"id":1,"name":"Foo"}, {"id":2,"name":"Bar"}], userMapping, viewModel.users);
// Should only update ID#1 - same ID?
ko.mapping.fromJS([{"id":1,"name":"Bat"}], userMapping, viewModel.users);
// Should insert new - New ID?
ko.mapping.fromJS([{"id":3,"name":"New"}, {"id":4,"name":"New"}], userMapping, viewModel.users);
ko.applyBindings(viewModel);​
Fiddle: http://jsfiddle.net/mikaelbr/gDjA7/
As you can see, the first line inserts the data. All good. But when I try to update, it replaces the content. The same for the third mapping; it replaces the content, instead of extening it.
Am I using it wrong? Should I try to extend the content "manually" before using mapping?
Edit Solution:
I solved this case by having a second helper array storing all current models. On new data i extended this array, and updated the view model to contain the accumulated items.
On update (In my case a WebSocket message), I looped through the models, changed the contents of the item in question, and used method valueHasMutated() to give notice of changed value to the Knockout lib.
From looking at your example code the mapping plugin is behaving exactly as I would expect it to. When you call fromJS on a collection you are effectively telling the mapping plugin this is the new contents of that collection. For example:
On the second line, How could it know whether you were updating or whether you had simply removed id:2?
I can't find any mention of a suitable method that treats the data as simply an update, although you could add one. Mapped arrays come with some helpful methods such as mappedIndexOf to help you find particular items. If you receive an update data set simply loop through it, find the item and update it with a mapping.fromJS call to that particular item. This can easily be generalized into reusable method.
You can use ko.mapping.updateFromJS() to update existing values. However, it does not add new values so that would be a problem in your instance. Take a look at the link below for more details.
Using updateFromJS is replacing values when it should be adding them
Yes, you should first collect all data into a list or array and then apply the mapping to that list. Otherwise you are going to overwrite the values in your viewModel.

How can I call an element from an array created by "document.getElementBytag()"?

I am trying to make a page work for my website using the mootools framework. I have looked everywhere I can think of for answers as to why this isn't working, but have come up empty.
I want to populate several arrays with different data types from the html, and then, by calling elements from each array by index number, dynamically link and control those elements within functions. I was testing the simple snippet of code below in mootools jsfiddle utility. Trying to call an element from array "region" directly returns "undefined" and trying to return the index number of an element returns the null value of "-1".
I cannot get useful data out of this array. I can think of three possible reasons why, but cannot figure out how to identify what is really happening here:
1. Perhaps this array is not being populated with any data at all.
2. Perhaps it is being populated, but I am misunderstanding what sort of data is gotten by "document.getElementBytag()" and therefore, the data cannot be displayed with the "document.writeln()" statement. (Or am I forced to slavishly create all my arrays?)
3. Perhaps the problem is that an array created in this way is not indexed. (Or is there something I could do to index this array?)
html:
<div>Florida Virginia</div>
<div>California Nevada</div>
<div>Ohio Indiana</div>
<div>New York Massachussetts</div>
<div>Oregon Washington</div>
js:
var region = $$('div');
document.writeln(region[2]);
document.writeln(region.indexOf('Ohio Indiana'));
Thanks for helping a js newbie figure out what is going on in the guts of this array.
$$ will return a list of DOM elements. If you are only interested in the text of those DOM nodes, then extract that bit out first. As #Dimitar pointed out in the comments, calling get on an object of Elements will return an array possibly by iterating over each element in the collection and getting the property in question.
var region = $$('div').get('text');
console.log(region[2]); // Ohio Indiana
console.log(region.indexOf('Ohio Indiana')); // 2
Also use, console.log instead of document.writeln or document.write, reason being that calling this function will clear the entire document and replace it with whatever string was passed in.
See an example.

Categories