I have an array defined and appending it to a string field to dynamically write a HTML TR. I have named a series of JPEGs with the same name as the string value in the array so that I can dynamically print the String name and its associated image. My problem is that I want to add an onclick event to the image and pass a javascript function the same name that is printed for the table row. The images and string iterate properly but the value passed to the javascript function for each table row is defaulting to the last array item? I tried multiple scenarios and don't understand why the same storyWords[index] isn't working when it used to choose the correct JPEG file and print out the correct name.
<script type="text/javascript">
var storyWords = "";
var index;
var strWord ="";
function doStuff(word){
alert(word);
};
$(document).ready(function(){
var storyId = localStorage.getItem("StoryId");
var strHTML = "<table>";
if (storyId == "1"){
storyWords = ["Ant", "Bananas", "Bottle", "Car", "Castle"];
}
else if (storyId == "2"){
storyWords = ["Dragons", "Football", "Hollow", "Hospital", "Island"];
}
else if (storyId == "3"){
storyWords = ["Log", "Party", "Mountain", "Poles", "Princess"];
}
else{
storyWords = ["Trophy"];
}
for (index = 0; index < storyWords.length; index++){
strWord = storyWords[index];
strHTML += "<tr><td><img src=img/Words/" + storyWords[index] + ".jpg onclick=doStuff("+ storyWords[index] +");> " + storyWords[index] + "</td></tr>";
}
$('#wordText').html(strHTML + "</table>");
});
</script>
Thanks for any help!
Just rewrote your function a bit and created a Fiddle
$(document).ready(function () {
function doStuff(word) {
alert(word);
}
var storyId = 3; // just set static storyId 3 as example
var table = $('<table>');
if (storyId == "1") {
storyWords = ["Ant", "Bananas", "Bottle", "Car", "Castle"];
}
else if (storyId == "2") {
storyWords = ["Dragons", "Football", "Hollow", "Hospital", "Island"];
}
else if (storyId == "3") {
storyWords = ["Log", "Party", "Mountain", "Poles", "Princess"];
}
else {
storyWords = ["Trophy"];
}
for (index = 0; index < storyWords.length; index++) {
(function (story) {
strImg = "";
var tr = $('<tr>');
var td = $('<td>');
var img = $('<img>');
img.attr('src', 'img/Words/' + story + '.jpg');
img.click(function () {
doStuff(story);
})
img.appendTo(td);
td.append(" " + story);
td.appendTo(tr);
tr.appendTo(table);
})(storyWords[index]);
}
$("#wordText").append(table);
});
HTML:
<div id="wordText"></div>
I adjusted the creating / appending of the rows, columns, etc a bit instead of writing the whole row including the table-closing-tag as one variable. Just a suggestion as I'm more used to write it like that. Hope this is of any use for you though it's kind of a different approach :)
Related
I asked this previously but didn't get an answer that applied to my project. I am trying to load images to a table dynamically without having to use server side code. It works, but I want to be able to have an infinite loop that breaks when a picture fails to load, rather than hard code the number of rows I need. That way I won't ever have to update the code, I'll just be able to add pictures to a folder if I want to expand the table.
Right now the "onerror" attribute hides the failed image, but I also want to break out of the outer loop (loop1).
function headCatalogLoader() {
var table = document.getElementById("catalog");
var meshNum = 0;
var uniqueID = 0;
loop1:
for (var i = 0; i <= 50; i++) { // i made it 50 instead of infinite for now
var row = table.insertRow(i);
loop2:
for (var k = 0; k <= 2; k++) { // 2 is because 3 columns
var skinTone = "none";
var cell = row.insertCell(k);
if (k == 0) {
skinTone = "lgt";
}
else if (k == 1) {
skinTone = "med";
}
else if (k == 2) {
skinTone = "drk";
}
cell.innerHTML = "<img src=\"headimgs/head" + skinTone + meshNum + ".png\" id=\"head" + uniqueID + skinTone + "\" onclick=\"previewIt(this)\" onerror=\"$(this).hide();\" />";
uniqueID++;
}
meshNum++;
}
var tbody = $("table tbody");
tbody.html($("tr",tbody).get().reverse());
}
Breaking from within the attribute is out of the loop's scope and doesn't work. Also using
$('img').on("error", function () {
break loop1;
});
inside loop2 doesn't do anything. Someone suggested I use a recursive method and rewrite my function, but that won't work for me since I'm dynamically creating a table and using image names that correspond to the loop. Any help or suggestions would be wonderful!
I'm thinking you could use an XMLHttpRequest to check the response for that URL before trying to put it onto the page. If status is not 404 then insert image else break loop1. Something like this might work:
function headCatalogLoader() {
var table = document.getElementById("catalog");
var meshNum = 0;
var uniqueID = 0;
loop1:
for (var i = 0; i <= 50; i++) { // i made it 50 instead of infinite for now
var row = table.insertRow(i);
loop2:
for (var k = 0; k <= 2; k++) { // 2 is because 3 columns
var skinTone = "none";
var cell = row.insertCell(k);
if (k == 0) {
skinTone = "lgt";
} else if (k == 1) {
skinTone = "med";
} else if (k == 2) {
skinTone = "drk";
}
// note: you'll need to use an absolute path for imageUrl
var imageUrl = "http://example.co.uk/example/headimgs/head" + skinTone + meshNum + ".png";
var xhttp = new XMLHttpRequest();
xhttp.open('HEAD', imageUrl, false);
xhttp.send();
if (xhttp.status !== 404) {
cell.innerHTML = "<img src=" + imageUrl + " id=\"head" + uniqueID + skinTone + "\" onclick=\"previewIt(this)\" onerror=\"$(this).hide();\" />";
uniqueID++;
} else {
break loop1;
}
}
meshNum++;
}
var tbody = $("table tbody");
tbody.html($("tr", tbody).get().reverse());
}
Note: you'll need to use an absolute path for the XMLHttpRequest. I've just used example.co.uk/example because I don't know your URL.
I'm guessing you're only expecting it to error if the image is not found, because that would indicate that you've reached the last image in your folder, which is why I checked !== 404, if you want to break in the case of any error (such as 500 internal server error), it might be best to change if (xhttp.status !== 404) to if (xhttp.status === 200).
I am trying to compare the 5th element of my array with the value of the object which is clicked,
Here is my code :
var options = new Array();
$(".option").click(function compareReaction(name) {
var classname1 = ($(this).parent().attr('class').slice(7));
var arr = new Array();
i = 1
var text_val
while (i <= 5) {
text_val = $('.' + classname1).children('.o' + (i)).text();
arr.push(text_val);
i++;
}
alert(arr);
var result = arr[4];
alert(result.length);
alert(name);
var name1 = "spain";
if (result == 'spain') {
alert("oh yeahhhh!");
} else {
alert("oh no");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-xs-12 option o<%= k %>" onclick="compareReaction(name=(this).innerHTML)">
Now here the length of the result is 24 while its just 'spain' word in it so it should be 5 and also if I alert the onclick action it displays the class name which I want to send but somehow it is not passing it to the compareReaction so if I alert name it displays (object, object) rather it should alert the classname.
I figured out what the problem was, I had to trim the element while i was pushing into the array and secondly I was following a wrong approach i had to use event target to get the value of the div clicked so my code looks as follows:
<script type="text/javascript">
$( ".option" ).click(function (e) {
var name=$(e.target).text().trim();;
//var name = $(e.target).innerHTML().trim();
var classname1 = ($(this).parent().attr('class').slice(7));
var arr = new Array();
i = 1
var text_val
while(i <= 5){
text_val = $('.'+classname1).children('.o'+(i)).text();
arr.push(text_val.trim());
i++;
}
// alert(arr);
// var result = arr[4];
// alert(result.length);
// alert(name);
if (result == name) {
alert("oh yeahhhh!");
}else{
alert("oh no");
}
});
</script>
Here is a working fiddle of it :
https://jsfiddle.net/gxenxbay/3/
hope it helps someone someday!
Essentially I am return an array of values that will either be " " or "X". When It's "X" I would like the element to be shown (which it is on page load), and when it's " "(blank) I'd like the element to be given
style.display = 'none';
Here is my Script so far:
<script type="text/javascript">
function onSuccess(id) {
for(var i = 0; i < 100; i++) {
if (id[i] == '') {
var td_mod = document.getElementById(i);
td_mod.style.display = 'none';
}
}
}
google.script.run.withSuccessHandler(onSuccess).returnAch();
</script>
And here is the function "returnAch();"
function returnAch() {
//return the ARRAY of all 'X'
var sheet = SpreadsheetApp.getActive().getSheetByName('Achievements');
var value = sheet.getRange("E1:E100").getValues();
//Logger.log(value + "<--- Values of 'x'");
return value;
}
I've tested "returnAch()" and it logs the entire array of values - I'm just unsure which part of the HTML I'm messing up.
Thanks for any and all help!
Okay so I figured out I wasn't calling the GoogleScript Function Correctly,
Html / Javascript:
<script type="text/javascript">
function onSuccess(id) {
for(var i = 1; i < 100; i++) {
if (id[i] == '') {
var td_mod = document.getElementById(i-1);
td_mod.style.display = 'none';
console.log(td_mod);
}
}
}
google.script.run.withSuccessHandler(onSuccess).returnAch();
</script>
Google Script:
function returnAch() {
//on call return if there is an x at pos "loc"
//return the ARRAY of all 'X'
var value = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName("Achievements").getRange("E1:E100").getValues();
//Logger.log(value + "<--- Values of 'x'");
return value;
}
I am trying to swap two array in javascript. While the replacement comes to the last iteration, I am getting "NotFoundError: Node was not found" in the call of parent.replaceChild(item2,item1). Please help me what mistake I have committed.
function sortTable(col){
if($("loacte-resultsTable") == null || $("loacte-resultsTable") == undefined){
return false;
}
if (lastSort == col) {
// sorting on same column twice = reverse sort order
absOrder ? absOrder = false : absOrder = true
}
else{
absOrder = true
}
lastSort = col;
try{
var loacteResultsTable = $("loacte-resultsTable").getElementsByTagName("TBODY")[0];
var loacteResultsTableTR = loacteResultsTable.getElementsByTagName("TR");
allTR = loacteResultsTableTR;
} catch (e) {
return false;
}
// allTR now holds all the rows in the dataTable
totalRows = allTR.length;
colToSort = new Array(); //holds all the cells in the column to sort
colArr = new Array(); //holds all the rows that correspond to the sort cell
copyArr = new Array(); //holds an original copy of the sort data to match to colArr
resultArr = new Array(); //holds the output
allNums = true
allDates = true
//store the original data
//remember that the first row - [0] - has column headings
//so start with the second row - [1]
//and load the contents of the cell into the array that will be sorted
for (x=0; x < totalRows; x++){
var data = setDataType(allTR[x].childNodes[col].innerText);
if(typeof data!="undefined"){
colToSort[x] = setDataType(allTR[x].childNodes[col].innerText);
}else{
colToSort[x] = setDataType(allTR[x].childNodes[col].textContent);
}
colArr[x] = allTR[x];
}
//make a copy of the original
for (x=0; x<colToSort.length; x++){
copyArr[x] = colToSort[x];
}
//sort the original data based on data type
if (allNums){
colToSort.sort(numberOrder);
} else if (allDates){
colToSort.sort(dateOrder);
} else {
colToSort.sort(textOrder);
}
//match copy to sorted
for(x=0; x<colToSort.length; x++) {
for(y=0; y<copyArr.length; y++) {
if (colToSort[x] == copyArr[y]) {
boolListed = false
//search the ouput array to make sure not to use duplicate rows
for(z=0; z<resultArr.length; z++) {
if (resultArr[z]==y) {
boolListed = true
break;
}
}
if (!boolListed){
resultArr[x] = y
break;
}
}
}
}
//now display the results - it is as simple as swapping rows
for (x=0; x<resultArr.length; x++) {
//allTR[x].swapNode(colArr[resultArr[x]])
swapNodes(allTR[x],colArr[resultArr[x]]);
}
function swapNodes(item1,item2)
{
var itemtmp = item1.cloneNode(1);
var parent = item1.parentNode;
item2 = parent.replaceChild(itemtmp,item2);
parent.replaceChild(item2,item1);
parent.replaceChild(item1,itemtmp);
itemtmp = null;
}
}
The call to the sortTable method is from synch().This is the UI part coded in JS:
function synch(){
var loacteResults = $('loacte-results');
var loacteResultsTable = $('loacte-resultsTable');
tab = loacteResults.getElementsByTagName('TABLE')[0];
loacteResults.removeChild(tab);
var updatedResults =
'<table id="loacte-resultsTable" cellspacing="0" cellpadding="3" border="1">' +
'<thead class="thead">' +
'<tr>' +
'<th>Site ID</th>' +
'<th>Store Name</th>' +
'<th>Agent Code</th>' +
'<th>Address</th>' +
'<th>City, State</th>' +
'<th>Phone</th>' +
'<th>Hours</th>' +
'<th>Deleted</th>' +
'<th width="65px;">Priority <img src="images/sort_up_down.gif" onclick="javascript:sortTable(8)" style="cursor: pointer;"/></th>' +
'<th width="115px;">Est.Dist.(miles) <img src="images/sort_up_down.gif" onclick="javascript:sortTable(9)" style="cursor: pointer;"/></th>' +
'</tr>' +
'</thead>' ;
if(tr == '')
updatedResults = updatedResults + '<tbody><tr><td colspan="10">No Stores to display</td></tr></tbody></table>';
else
updatedResults = updatedResults + '<tbody>' + tr + '</tbody></table>';
loacteResults.innerHTML = updatedResults;
}
In the third parent.replaceChild line item1 is no longer is on the page, since it has been replaced with item2.
Your code broken down:
function swapNodes(item1,item2)
{
var itemtmp = item1.cloneNode(1); //create a copy of item 1
var parent = item1.parentNode; //set a reference to the parent
item2 = parent.replaceChild(itemtmp,item2); //replace item2 with the copy of item1 and store the old child in item2
parent.replaceChild(item2,item1); //replace item1 with item2
parent.replaceChild(item1,itemtmp); //this line is redundant. <-- item1 no longer is on the page.
itemtmp = null;
}
I have this code that sends the values a user have typed in... the information and numbers are sent as an array and pushed into another array, I then display the text in a dynamically created list element and number in a span element...
var button = $('#add');
button.click(function()
{
var filmnamn = $('#name');
var filmnamnet = filmnamn.val();
var betyg = $('#star');
var betyget = betyg.val();
betyget = Number(betyget);
if(filmnamnet == 0)
{
$('#name').css('background-color', 'red');
}
if(betyget == 0)
{
$('#star').css('background-color', 'red');
}
if(betyget == 0 || filmnamnet == 0)
{
alert("Vänligen fyll i fälten korrekt");
}
else
{
var array = new Array();
array.unshift(betyget);
array.unshift(filmnamnet);
film_array.unshift(array);
betyg_array.unshift(array);
updateFilmList();
}
});
var film_list = $("#filmlista");
var film_array = new Array();
function updateFilmList()
{
document.getElementById("name").value = '';
document.getElementById("star").value = 0;
var filmen = film_array[0][0];
var grade = film_array[0][1];
var element = '<li class="lista">' + filmen + '<span class="betyg">'+ grade +'</span></li>';
film_list.append(element);
changeNumber();
}
And at last I have the function that i want to change the number in the span element to the amount of stars that the number shows... this works fine but only for the first created list and span element, when I try to add more listelements the number wont show up as stars, can someone tell me why this happens and point me in the direction to fix the problem?
function changeNumber(){
var elements= document.getElementsByClassName("betyg");
for (var i=0; i<elements.length; i++) {
var element = elements[i];
var length = parseInt(element.innerHTML);
var x=Array(length+1).join("*");
element.innerHTML=x;
}
}