Dynamic dropdown list using JavaScript object - javascript

I want to make a dynamic drop-down list based on a JavaScript object like this:
var EXERCISE_OBJ = {
"title" : {
"name" : "Exercise_Name",
"category" : "Pronunciation",
"type":"Multiple Choice",
},
"title2" : {
"name" : "Exercise_Name2",
"category" : "Spelling",
"type":"Crossword",
},
"title3" : {
"name" : "Exercise_Name3",
"category" : "Spelling",
"type":"Multiple Choice",
},
"title4" : {
"name" : "Exercise_Name4",
"category" : "Grammar",
"type":"Wordsearch",
},
}
I want a drop-down list enlisting all the categories and another one displaying all the exercise titles from each category.. How can I output it?

Please try this:
Create div with id test. <div id="test"></div>
var exercise_select = "<select name='exc'>";
var category_select = "<select name='cate'>";
$.each(EXERCISE_OBJ, function() {
var name = this.name;
var category = this.category;
exercise_select += "<option value='"+name+"'>"+name+"</option>";
category_select += "<option value='"+category+"'>"+category+"</option>";
});
exercise_select += "</select>"; category_select += "</select>";
$("#test").append(exercise_select); $("#test").append(category_select);

Related

Javascript - How to get star rating from object array field rating?

I have this object array:
var test_data = [
{
"id" : "Test01", //Has to be a string form ID
"test_info" : "This is the test information",
"test_rating" : 5
},
{
"id" : "Test02", //Has to be a string form ID
"test_info" : "This is the test information",
"test_rating" : 2
}
As it stands I am using the following to populate a unordered list (but it is only populating the id)
fieldOutputId.forEach(function(id) {
$("#idList").append('<li>' + id +" "+ "</li>");
});
I am wondering how to get Stars appearing to the right with the value of test_rating that's stored in fieldOutputRating like showing up like this picture (Stars being the red text)
Fig1 :
-----EDIT-----
Thanks to #ChrisG this gets it inline, id & test_rating:
test_data.forEach(function(item) { $("#idList").append('<li>' + item.id+ '<div class="fa fa-star">'+ item.test_rating+ "</div></li>"); })
With the above code I am trying to get the stars to appear in-line (done) and as stars using font-awesome library with a class="fa fa-star
This is what the above is giving:
So its getting the test_rating but not giving any stars for it.
Any help is appreciated??
Something like this?
const test_data = [
{
"id" : "Test01",
"test_info" : "This is the test information",
"test_rating" : 5
},
{
"id" : "Test02",
"test_info" : "This is the test information",
"test_rating" : 2
}
];
test_data.forEach(({id, test_rating}) => {
$("#idList").append(`<li>${id} ${'*'.repeat(test_rating)}</li>`);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="idList" />
You need to build up the 'star rating' from the input, like below:
test_data.forEach(function(data) {
let rating_str = '';
for (let i = 0; i < data.rating; i++) rating_str += '*';
$("#idList").append('<li>' + data.id +" "+ "<span>" + rating_str + "</span></li>");
});
If your 'star' is some image, instead of just '*' like in my code example, you can do rating_str += '<img src="..." />'

Using php array in javascript to populate a 'select' ajax

I have a multidimensional array of stores and states, which makes a json as follows:
<?php
$list[$store][$state] = $city;
echo json_encode ($list);
{"store 1": {"state x": "city 1", "state y": "city 2"}, "store 2": {"state z": "city 3"}}
?>
I need to create a select that changes the second select according to what was chosen, using the data of the array in question.
Something like this http://www.daviferreira.com/blog/exemplos/cidades/index.php
How can I handle this data in php for javascript?
And how can I separate them to use them in each select?
I've already tried:
var list = JSON.parse ("<? php echo json_encode($list)?>");
But it did not work :(
EDIT The structure of the selects should look like this.
{"store 1": {"state x": "city 1", "state y": "city 2"}, "store 2": {"state z": "city 3"}}
First select
Store 1
Store 2
if store 1 selected
Second select
State x
State y
if store 2 selected
Second select
State z
Something like that
You can simply do this using jQuery:
$(document).ready(function(){
var list = <?= json_encode($list); ?>;
var storeSelect = $("<select></select>");
storeSelect.attr('id', 'storeSelect');
for(var item in list)
{
storeSelect.append('<option value="' + item + '">' + item + '</option>');
}
$('#theForm').append(storeSelect);
var storeStates = $("<select></select>");
storeStates.attr('id', 'storeState');
$('#theForm').append(storeStates);
$('#storeSelect').change(function ()
{
var storeName = $(this).val();
for(var item in list[storeName])
{
storeStates.html('<option value="' + item + '">' + item + '</option>');
}
});
$('#storeSelect').change();
});
It simply uses loops to create the select menu. And uses the onChange event to manipulate the values.
Here's how to do it using jQuery. If you're using plain JS, converting it is an exercise for the reader.
var list = <?php echo json_encode($list); ?>;
$.each(list, function(store) {
$("#store_menu").append($("<option>", {
value: store,
text: store
}));
});
$("#store_menu").change(function() {
var store = $(this).val();
$("#state_menu").empty();
$.each(list[store], function(state) {
$("#state_menu").append($("<option>", {
value: state,
text: state
}));
});
});

Datatable foreach detail/child row

I want to display foreach child row datatable
lets say I have ajax data like this
"data": [
{
"date" : "1/17/2016",
"supplier" : "supplier1",
"total" : "$10",
"payment" : "Cash",
"product" : Array[2]
0: "product1"
1: "product2"
"price" : Array[2]
0: "$5"
1: "$5"
},
{
"date" : "2/1/2016",
"supplier" : "supplier2",
"total" : "$3",
"payment" : "Cash",
"product" : Array[1]
0: "product1"
"price" : Array[1]
0: "$3"
},
{
"date" : "1/17/2016",
"supplier" : "supplier3",
"total" : "$15",
"payment" : "Cash",
"product" : Array[3]
0: "product1"
1: "product2"
2: "product3"
"price" : Array[2]
0: "$3"
1: "$5"
2: "$7"
},
I wanna create datatable child row for product & price array following link here
I only edit script in function format to meet my need like this
function format ( d ) {
// `d` is the original data object for the row
return '<table class="table table-border table-hover">'+
'<tr>'+
'<td>Product</td>'+
'<td>Price</td>'+
'</tr>' +
'<?php
$loop = 5;
echo $loop; <-- here
for ($i=0; $i<$loop; $i++) {
echo "<tr><td>'+d.product['$i']+'</td> <td>'+d.price['$i']+'</tr>";
} ?>' +
'</table>';
}
it's run quite well...I can display data like i want..but i must define $loop manual...
I tried using $loop = "'+d.product.length+'"
when i echo that var in php it's display real value
(say i have 3 array in product it's display 3 too)
but somehow when it's enter for section it's like $loop become 0
because not display anyrow (if i set condition to $i<=$loop it's dispaly one row detail in every row parents)
i found something weird too
$loop = "'+d.product_.length+'" . "'+d.product_.length+'";
echo $loop ==> 33 (say if product array count is 3)
but if I change it to sum it's result 0
$loop = "'+d.product_.length+'" + "'+d.product_.length+'";
echo $loop ==> 0 (say if product array count is 3 too)
how to solve it, so i can know how many looping should my script do
You don't really need php here to append your extra table with a loop, rather you can use jquery's $.each.. You just need to construct your table body structure prior to append as below:
/* Formatting function for row details - modify as you need */
function format ( d ) {
console.log(d.product);
var trs=''; //just a variable to construct
$.each($(d.product),function(key,value){
trs+='<tr><td>'+value+'</td><td>'+d.price[key]+'</td></tr>';
//loop through each product and append it to trs and am hoping that number of price
//values in array will be equal to number of products
})
// `d` is the original data object for the row
return '<table class="table table-border table-hover">'+
'<thead>'+
'<th>Product</th>'+
'<th>Price</th>'+
'</thead><tbody>'
+ trs +
'</tbody></table>';
}
$(document).ready(function() {
var table = $('#example').DataTable({
"ajax": 'https://raw.githubusercontent.com/kshkrao3/JsonFileSample/master/Employees.json',
"columns": [
{
"class": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{ "data": "date"},
{ "data": "supplier"},
{ "data": "total"},
{ "data": "payment"}
]
});
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row( tr );
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
});
});
Note : There was an error in your click event.. You were trying dTable.row in the event where as it has to be table.row since you are holding reference in table variable.
DEMO

Append only working for first child - looping issue?

I have a for loop that appends an ordered list with a list item and a load of other info.
It works great for the first list item, however, the others do not populate/append.
I'm having trouble finding which part of my code is causing the issue:
<script>
$(document).ready(function(){
var artistID =$(".artist").attr('id');
$.get("songs.php?id="+artistID, function(data){
for (var j=0; j < data.length; j++){
$(".songs."+data[j].ArtistNumber).append(
'<li class="song">'+
'<a class="song-link" onclick="songClick();return false;" href="'+data[j].FileLocation+'">'+
'<p>'+data[j].Title+'</p>'+
'<small>'+data[j].duration+'</small>'+
'</a>'+
'</li>'
);
}
},'json');
});
</script>
Any help would be appreciated.
Edit:
It turns out all I needed was a $(".artist").each(function(){}) wrapped around that.
I hope this can be of help to someone.
After many comments, I finally get your point. Here is how to proceed : you want a nested 'each' loop.
Since you did not provide any data structure, I will assume it looks like this :
data = {
"123" : [
{
"title" : "song 1",
"fileLocation" : "someURL",
"duration" : "2m45s"
},
{
"title" : "song 2",
"fileLocation" : "someOtherURL",
"duration" : "4m10s"
}
],
"456" : [
{
"title" : "song 1",
"fileLocation" : "someNewURL",
"duration" : "3m20s"
},
{
"title" : "song 2",
"fileLocation" : "someOtherNewURL",
"duration" : "4m17s"
}
]
}
I assume your data is an object containing key/values, each key is the artist number and each value is a list (array) of songs of this artist (represented as object with details).
and here's how to exploit the data :
$.each(data, function(artistNumber, songs){ // Iterating through each artist/songs pair. songs is an array
$list = $(".songs." + artistNumber); // Select each list one by one in the dom
$.each(songs, function(index, song){ // song is an object
$list.append(
'<li class="song">'+
'<a class="song-link" onclick="songClick();return false;" href="'+song.fileLocation+'">'+
'<p>'+song.title+'</p>'+
'<small>'+song.duration+'</small>'+
'</a>'+
'</li>'
);
});
});
See this fiddle in action.
I'm not shure about your DOM, I would need your HTML, but here is a try :
<script>
$(document).ready(function(){
var artistID =$(".artist").attr('id');
$.get("songs.php?id="+artistID, function(data){
for (var j=0; j < data.length; j++){
$(".artist").append($("<ul />").addClass(data[j].ArtistNumber).addClass('songs'));
$(".songs."+data[j].ArtistNumber).html(
'<li class="song">'+
'<a class="song-link" onclick="songClick();return false;" href="'+data[j].FileLocation+'">'+
'<p>'+data[j].Title+'</p>'+
'<small>'+data[j].duration+'</small>'+
'</a>'+
'</li>'
);
}
},'json');
});
And this still will not ,because you make selector for class,and this get first item with class artist,you need to change selector.Try thiseach

Pulling parts of JSON out to display them in a list

I have the following JSON:
var questions = {
section: {
"1": question: {
"1": {
"id" : "1a",
"title": "This is question1a"
},
"2": {
"id" : "1b",
"title": "This is question2a"
}
},
"2": question: {
"1": {
"id" : "2a",
"title": "This is question1a"
},
"2": {
"id" : "2b",
"title": "This is question2a"
}
}
}
};
NOTE: JSON changed based on the answers below to support the question better as the original JSON was badly formatted and how it works with the for loop below.
The full JSON will have 8 sections and each section will contain 15 questions.
The idea is that the JS code will read what section to pull out and then one by one pull out the questions from the list. On first load it will pull out the first question and then when the user clicks on of the buttons either option A or B it will then load in the next question until all questions have been pulled and then do a callback.
When the button in the appended list item is clicked it will then add it to the list below called responses with the answer the user gave as a span tag.
This is what I have so far:
function loadQuestion( $section ) {
$.getJSON('questions.json', function (data) {
for (var i = 0; i < data.length; i++) {
var item = data[i];
if (item === $section) {
$('#questions').append('<li id="' + item.section.questions.question.id + '">' + item.section.questions.question.title + ' <button class="btn" data-response="a">A</button><button class="btn" data-response="b">B</button></li>');
}
}
});
}
function addResponse( $id, $title, $response ) {
$('#responses').append('<li id="'+$id+'">'+$title+' <span>'+$response+'</span></li>');
}
$(document).ready(function() {
// should load the first question from the passed section
loadQuestion( $('.section').data('section') );
// add the response to the list and then load in the next question
$('button.btn').live('click', function() {
$id = $(this).parents('li').attr('id');
$title = $(this).parents('li').html();
$response = $(this).data('response');
addResponse( $id, $title, $response );
loadQuestion ( $('.section').data('section') );
});
});
and the HTML for the page (each page is separate HTML page):
<div class="section" data-section="1">
<ul id="questions"></ul>
<ul id="responses"></ul>
</div>
I've become stuck and confused by how to get only the first question from a section and then load in each question consecutively for that section until all have been called and then do a callback to show the section has been completed.
Thanks
Do not have multiple id's in html called "section."
Do not have multiple keys in your JSON on the same level called "section". Keys in JSON on the same level should be unique just as if you are thinking about a key-value hash system. Then you'll actually be able to find the keys. Duplicate JSON keys on the same level is not valid.
One solution can be section1, section2, etc. instead of just section. Don't rely on data-section attribute in your HTML - it's still not good if you have "section" as the duplicate html id's and as duplicate JSON keys.
If you have only one section id in HTML DOM, then in your JSON you must also have just one thing called "section" e.g.:
var whatever = {
"section" : {
"1": {
"question" : {
"1" : {
"id" : "1a",
"title" : "question1a"
},
"2" : {
"id" : "2a",
"title" : "question2a"
}
}
},
"2": {
"question" : {
"1" : {
"id" : "1a",
"title" : "aquestion1a"
},
"2" : {
"id" : "2a",
"title" : "aquestion2a"
}
}
}
}
}
console.log(whatever.section[1].question[1].title); //"question1a"
To get question, do something like this:
function loadQuestions(mySectionNum) {
$.getJSON('whatever.json', function(data){
var layeriwant = data.section[mySectionNum].question;
$.each(layeriwant, function(question, qMeta) {
var desired = '<div id="question-' +
qMeta.id +
'"' +
'>' +
'</div>';
$("#section").append(desired);
var quest = $("#question-" + qMeta.id);
quest.append('<div class="title">' + qMeta.title + '</div>');
//and so on for question content, answer choices, etc.
});
});
}
then something like this to actually get the questions:
function newQuestion(){
var myHTMLSecNum = $("#section").attr('data-section');
loadQuestions(myHTMLSecNum);
}
newQuestion();
//below is an example, to remove and then append new question:
$('#whatevernextbutton').on('click',function(){
var tmp = parseInt($("#section").attr('data-section'));
tmp++;
$("#section").attr('data-section', tmp);
$("#section").find('*').remove();
newQuestion();
});
Technically your getJSON function always retrieves the same data. Your code never compares the id given to the id you're extracting.
Your getJSON should look something like:
function loadQuestion( $section ) {
for (var i = 0; i < questions.section.length; i++) {
var item = questions.section[i];
if (item.id === $section) {
for (var j = 0; j < item.questions.length; j++) {
$('#questions').append('<li id="' +
item.questions[i].id + '">' +
item.questions[i].title +
' <button class="btn" data-response="a">A</button><button class="btn" data-response="b">B</button></li>'
);
}
}
}
}
Modify your JSON to:
var questions = {
section: [{
id: 1,
questions: [{
id: "1a",
title: "This is question1a"
},{
id: "2a",
title: "This is question2a"
}]},{
id: 2,
questions: [{
id: "1a",
title: "This is question1a"
},{
id: "2a"
title: "This is question2a"
}]
}]
};
Edit: your first parameter of getJSON is the URL of the JSON returning service.
You don't need getJSON at all if your JSON is already defined on the client. I have modified the code above.

Categories