Javascript: Javascript ignores the elements generated by itself - javascript

I have this javascript function that generates new selects with IDs:
function generateChild(root, categories){
++counter;
var appendid = "id='selectCategory_".concat(counter);
var coma = "'";
var mayorque = "'>";
var appendcoma = appendid.concat(coma);
var select ="<div class='selectContainer'".concat(appendcoma);
var close = "><select ";
var cerrar = select.concat(close);
var appendidselect = cerrar.concat(appendid);
var html = appendidselect.concat(mayorque);
for (var i = 0; i < categories.length; i++) {
html += "<option value='" + categories[i] + "'>" + categories[i] + "</option>";
}
html += '</select></div>';
// ---------------------------
// ---------------------------
// create an element from the html string
// ---------------------------
var tplt = root.createElement('template');
tplt.innerHTML = html;
var el = tplt.content.firstChild;
// ---------------------------
// ---------------------------
// attach the change handler
// ---------------------------
el.firstChild.addEventListener("change", handle_onChange);
// ---------------------------
return el;
}
}
And then this function to search for the last dropdown that didn't have a blank space on it, and save it in a hidden input for later use:
if(this.value == ' '){
for (var i = counter - 1 ; i >= 0 ; --i){
var string = i.toString();
var selectid = "selectCategory_".concat(string);
if(document.getElementById(selectid)){
document.getElementById("category").value = document.getElementById(selectid).value;
break;
}
}
}
else{
var lastselectedvalue = this.value;
document.getElementById("category").value = this.value;
}
This works well with the first dropdown, which is already in the code:
<input type ="hidden" name="category" id = "category" value="">
<div id="category0" class="selectContainer">
<select id="selectCategory_0">
<option>something</option>
<option>something else</option>
</select>
</div>
But never works with the other dropdowns, it always returns undefined.

Related

How to populate HTML drop down with Text File using JavaScript?

I have been stuck on this problem for a while now, Basically i want to populate the below select with option group and option check boxes. The text file imports to JS just fine, i'm getting the problem trying to populate the drop down. Here is my HTML:
function LoadTxtFile(p) {
var AllTxtdata = '';
var targetFile = p.target.files[0];
if (targetFile) {
// Create file reader
var FileRead = new FileReader();
FileRead.onload = function (e) {
if (FileRead.readyState === 2) {
AllTxtdata = FileRead;
// Split the results into individual lines
var lines = FileRead.result.split('\n').map(function (line) {
return line.trim();
});
var select = $("#MySelect");
var optionCounter = 0;
var currentGroup = "";
lines.forEach(function (line) {
// If line ends it " -" create option group
if (line.endsWith(" -")) {
currentGroup = line.substring(0, line.length - 2);
optionCounter = 0;
select.append("<optgroup id'" + currentGroup + "' label='" + currentGroup + "'>");
// Else if the line is empty close the option group
} else if (line === "") {
select.append("</optgroup>");
// Else add each of the values to the option group
} else {
select.append("<option type='checkbox' id='" + (currentGroup + optionCounter) + "' name'"
+ (currentGroup + optionCounter) + "' value='"
+ line + "'>" + line + "</option>");
}
});
}
}
FileRead.readAsText(targetFile);
}
}
document.getElementById('file').addEventListener('change', LoadTxtFile, false);
<html>
<body>
<select name="MySelect" id="MySelect"/>
</body>
</html>
I believe you are using append incorrectly as you are dealing with partial nodes with the optgroup. I would build the html snippet then append it in one go. This would also bring a performance benefit as multiple DOM manipulations can get expensive.
I'd do something like the following.
function LoadTxtFile(p) {
var AllTxtdata = '';
var htmlString = '';
//Optional Templates. I find them more readable
var optGroupTemplate = "<optgroup id='{{currentGroup}}' label='{{currentGroup}}'>";
var optionTemplate = "<option type='checkbox' id='{{currentGroupCounter}}' name='{{currentGroupCounter}}' value='{{line}}'>{{line}}</option>";
var targetFile = p.target.files[0];
if (targetFile) {
// Create file reader
var FileRead = new FileReader();
FileRead.onload = function (e) {
if (FileRead.readyState === 2) {
AllTxtdata = FileRead;
// Split the results into individual lines
var lines = FileRead.result.split('\n').map(function (line) {
return line.trim();
});
var select = $("#MySelect");
var optionCounter = 0;
var currentGroup = "";
lines.forEach(function (line) {
// If line ends it " -" create option group
if (line.endsWith(" -")) {
currentGroup = line.substring(0, line.length - 2);
optionCounter = 0;
htmlString += optGroupTemplate.replace("{{currentGroup}}", currentGroup);
// Else if the line is empty close the option group
} else if (line === "") {
htmlString +="</optgroup>";
// Else add each of the values to the option group
} else {
//I'm assuming you want to increment optionCounter
htmlString += optionTemplate.replace("{{currentGroupCounter}}", currentGroup + optionCounter).replace("{{line}}", line);
}
});
select.append(htmlString);
}
}
FileRead.readAsText(targetFile);
}
}
document.getElementById('file').addEventListener('change', LoadTxtFile, false);
NOTE the above is untested and may need some debugging.

Only show objects in array that contain a specific string

I was trying to make something where you can type a string, and the js only shows the objects containing this string. For example, I type Address1 and it searches the address value of each one then shows it (here: it would be Name1). Here is my code https://jsfiddle.net/76e40vqg/11/
HTML
<input>
<div id="output"></div>
JS
var data = [{"image":"http://www.w3schools.com/css/img_fjords.jpg","name":"Name1","address":"Address1","rate":"4.4"},
{"image":"http://shushi168.com/data/out/114/38247214-image.png","name":"Name2","address":"Address2","rate":"3.3"},
{"image":"http://www.menucool.com/slider/jsImgSlider/images/image-slider-2.jpg","name":"Name3","address":"Address3","rate":"3.3"}
];
var restoName = [], restoAddress = [], restoRate = [], restoImage= [];
for(i = 0; i < data.length; i++){
restoName.push(data[i].name);
restoAddress.push(data[i].address);
restoRate.push(data[i].rate);
restoImage.push(data[i].image);
}
for(i = 0; i < restoName.length; i++){
document.getElementById('output').innerHTML += "Image : <a href='" + restoImage[i] + "'><div class='thumb' style='background-image:" + 'url("' + restoImage[i] + '");' + "'></div></a><br>" + "Name : " + restoName[i] + "<br>" + "Address : " + restoAddress[i] + "<br>" + "Rate : " + restoRate[i] + "<br>" + i + "<br><hr>";
}
I really tried many things but nothing is working, this is why I am asking here...
Don't store the details as separate arrays. Instead, use a structure similar to the data object returned.
for(i = 0; i < data.length; i++){
if (data[i].address.indexOf(searchedAddress) !== -1) { // Get searchedAddress from user
document.getElementById("output").innerHTML += data[i].name;
}
}
Edits on your JSFiddle: https://jsfiddle.net/76e40vqg/17/
Cheers!
Here is a working solution :
var data = [{"image":"http://www.w3schools.com/css/img_fjords.jpg","name":"Name1","address":"Address1","rate":"4.4"},
{"image":"http://shushi168.com/data/out/114/38247214-image.png","name":"Name2","address":"Address2","rate":"3.3"},
{"image":"http://www.menucool.com/slider/jsImgSlider/images/image-slider-2.jpg","name":"Name3","address":"Address3","rate":"3.3"}
];
document.getElementById('search').onkeyup = search;
var output = document.getElementById('output');
function search(event) {
var value = event.target.value;
output.innerHTML = '';
data.forEach(function(item) {
var found = false;
Object.keys(item).forEach(function(val) {
if(item[val].indexOf(value) > -1) found = true;
});
if(found) {
// ouput your data
var div = document.createElement('div');
div.innerHTML = item.name
output.appendChild(div);
}
});
return true;
}
<input type="search" id="search" />
<div id="output"></div>

Create a new dropdown with javascript

I am trying to create a dropdown after I choose an option in an original dropdown.
This is the HTML code:
<br>
<select id ="select-container" onchange="addSelect('select-container');">
<option>test1</option>
<option>test2</option>
<option>test3</option>
</select>
<br>
This is the javascript.
function categorygenerate() {
//for testing purposes
var categoryarray = new Array(),
i;
for (i = 0; i < 3; i++) {
categoryarray[i] = Math.random();
}
return categoryarray;
}
function addSelect(divname) {
var newDiv = document.createElement('div');
var html = '<select>',
dates = categorygenerate(),
i;
for (i = 0; i < dates.length; i++) {
html += "<option value='" + dates[i] + "'>" + dates[i] + "</option>";
}
html += '</select>';
newDiv.innerHTML = html;
document.getElementById(divname).appendChild(newDiv);
console.log($("#" + divname).html());
console.log(newDiv);
}
The debugger mode shows me no error.
It is because you are trying to append your code in the "original select": look at the id of your select.
You have to add a div tag with the id="select-container" and remove it from the "original select"
Here is a working snippet:
function categorygenerate() {
//for testing purposes
var categoryarray = new Array(),
i;
for (i = 0; i < 3; i++) {
categoryarray[i] = Math.random();
}
return categoryarray;
}
function addSelect(divname) {
var newDiv = document.createElement('div');
var html = '<select>',
dates = categorygenerate(),
i;
for (i = 0; i < dates.length; i++) {
html += "<option value='" + dates[i] + "'>" + dates[i] + "</option>";
}
html += '</select>';
newDiv.innerHTML = html;
document.getElementById(divname).appendChild(newDiv);
console.log($("#" + divname).html());
console.log(newDiv);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br>
<select onchange="addSelect('select-container');">
<option>test1</option>
<option>test2</option>
<option>test3</option>
</select>
<br>
<div id="select-container"></div>
Put your select in a div with the id select-container. Ofcourse, give your select an other ID. Then your code should work. It's because you try to append a new select to the original one in your HTML.
https://jsfiddle.net/b248a4k1/

Uncaught ReferenceError: variable is not defined on onclick function Javascript

Today , i have been read all the topic about this but couldn't come up with a solution that's why i am opening this topic.
This is my function which creates the view and i am trying to have a onclick function which should directs to other javascript function where i change the textbox value.
<script type="text/javascript">
$('#submitbtnamazon')
.click(function(evt) {
var x = document.getElementById("term").value;
if (x == null || x == "" || x == "Enter Search Term") {
alert("Please, Enter The Search Term");
return false;
}
listItems = $('#trackList').find('ul').remove();
var searchTerm = $("#term").val();
var url = "clientid=Shazam&field-keywords="
+ searchTerm
+ "&type=TRACK&pagenumber=1&ie=UTF8";
jsRoutes.controllers.AmazonSearchController.amazonSearch(url)
.ajax({
success : function(xml) {
$('#trackList')
.append('<ul data-role="listview"></ul>');
listItems = $('#trackList').find('ul');
html = ''
tracks = xml.getElementsByTagName("track");
for(var i = 0; i < tracks.length; i++) {
var track = tracks[i];
var titles = track.getElementsByTagName("title");
var artists = track.getElementsByTagName("creator");
var albums = track.getElementsByTagName("album");
var images = track.getElementsByTagName("image");
var metaNodes = track.getElementsByTagName("meta");
//trackId ="not found";
trackIds = [];
for (var x = 0; x < metaNodes.length; x++) {
var name = metaNodes[x]
.getAttribute("rel");
if (name == "http://www.amazon.com/dmusic/ASIN") {
trackId = metaNodes[x].textContent;
trackIds.push(trackId);
}
}
for (var j = 0; j < titles.length; j++) {
var trackId=trackIds[j];
html += '<div class="span3">'
html += '<img src="' + images[j].childNodes[0].nodeValue + '"/>';
html += '<h6><a href="#" onclick="someFunction('
+trackId
+ ')">'
+trackId
+ '</a></h6>';
html += '<p><Strong>From Album:</strong>'
+ albums[j].childNodes[0].nodeValue
+ '</p>';
html += '<p><Strong>Artist Name:</strong>'
+ artists[j].childNodes[0].nodeValue
+ '</p>';
html += '<p><Strong>Title:</strong>'
+ titles[j].childNodes[0].nodeValue
+ '</p>';
/*html += '<p><Strong>Created:</strong>'
+ releaseDate
+ '</p>';*/
html += '</div>'
}
}
//listItems.append( html );
$("#track").html(html);
$("#track").dialog({
height : 'auto',
width : 'auto',
title : "Search Results"
});
// Need to refresh list after AJAX call
$('#trackList ul').listview(
"refresh");
}
});
});
</script>
This is my other function where i change the textbox value. it works actually with other values e.g. when i give hardcoded string value. I can see the value in the console but for some reason it gives me the error like :
here the string starts with B is AsinId where i take from amazon. I am definitely in need of help because i am totally stucked.
Uncaught ReferenceError: B00BMQRILU is not defined 62594001:1 onclick
<script type="text/javascript">
function someFunction(var1) {
tracktextbox = document.getElementsByName("trackId");
for (var i = 0; i < tracktextbox.length; i++) {
tracktextbox[i].value = var1;
}
$('#track').dialog('close');
}
</script>
The problem is '<h6><a href="#" onclick="someFunction('+trackId+ ')">', from the error it is clear that trackId is a string value, so you need to enclose it within "" or ''. So try
'<h6><a href="#" onclick="someFunction(\'' + trackId + '\')">'

Jquery not appending values correctly

I have a fixed set of input fields on page load. I have checkboxes with values displayed and when someone checks the checkbox the values are added to the input field. If all the input fields are filled, a new one is created. My problem is that, the checkbox values are inserted correctly in existing input fields and if the value exceeds,a new input field is created but values are not inserted immediately when the input field is created.Only on the next click is the values inserted in the newly created input field. Here's the code
<script>
function fillin(entire,name,id,key) {
if (entire.checked == true) {
var split_info = new Array();
split_info = name.split(":");
var div = $("#Inputfields"+id);
var till = (div.children("input").length)/4;
var current_count = 0;
for (var j=0;j<till;j++) {
if (document.getElementById("insertname_"+j+"_"+id).value == "" && document.getElementById("insertnumber_"+j+"_"+id).value == "") {
document.getElementById("insertname_"+j+"_"+id).value = split_info[0];
document.getElementById("insertnumber_"+j+"_"+id).value = split_info[1];
break;
} else
current_count = current_count+1;
if (current_count == till) {
var x= addnew(id);
x =x+1;
$("#Inputfields"+id).find("#insertname_"+x+"_"+id).value = split_info[0];
alert($("#Inputfields"+id).find("#insertname_"+x+"_"+id).value);
document.getElementById("insertname_"+x+"_"+id).text = split_info[0];
//alert(document.getElementById("insertname_"+x+"_"+id).value);
//document.getElementById("insertnumber_"+x+"_"+id).value = split_info[1];
}
}
} else {
}
}
</script>
<script>
function addnew(n) {
//var id = $(this).attr("id");
var div = $("#Inputfields"+n);
var howManyInputs = (div.children("input").length)/4;
alert(howManyInputs);
var val = $("div").data("addedCount");
var a = '<input type="search" id="insertinstitute_'+(howManyInputs)+'_'+n+'" placeholder="Institute" class="span3">';
var b = '<input type="search" id="insertname_'+(howManyInputs)+'_'+n+'" placeholder="name" class="span3">';
var c = '<input type="search" name="" id="insertnumber_'+(howManyInputs)+'_'+n+'" placeholder="number" class="span3">';
var d = '<input type="search" name="" id="insertarea_'+(howManyInputs)+'_'+n+'" placeholder="area" class="span3">';
var fin = a+b+d+c;
$(fin).appendTo(div);
div.data("addedCount", div.data("addedCount") + 1);
return howManyInputs;
}
</script>
UPDATED: Thank you all. I was able to find the bug. The culprit was x =x+1;. It should have been x
The problem is probably here:
document.getElementById("insertname_"+x+"_"+id).text
There's no text property in elements. There's textContent (not in IE8-), innerText (in IE) and innerHTML. There's the text method in jQuery, though. So you can either do:
document.getElementById("insertname_"+x+"_"+id).innerHTML = ...
or
$("#insertname_"+x+"_"+id).text(...);
Also, these lines:
$("#Inputfields"+id).find("#insertname_"+x+"_"+id).value = split_info[0];
alert($("#Inputfields"+id).find("#insertname_"+x+"_"+id).value);
.value there should be replaced with .val(), because those are jQuery objects.
I have reworked a lot of your code for a lot of reasons. Compare the two.
function fillin(entire, name, id, key) {
if (entire.checked) {
var split_info = [];
split_info = name.split(":");
var div = $("#Inputfields" + id);
var till = (div.children("input").length) / 4;
var current_count = 0;
var j = 0;
for (j = 0; j < till; j++) {
var myj = j + "_" + id;
if ($("#insertname_" + myj).val() === "" && $("#insertnumber_" + myj).val() === "") {
$("#insertname_" + myj).val(split_info[0]);
$("#insertnumber_" + myj).val(split_info[1]);
break;
} else {
current_count = current_count + 1;
}
if (current_count === till) {
var x = addnew(id) + 1;
div.find("#insertname_" + x + "_" + id).val(split_info[0]);
alert(div.find("#insertname_" + x + "_" + id).val());
$("#insertname_" + x + "_" + id).val(split_info[0]);
}
}
}
}
function addnew(n) {
var div = $("#Inputfields" + n);
var howManyInputs = (div.children("input").length) / 4;
alert(howManyInputs);
var myi = (howManyInputs) + '_' + n + '"';
var val = div.data("addedCount");
var a = '<input type="search" id="insertinstitute_' + myi + ' placeholder="Institute" class="span3">';
var b = '<input type="search" id="insertname_' + myi + ' placeholder="name" class="span3">';
var c = '<input type="search" name="" id="insertnumber_' + myi + ' placeholder="number" class="span3">';
var d = '<input type="search" name="" id="insertarea_' + myi + ' placeholder="area" class="span3">';
var fin = a + b + d + c;
$(fin).appendTo(div);
div.data("addedCount", val + 1);
return howManyInputs;
}

Categories