How do I get object data from my json in my select? - javascript

So I have a select element and I am appending the data I am getting back from my API.
function getHeadData() {
$("#itemSelect").empty();
if (headitemData.length < 1) {
$.getJSON("http://localhost:9000/api/helmets", function (key, value) {
console.log("request helmets");
var item = "";
headitemData = key;
var len = key.length;
for (let i = 0; i < len; i++) {
item += '<option value="' + key + '">' + key[i].Name + '</option>';
}
$('#itemSelect').append(item);
});
}
else {
clearIndex(headitemData);
}
}
That right there returns this
Which is just what I want.
But if I want to get other data like.. the Icon
Let's say I want to log to the console when I select a item from the Select element, how would I do that?
The end goal is to print out the Icon property of the json object when I change item in the Select.
JsonData example
<ItemModel>
<ACrush>+0</ACrush>
<AMagic>-5</AMagic>
<ARange>-2</ARange>
<ASlash>+0</ASlash>
<AStab>+0</AStab>
<DCrush>+43</DCrush>
<DMagic>-3</DMagic>
<DRange>+48</DRange>
<DSlash>+49</DSlash>
<DStab>+47</DStab>
<Icon>
https://vignette.wikia.nocookie.net/2007scape/images/a/a0/3rd_age_full_helmet.png/revision/latest?cb=20141217224936
</Icon>
<MagicDamage>+0%</MagicDamage>
<MeleeStrength>+0</MeleeStrength>
<Name>3rd age full helmet</Name>
<Prayer>+0</Prayer>
<RangedStrength>+0</RangedStrength>
<Slayer>0</Slayer>
<Undead>0</Undead>
</ItemModel>

You can set a data for your option like:
'<option data-icon="'+ key[i].Icon +'"></option>'
And then you can bind a change for your select after create your list:
$('select').on('change', function () {
const _this = $(this).find(':selected');
const icon = _this.attr('data-icon');
console.log(icon);
})

Since you want to use the data in other areas of your code, use a closure to create an environment where your variables don't leak out into the global space. For example, with the callback:
(function () {
var myData;
function test(callback) {
$.getJSON("http://localhost:9000/api/helmets",function (data) {
callback(data);
});
}
test(function (data) {
myData = data;
});
function getHeadData() {
$("#itemSelect").empty();
if (headitemData.length < 1){
console.log("request helmets");
var item = "";
headitemData = myData;
var len = myData.length;
for (let i = 0; i < len; i++) {
item += '<option value="' +myData+ '">' + myData[i].Name + '</option>';
}
$('#itemSelect').append(item);
}
else {
clearIndex(headitemData);
}
}
$("#itemSelect").on("change",function(){
var value = $(this).val();
var newData = myData.filter(item=>{
if(myData.Name==value){
return item;
}
});
console.log(newData.Icon);
});
myData is cached as a global variable specific to that closure. Note the other functions will only be able to use that variable once the callback has completed.

Modified version below:
function getHeadData() {
$("#itemSelect").empty();
if (headitemData.length < 1) {
$.getJSON("http://localhost:9000/api/helmets", function (key, value) {
console.log("request helmets");
var item = "";
headitemData = key;
var len = key.length;
for (let i = 0; i < len; i++) {
var icon=key[i].Icon;
item += '<option data-icon="'+icon+'" value="' + key + '">' + key[i].Name + '</option>';
}
$('#itemSelect').append(item);
});
}
else {
clearIndex(headitemData);
}
}
Simple test to get the Icon from the first option in select:
//Get first option to test output
var test=$("#itemselect option:first");
//Read data-icon
console.log(test.data('icon'));
//To update data-icon
test.data('icon','new icon');
To echo when select is changed
$("#itemselect").change(function(e) {
var optionSelected = $("option:selected", this);
console.log (optionSelected.data('icon'));
});

Related

Get value select (Javascript) and Grid in Electronjs

I don't know why the value in my div appears only one time ...
function nbProduct(sel) {
var nbProduct = sel.options[sel.selectedIndex].text
$('#tableFacture').remove();
$('#tableFacture').remove();
for(var i =0;i < nbProduct;i++){
var nFacture = i + 1
$("#product").append("<table id='tableFacture'></table>")
$("#tableFacture").append("<th scope='row' id='rowProduct"+i+"'>Produit N°"+nFacture+"</th")
$("#rowProduct"+i+"").append("<div class='row' syle='margin-top: 40px;' id='"+i+"'><select onChange='typeProduct(this);'><option></option><option value='"+i+"'>Velo</option><option value='"+i+"'>Trottinette</option><option value='"+i+"'>Accessoires</option></select></div>")
}
function typeProduct(sel) {
var typeOfProduct = sel.options[sel.selectedIndex].text
var nbDiv = sel.options[sel.selectedIndex].value
if (typeOfProduct == 'Velo'){
$("#"+nbDiv+"").append("<div class='containerFacture><select id='factureVelo'><option></option></select></div>")
client.query('SELECT * FROM core_velo ORDER BY model DESC',(err,res)=>{
for(var i =0;i < res.rows.length;i++){
var item = res.rows[i];
var model = item['model']
$("#factureVelo").append("<option>"+model+"</option>")
}
client.end()
})
}
};
picture of my problem
And I have an other problem, how use grid in electronjs ? because col-md/sm/XS ... do not work.
You to try use:
function typeProduct(sel) {
var typeOfProduct = sel.options[sel.selectedIndex].text
var nbDiv = sel.options[sel.selectedIndex].value
if (typeOfProduct == 'Velo'){
$("#"+nbDiv+"").append("<div class='containerFacture col-xs-2 offset-xs-1'><select id='factureVelo'><option></option></select></div>")
client.query('SELECT * FROM core_velo ORDER BY model DESC',(err,res)=>{
var model ="";
$.each(res, function(index, value){
model += value.model;
})
$("#factureVelo").append("<option>"+model+"</option>")
}
client.end()
})
}
};

How to store drag&drop to local storage

hope you can help!
I am working on a school assignment with local storage and drag & drop, so I am very new to this. I'm making a kind of task manager, similar to Trello, with tasks, members and different lists.
The problem I am having is that the things I drag are "reset" if I refresh the page. How can I fix it so it stays where I drop it?
Here the tasks are created:
function renderTasks() {
var outputTask = JSON.parse(window.localStorage.getItem("outputTask")) || [];
var outputTaskEl = document.getElementById("outputTasks");
outputTaskEl.innerHTML = "";
for (var product of outputTask) {
var productTwo = document.createElement("div");
productTwo.setAttribute('class', 'task');
productTwo.setAttribute('draggable', true);
var {task,member,deadline} = product;
productTwo.innerHTML =
"<div id='task'>" +
"<p>" + product.task + "</p>" +
"<ul>" +
"<li><img id='pencil-img' src='images/pencil.png' alt='task-options. Pencil'>"+
"<ul class='dropdown-menu'>" +
"<li><a href='#' onclick='deleteTask(" + product.id + ")'>Delete task</a></li>" +
"<li><a href='#' onclick='editTask(" + product.id + ")'>Edit task</a></li>" +
"</ul>"
"</li>" +
"</ul>";
outputTaskEl.appendChild(productTwo);
}
for ( i = 0; i < outputTask.length; i++){
var taskId = document.getElementsByClassName("task");
taskId[i].id = "task" + (i + 1);
}
}
And this is the drag and drop code:
function dragDropItems() {
const taskItems = document.querySelectorAll('.task');
const taskFields = document.querySelectorAll('.taskField');
for (let i = 0; i < taskItems.length; i++) {
const item = taskItems[i];
item.addEventListener('dragstart', function () {
draggedItem = item;
setTimeout(function () {
}, 0)
});
item.addEventListener('dragend', function () {
setTimeout(function () {}, 0);
})
for (let j = 0; j < taskFields.length; j ++) {
const list = taskFields[j];
draggedItem = item;
list.addEventListener('dragover', function (e) {
e.preventDefault();
});
list.addEventListener('dragenter', function (e) {
e.preventDefault();
});
list.addEventListener('drop', function (e) {
e.preventDefault();
this.append(draggedItem);
});
}
}
}
Try this:
// Save object
localStorage.setItem('key', JSON.stringify(obj))
// Get object
let obj = JSON.parse(localStorage.getItem('key'))

Splitting out xml result into dropdownlist

Hope someone can help - I'm new to js/jQuery so I'm hoping it's something really simple I'm missing here.
I'm trying to populate a dropdownlist with the xml result from below. The parseXML function works great and the result.push(valueid + "," + value) leaves me with the following:
1,Service
2,Breakdown
How do I get this into a dropdownlist please? Using the below, I get the error "Object doesn't support property or method 'split'"
Many thanks
leddy
function testFunction() {
var jobresults = "<resultset morerecords='0'> " +
"<result> " +
"<itt_jobtypeid>1</itt_jobtypeid> " +
"<itt_name>Service</itt_name> " +
"</result> " +
"<result> " +
"<itt_jobtypeid>2</itt_jobtypeid> " +
"<itt_name>Breakdown</itt_name> " +
"</result> " +
"</resultset> ";
var xml = parseXML(jobresults);
var jobid = xml.getElementsByTagName("itt_jobtypeid");
var jobname = xml.getElementsByTagName("itt_name");
var result = [];
for (var i = 0; i < jobid.length; i++) {
var valueid = jobid[i].childNodes[0].nodeValue;
var value = jobname[i].childNodes[0].nodeValue;
// add longitude value to "result" array
result.push(valueid + "," + value);
}
var jobtype = $("#ddlJobType");
$.each(result, function () {
var arr = result.split(',');
for (var i = 0; i < arr.length; i++) {
jobtype.append($("<option />").val(arr[0]).text(arr[1]));
}
});
}
function parseXML(text) {
if (window.DOMParser) {
parser = new DOMParser();
doc = parser.parseFromString(text, "text/xml");
}
else { // Internet Explorer
doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async = "false";
doc.loadXML(text);
}
return doc;
}
It can be simpler and cleaner if you optimize data structure for result array. Push an object with value and label so that you can simply use attr method directly after:
for (var i = 0; i < jobid.length; i++) {
var valueid = jobid[i].childNodes[0].nodeValue;
var value = jobname[i].childNodes[0].nodeValue;
// add longitude value to "result" array
result.push({value: valueid, label: value});
}
var jobtype = $("#ddlJobType");
$.each(result, function (i, obj) {
$('<option>').attr(obj).appendTo(jobtype);
});
See https://api.jquery.com/jquery.each/. The callback function gets each jobtype as parameter to the function.
Try changing the code to:
$.each(result, function (idx, value) {
var arr = value.split(',');
for (var i = 0; i < arr.length; i++) {
jobtype.append($("<option />").val(arr[0]).text(arr[1]));
}
});

generate list of variables from a FOR loop

var select = [];
for (var i = 0; i < nameslots; i += 1) {
select[i] = this.value;
}
This is an extract of my code. I want to generate a list of variables (select1, select2, etc. depending on the length of nameslots in the for.
This doesn't seem to be working. How can I achieve this? If you require the full code I can post it.
EDIT: full code for this specific function.
//name and time slots
function gennametime() {
document.getElementById('slots').innerHTML = '';
var namelist = editnamebox.children, slotnameHtml = '', optionlist;
nameslots = document.getElementById('setpresentslots').value;
for (var f = 0; f < namelist.length; f += 1) {
slotnameHtml += '<option>'
+ namelist[f].children[0].value
+ '</option>';
};
var select = [];
for (var i = 0; i < nameslots; i += 1) {
var slotname = document.createElement('select'),
slottime = document.createElement('select'),
slotlist = document.createElement('li');
slotname.id = 'personname' + i;
slottime.id = 'persontime' + i;
slottime.className = 'persontime';
slotname.innerHTML = slotnameHtml;
slottime.innerHTML = '<optgroup><option value="1">00:01</option><option value="2">00:02</option><option value="3">00:03</option><option value="4">00:04</option><option value="5">00:05</option><option value="6">00:06</option><option value="7">00:07</option><option value="8">00:08</option><option value="9">00:09</option><option value="10">00:10</option><option value="15">00:15</option><option value="20">00:20</option><option value="25">00:25</option><option value="30">00:30</option><option value="35">00:35</option><option value="40">00:40</option><option value="45">00:45</option><option value="50">00:50</option><option value="55">00:55</option><option value="60">1:00</option><option value="75">1:15</option><option value="90">1:30</option><option value="105">1:45</option><option value="120">2:00</option></optgroup>';
slotlist.appendChild(slotname);
slotlist.appendChild(slottime);
document.getElementById('slots').appendChild(slotlist);
(function (slottime) {
slottime.addEventListener("change", function () {
select[i] = this.value;
});
})(slottime);
}
}
You'll have to close in the iterator as well in that IIFE
(function (slottime, j) {
slottime.addEventListener("change", function () {
select[j] = this.value;
});
})(slottime, i);
and it's only updated when the element actually change
The cool thing about JavaScript arrays is that you can add things to them after the fact.
var select = [];
for(var i = 0; i < nameSlots; i++) {
var newValue = this.value;
// Push appends the new value to the end of the array.
select.push(newValue);
}

Why is a named function not working when the unnamed was?

I had this code:
$('#testsPane').live("click", function() {//if the secondary ui nav tests is
selected
//Displays the test list
var listOfTests = "";
var subjects = [];
var tests= [];
var titles = [];
var keysplit;
var testSubj;
var key, value;
for (var i = 0; i < localStorage.length; i++) {
key = localStorage.key(i);
value = localStorage.getItem(key);
keysplit = key.split(".");
tests.push(value);
titles.push(keysplit[0]);
subjects.push(keysplit[keysplit.length-1]);
}
for(var i=0; i < tests.length; i++) {
listOfTests += '<div class="testDisplayBox"><div
class="subjColorBar"></div><div class="testListIndiContain"><span
class="testListTitle">' + titles[titles.length-(i+1)] + '</span><span> in
</span><span class="testListSubj">' + subjects[subjects.length-(i+1)] +
'</span></div><div class="testListTags"><span
class="specTags">quiz</span></div></div>';
}
var testsDashboard = '<div id="testsList">' + listOfTests + '</div>';
$('#selectedPane').append(testsDashboard);//adds the html to the pane to make it
into the tests dashboard
})
The above code worked but I wanted to reuse some of it so I put it into a function. When I did that it did not work. Any idea why? The code below is with using a named function.
function grabTestList() {//Displays the test list
var keysplit;
var testSubj;
var key, value;
for (var i = 0; i < localStorage.length; i++) {
key = localStorage.key(i);
value = localStorage.getItem(key);
keysplit = key.split(".");
tests.push(value);
titles.push(keysplit[0]);
subjects.push(keysplit[keysplit.length-1]);
}}
$('#testsPane').live("click", function() {//if the secondary ui nav tests is selected
grabTestList();
var listOfTests = "";
var subjects = [];
var tests= [];
var titles = [];
for(var i=0; i < tests.length; i++) {
listOfTests += '<div class="testDisplayBox"><div class="subjColorBar"></div><div class="testListIndiContain"><span class="testListTitle">' + titles[titles.length-
(i+1)] + '</span><span> in </span><span class="testListSubj">' + subjects[subjects.length-(i+1)] + '</span></div><div class="testListTags"><span
class="specTags">quiz</span></div></div>';
}
var testsDashboard = '<div id="testsList">' + listOfTests + '</div>';
$('#selectedPane').append(testsDashboard);//adds the html to the pane to make it into the tests dashboard
})
Because you are defining variables in the context of the anonymous function which are unknown to the named function. Pass them to grabTestList so the .push methods can mutate those arrays.
function grabTestList(tests, titles, subjects) {
// manipulate tests/titles/subjects
}
$('blah').live('click', function() {
var tests = [], titles = [], subjects = [];
grabTestList( tests, titles, subjects );
// since tests, titles, and subjects are mutated by the function, you can just loop through them here.
})
DEMO:
Here's a sample version which you can base your code on: http://jsfiddle.net/JLK6N/2/
updated with the fix: http://jsfiddle.net/JLK6N/3/
Remember that objects are passed by reference, arrays are objects, and methods like .push are mutator methods.

Categories