Array.sort not working correctly - javascript

I need the sort function to sort the dates from the earliest date to the latest date. What can I do to fix this in my tasks table?
var tasks = new Array();
var index = 0;
function addTask() {
var temptask = document.getElementById("taskinfo").value;
var td = document.getElementById("taskdate").value;
var tempdate = new Date(td);
//add array and populate from tempdate and temptask
//generate html table from 2d javascript array
tasks[index] = {
Date: tempdate,
Task: temptask,
};
index++
tasks.sort(function(a,b){return new Date(b.Date).getTime() - new Date(a.Date).getTime()});
var tablecode = "<table class = 'tasktable'>" +
"<tr>"+
"<th>Date</th>"+
"<th>Task</th>"+
"</tr>";
for (var i = 0; i < tasks.length; i++) {
tablecode = tablecode + "<tr>" +
"<td>" + tasks[i]["Date"].toDateString() + " </td>" +
"<td>" + tasks[i]["Task"] + " </td>" +
"</tr>";
}
tablecode = tablecode + "</table>";
document.getElementById("bottomright").innerHTML = tablecode;
return false;
}
I have tried many different syntax variations and can not get the sort function to sort in descending order

Since the date is represented as
the number of milliseconds since 1 January, 1970 UTC (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date)
the sorting order you are looking for is ascending not descending.
Also, as #birdspider already commented, there is no use of creating new Date objects and invoking the getTime() method. They are comparable as they are.
To summarize the above points, try using the following sorting function:
function sortDatesAsc(tempdateA, tempdateB) {
return tempdateA - tempdateB < 0 ? -1 : (tempdateA > tempdateB ? 1 : 0);
}
tasks.sort(sortDatesAsc);

You're subtracting a.Date from b.Date, exactly the reverse of what you want.
Flip those around (and remove the unnecessary new Date() wrappers, although they're not actually breaking anything) and you'll get the correct sort:
var tasks = [],
index = 0;
function addTask() {
var temptask = document.getElementById("taskinfo").value;
var td = document.getElementById("taskdate").value;
var tempdate = new Date(td);
tasks[index] = {
Date: tempdate,
Task: temptask,
};
index++
tasks.sort(function(a, b) {
return a.Date.getTime() - b.Date.getTime()
});
var tablecode = "<table class='tasktable'>" +
"<tr>" +
"<th>Date</th>" +
"<th>Task</th>" +
"</tr>";
for (var i = 0; i < tasks.length; i++) {
tablecode += "<tr>" +
"<td>" + tasks[i]["Date"].toDateString() + " </td>" +
"<td>" + tasks[i]["Task"] + " </td>" +
"</tr>";
}
tablecode += "</table>";
document.getElementById("bottomright").innerHTML = tablecode;
return false;
}
document.getElementById('add').addEventListener('click', addTask);
<p>Task:
<input type="text" id="taskinfo" /></p>
<p>Date:
<input type="date" id="taskdate" /></p>
<button id="add">add</button>
<div id="bottomright"></div>

Related

Remove items from array when removing from table

I have a function that builds up a table of dates as the user clicks on different dates in a date picker.
An array is also built up of the dates as they are added to the table
I also have a function to remove the dates from the table and array as they are clicked in the table
This all works except the last part. The dates are removed from the table but not the array and this is what I need help with.
I don't think it is appending
//function to build up custom dates list
var customStartDates = [];
var customEndDates = [];
$("#btnStartDate").on('click', function () {
//I think this.value below is undefined..
$('#customDatesTable').append("<tr id='" + this.value + "'><td>" +
$("#StartDateCustom").val() + "<input type='hidden'
name='CustomStartDates[]' value='"
+ $("#StartDateCustom").val() + "'>" + "<input type='hidden'
name='CustomEndDates[]' value='"
+ $("#EndDateCustom").val() + "'>" + "</td>" + "<td>"
+ $("#EndDateCustom").val() + "</td>" + "<td
width='10%'>X</td> </tr>");
customStartDates.push( $("#StartDateCustom").val());
customEndDates.push($("#EndDateCustom").val());
});
//function to remove custom dates from table
$("#customDatesTable").on('click', 'td', function () {
var item = $(this).parent().attr('value');
$(this).parent().remove();
customStartDates = $.grep(customStartDates, function (value) {
return value != item;
});
customEndDates = $.grep(customEndDates, function (value) {
return value != item;
});
});
You should read id attribute of <TR>, as <TD> parent's can only be <TR> which doesn't have value attribute.
var item = $(this).parent().attr('id');
Send Start Date or End Date as Input parameter For a Function and Splice that Selected Date Index From the array.
Try this for both Start and End Dates
function DeleteStartDate(StartDate) {
for (var i = 0; i < customStartDates.length; i++) {
if (StartDate == customStartDates[i]) {
customStartDates.splice(i, 1);
$("#btnStartDate").click();
}
}
}

How to create a table in JS

I need to create a table in JS and show it in the page but it does not seem to work. I have two functions, the first one to actually create the table and the second one to order the elements in the table. I tried creating a simple div in html with id showlist but the table does not appear in the page. Please see the code below.
function myfunction() {
var array2 = [];
var list = "<table border ='1'>";
array2.sort(order);
list = list + "<tr>";
list = list + "<td colspan = '2'> TABLE </td>";
list = list + "</tr>";
list = list + "<tr>";
list = list + "<td> PRICE</td>";
list = list + "</tr>";
for (i = 0; i <= array2.length; i++) {
list = list + "<tr>";
list = list + "<td>" + array2[i].name + "</td>";
list = list + "<td>" + array2[i].price + "</td>";
list = list + "</tr>";
}
list = list + "</table>";
$("#showlist").html(list);
}
function order(n1, n2) {
if (n1.price > n2.price) {
return 1;
} else {
if (n1.price < n2.price) {
return -1;
} else {
return 0;
}
}
}
Your for loop <= runs from 0 to array2.length, it should be < - from 0 to array2.length-1.
for (i = 0; i < array2.length; i++) {
// ^_ Notice change here
...
}
Else, the last iteration would throw undefined errors.
Uncaught TypeError: Cannot read property 'name' of undefined
Fiddle Example

Creating html table using Javascript not working

Basically, I want the user the just change the 'height' variable to how ever many rows he wants, and then store the words which each td in the row should contain, and the code should then generate the table.
My html is just this:
<table id="newTable">
</table>
This is my Javascript:
<script type="text/javascript">
var height = 2; // user in this case would want 3 rows (height + 1)
var rowNumber = 0;
var height0 = ['HeadingOne', 'HeadingTwo']; // the words in each td in the first row
var height1 = ['firstTd of row', 'secondTd of row']; // the words in each td in the second row
var height2 = ['firstTd of other row', 'secondTd of other row']; // the words in each td in the third row
$(document).ready( function() {
createTr();
});
function createTr () {
for (var h=0; h<height + 1; h++) { // loop through 3 times, in this case (which h<3)
var theTr = "<tr id='rowNumber" + rowNumber + "'>"; // <tr id='rowNumber0'>
$('#newTable').append(theTr); // append <tr id='rowNumber0'> to the table
for (var i=0; i<window['height' + rowNumber].length; i++) {
if (i == window['height' + rowNumber].length-1) { // if i==2, then that means it is the last td in the tr, so have a </tr> at the end of it
var theTd = "<td class='row" + rowNumber + " column" + i + "'>" + window['height' + rowNumber][i] + "</td></tr>";
$('#rowNumber' + rowNumber).append(theTr); // append to the end of the Tr
} else {
var theTd = "<td class='row" + rowNumber + " column" + i + "'>" + window['height' + rowNumber][i] + "</td>";
$('#rowNumber' + rowNumber).append(theTr);
}
}
rowNumber += 1;
}
}
</script>
I did 'alert(theTr);' and 'alert(theTd);' and they looked correct. How come this code doesn't generate any table?
You should change the line
$('#rowNumber' + rowNumber).append(theTr);
into
$('#rowNumber' + rowNumber).append(theTd);
You are adding the Tr-Code again in the inner loop, but you actually wanted to add the Td-Code.
All that window["height"+rowNumber] stuff is a poor way to do it. Use an array, and pass it as a parameter to the function so you don't use global variables. And use jQuery DOM creation functions instead of appending strings.
<script type="text/javascript">
var heights = [['HeadingOne', 'HeadingTwo'], // the words in each td in the first row
['firstTd of row', 'secondTd of row'], // the words in each td in the second row
['firstTd of other row', 'secondTd of other row'] // the words in each td in the third row
];
$(document).ready( function() {
createTr(heights);
});
function createTr (heights) {
for (var h=0; h<heights.length; h++) { // loop through 3 times, in this case (which h<3)
var theTr = $("<tr>", { id: "rowNumber" + h});
for (var i=0; i<heights[h].length; i++) {
theTr.append($("<td>", { "class": "row"+h + " column"+i,
text: heights[h][i]
}));
}
$('#newTable').append(theTr); // append <tr id='rowNumber0'> to the table
}
}
</script>
JSFIDDLE

Tweak needed to store multiple data in Javascript array or an object

I have a string as
var str = 'Supplier Name^supplier^left^string*Spend (USD MM)^spend^right^number^5';
I write a function in javascript to retrieve the datafield names from the above string and store it in an array as :
function getColNamesfromConfig(str) {
var cols = new Array();
for (i = 0; i <= str.split('*').length - 1; i++) {
cols[i] = str.split('*')[i].split('^')[1];
//Will write logic to retrieve the Supplier Name, Spend (USD MM) fields etc
}
return cols;
}
The result i get is as :
cols[0] = supplier;
cols[1] = spend; and so on..(which are datafields)
Then i make a dynamic table and use the above info retrieved as :
"onResultHttpService": function (result, properties) {
var json_str = Sys.Serialization.JavaScriptSerializer.deserialize(result);
var colNames = getColNamesfromConfig(properties.PodAttributes.DGConfig);
var htmlMarkup = '';
htmlMarkup = "";
htmlMarkup = htmlMarkup + "<table width='100%' border='1' cellspacing='0' cellpadding='0' class='gridView gridMouseOverEffect'>";
htmlMarkup = htmlMarkup + "<tr>";
for (var c = 0, colLen = colNames.length; c < colLen; c++) {
//COLUMN LOOP (here i want to bind 'Supplier Name' and not 'supplier' which is what i get from getColNamesfromConfig(str);
htmlMarkup = htmlMarkup + "<th align='left' class='secondaryLink tableContentRow'> <h5>" + colNames[c] + "</h5>";
htmlMarkup = htmlMarkup + "</th>";
}
htmlMarkup = htmlMarkup + "</tr>";
for (var i = 0, rowlen = json_str.length; i < rowlen; i++) {
htmlMarkup = htmlMarkup + " <tr>"
for (var c = 0, colLen = colNames.length; c < colLen; c++) {
htmlMarkup = htmlMarkup + " <td align='left' class='secondaryLink tableContentRow'> " + json_str[i][colNames[c]];
htmlMarkup = htmlMarkup + "</td>"
}
htmlMarkup = htmlMarkup + "</tr>"
}
htmlMarkup = htmlMarkup + "</table>"
divPortletId = '#' + properties.id;
$(htmlMarkup).appendTo($(divPortletId));
}
If i had to retrieve the Display Name as well from the sample string how would i store it in the same array and access it?. For ex: i want something where i can just loop and get my Display Name (Supplier Name) and also datafield name (supplier). I just want to bind the Display name in my COLUMN LOOP where it is currently binding the column data field. Thus please help me TWEAK my getColNamesfromConfig(str) function to return both the datafield as well as displayname in an array or an object literal if possible..I need something like
cols[0].DisplayName = "Supplier Name";
cols[0].DatafieldName = "supplier";
cols[1].DisplayName = "Spend (USD MM)";
cols[1].DatafieldName = "spend";
function getColNamesfromConfig(str) {
var cols = new Array();
for (i = 0; i <= str.split('*').length - 1; i++) {
cols[i] = {}
cols[i].DatafieldName = str.split('*')[i].split('^')[1];
cols[i].DisplayField = str.split('*')[i].split('^')[0];
}
return cols;
}
That should do the trick

Splitting an array

I have two javascript functions, the first one is working, teh second is working but not echoing the correct value in the hidden inputs.
Ive manage to get the last hidden input value correct but I'm not sure how
var customTicketsArr = Array();
function EditEventAddTicket(){
alertWrongTime = false;
var TicketName = jQuery("#ticketname").val();
var TicketPrice = jQuery("#ticketprice").val();
var ticketquantity = jQuery("#ticketquantity").val();
var storeString = "TicketName" + TicketName + "TicketPrice" + TicketPrice + "Quantity" + ticketquantity + '';
customTicketsArr.push(storeString);
EditEventUpdateTickets(true);
}
function EditEventUpdateTickets(fade){
jQuery("#custom_tickets_string").val(customTicketsArr);
var output = "";
var style = "";
for (i = customTicketsArr.length-1; i >= 0; i--){
ticketname = customTicketsArr[i].split("TicketName");
ticketprice = customTicketsArr[i].split("TicketPrice");
ticketquantity = customTicketsArr[i].split("Quantity");
if(fade){
if (customTicketsArr.length - 1 == i){
style = "display: none; ";
var fadeInDiv = i;
} else {
style = "";
}
}
if (i % 2 == 1) { style += "background-color: #660000; "}
html = "<div id='customticket" + i + "' class='customeventbase' style='" + style + "'>";
html += '<input type="hidden" name="customTicketid[' + i + '][Name]" id="customticketName' + i + '" value="'+ ticketname + '" />';
html += '<input type="hidden" name="customTicketid[' + i + '][Price]" id="customticketPrice' + i + '" value="' +ticketprice[1] +'" />';
html += '<input type="hidden" name="customTicketid[' + i + '][Quantity]" id="customticketQuantity' + i + '" value="'+ ticketquantity[1] +'" />';
html += '<button class="customeventdel" type="button" onClick="EditEventRemoveDate(' + i + ')"></button>';
html += '<div class="clear"></div>';
html += '</div>\n';
output += html;
}
output += "<input type='hidden' id='custom_ticket_info' name='custom_ticket_info' value='" + customTicketsArr + "' />";
jQuery("#custom_ticket_container").html(output);
if(fade){
setTimeout("EditEventfadeInDiv(" + fadeInDiv +")", 10);
}
}
this outputs:
<div style="background-color: #660000; " class="customeventbase" id="customticket1">
<input type="hidden" value=",testTicketPrice50Quantity44" id="customticketName1" name="customTicketid[1][Name]">
<input type="hidden" value="undefined" id="customticketPrice1" name="customTicketid[1][Price]">
<input type="hidden" value="44" id="customticketQuantity1" name="customTicketid[1][Quantity]">
<button onclick="EditEventRemoveDate(1)" type="button" class="customeventdel"></button>
<div class="clear"></div></div>
the values for the first two hidden fields are incorrect
They're not incorrect values - split() is doing exactly what it is supposed to - returning an array of substrings after removing the separator.
With your string structure, splitting on TicketName will give you two strings - the substring before the separator and the substring after - TicketName itself is not included.
Thus, for the string "TicketNametestTicketPrice50Quantity44", you will get "" and "testTicketPrice50Quantity44" when you split on "TicketName" . Splitting the same string on TicketPrice will give you "TicketNametest" and "50Quantity44".
I'd suggest putting objects into your array instead -
var storeObject = {
"TicketName" : TicketName,
"TicketPrice" : TicketPrice,
"Quantity" : ticketquantity
};
customTicketsArr.push(storeObject);
You can then get back the data as:
for (i = customTicketsArr.length-1; i >= 0; i--){
var currentObject = customTicketsArr[i];
var ticketname = currentObject.TicketName;
var ticketprice = currentObject.TicketPrice;
var ticketquantity = currentObject.Quantity;
//do other stuff here
}
why do you save it as a string? I would recommend storing it in an object:
function EditEventAddTicket(){
alertWrongTime = false;
var TicketName = jQuery("#ticketname").val();
var TicketPrice = jQuery("#ticketprice").val();
var ticketquantity = jQuery("#ticketquantity").val();
var ticket = {"TicketName": TicketName, "TicketPrice": TicketPrice, "Quantity": ticketquantity};
customTicketsArr.push(ticket);
EditEventUpdateTickets(true);
}
and then you can simply load the data:
for (i = customTicketsArr.length-1; i >= 0; i--){
ticketname = customTicketsArr[i].TicketName;
ticketprice = customTicketsArr[i].TicketPrice;
ticketquantity = customTicketsArr[i].Quantity;
// ...
}
Why not just make a two dimensional array?
var customTicketsArr = Array();
function EditEventAddTicket() {
customTicketsArr.push({
'name' : jQuery("#ticketname").val(),
'price' : jQuery("#ticketprice").val(),
'qty' : jQuery("#ticketquantity").val()
});
}

Categories

Resources