I have a number of li items in a ul. I need to add all of the li items to an array, then loop through the array and sum a value that is in each li.
The value is for the number of hours that item will take. So item one might be 2 hours, item two might be 5 hours.
For every 7.5 hours, I need to add 1 day to the day field in each li. So item 1,2 and 3 will display day 1. Items 4,5,6 and 7 will display day 2 etc.
Here is what I have so far:
list array:
var list = document.getElementById("dropArea").getElementsByTagName("li");
Number of Hours:
var hrsArray = $("#sortable2 li").find("#hrsSpan").map(function () { return $(this).text() }).get();
var lengthArr = hrsArray.length;
for (var i = 0; i < lengthArr; i++) {
hrsArray[i] = hrsArray[i].replace("Hours - (", "");
hrsArray[i] = hrsArray[i].replace(")", "");
}
And here is were I count the total number of hours. I can send "1" to the day span in each li, but I can't figure out how to look at the li's on an individual basis:
//Add all the hrs together to get the total
for (var i in hrsArray) {
total += hrsArray[i];
//alert(list[i].toString());
//Object found at this point, need to figure out how to send text to day span in it.
if (total / 7.5 <= 1) {
$('#sortable2 li').find('#day').html('1');
}
}
$('#sortable2 li').find('#day')
This creates a set with all the matched objects, to retrieve a specific object use .get(index).
http://api.jquery.com/get/
$('#sortable2 li').find('#day').get(i).html('1');
To avoid rebuilding the set on every iteration, I would store it in a variable outside of the loop.
//Add all the hrs together to get the total
var $dayFields = $('#sortable2 li').find('#day');
for (var i in hrsArray) {
total += hrsArray[i];
//alert(list[i].toString());
//Object found at this point, need to figure out how to send text to day span in it.
if (total / 7.5 <= 1) {
$($dayFields.get(i)).html('1');
}
}
EDIT:
A better way to approach this would be to loop over each li instead of an array of hours:
$("#sortable2 li").each(function() {
$(this).find("hrsSpan"); // This selects the hours field
$(this).find("day"); // This selects the day field in the same li
});
When you do $('#sortable2 li').find('#day').html('1'); you lose the jquery object on the find. You would need to wrap it in the $() again. Here's a simpler way to do it without having to use find.
$("#sortable2 #day").html(1)
Heres an example of it working http://jsfiddle.net/9nutmuvm/
Related
Ok, I have been working on this for some time, I have some close to getting it to work but not completely. So what I am doing is adding the value from a weekly input form into an array with its key.
There will be no limit on the number of rows as I can (and this works fine) AJAX add a row to the form with a button.
I currently add all the totals for each day together, this works, as all the Mondays have a .Monday class on them (I can post that code it need, please just ask) and each other day.
I have also got an id on each input which as the day of the week and a count, so #Monday0, #Monday1, same for each day and each row ect.
Now what I am doing with the code below, is to add the week up and then display that (console log for now) in that weeks row. So I want to add all the daily ids, Monday though to Sunday that end in 0, then do the same for 1 and so on.
var LoadHourTotals = function() {
$('.TimebreakdownInput').change(function() {
var InputArrays = []; //Array to store all weekly inputs
var Totals = []; //Store Array total for display
GetCurrentID = $(this).attr('id');
CurrentCount = GetCurrentID.charAt(GetCurrentID.length-1)
var WeeklyArray = ["Monday"+CurrentCount,"Tuesday"+CurrentCount,"Wednesday"+CurrentCount,"Thursday"+CurrentCount,"Friday"+CurrentCount,"Saturday"+CurrentCount,"Sunday"+CurrentCount];
$.each(WeeklyArray, function(k, v) {
var values = parseFloat( $('#'+v).val() );
if (isNaN(values)) { values = 0; } //Set value to 0 if its not a number
if (!values) { values = 0; }
InputArrays.push({ key: CurrentCount, hours:values });
});
console.log(InputArrays);
//$('.TimebreakdownTotalHours').html(Totals); //Display / Add total into HTML
});
} //End of LoadHourTotals function
I think I am close with this, each daily input is saved into its own array with a key count and its value for that day. For example, 0:XX 0:XX (this seven times, all for the 1st row). This is then repeated for each row as needed.
If what I have done is not right or there is a better method for doing this, then please let me know.
But now what I need to do is go though each key, take its value, getting a 'grand' total for all seven inputs, then display or save that total into a new array (which is what I was trying to do) then display / console log each weekly total.
I have gone though a number of posts on here but I could not find anything that fits for my problem.
All help very welcome.
If I have not posted some code that is need then please let me know.
Please let me know if I have not explained myself right.
Many Thanks.
Its ok, I have found an answer. I tried this but it did not work,
var total = 0;
$.each(InputArrays,function() {
total += this;
console.log(total);
});
But some playing around with the code, I console loged 'this' and tried the following which now seems to work. Thanks
var total = 0;
$.each(InputArrays,function() {
total += this.hours;
console.log(total);
});
I have an array of objects that have a keys called timestamp and motion. motion contains a value and timestamp contains a unix timestamp. I want to iterate over a number of the objects and find what "time of day" period they correspond to, I then want to total up the motion values for that given time of day and save the entire thing in an array of arrays. I want the duration to be changeable.
Let's say these are my objects;
{
timestamp: 1397160634,
motion: 2,
id: '534771d8c311731e21c75c9f'
},
{
timestamp: 1397160634,
motion: 3,
id: '534771d8c311731e21c75c9f'
}
Now I create my results array
var sampleDuration = 60; // Min
var minutesInDay = 1440;
var samplesPerDay = minutesInDay/sampleDuration;
var finalResultItem = []
for (var i = 0; i < samplesPerDay; i++) {
var IndividualresultArray = []
IndividualresultArray.push(60*i);
IndividualresultArray.push(0);
finalResultItem.push(IndividualresultArray);
}
I now have an array of arrays with each subarray's first item being a number (corresponding to a minute stamp) and the second value being zero.
I would now like to loop through all my objects and increment the second value (motion) based on the time of day range that is in the timestamp
_forEach(objects, function (object) {
{
// grab the timestamp
// figure out which minute range it coresponds to
// increment the array value that corresponds to the minute stamp
// rinse and repeat
}
this is where I go blank, I need the end result to look something like this
[[30, 5],[60, 20],[90, 5],[120, 0] .........]
or it could even look like this
[[000002400, 5],[000003000, 20],[000003600, 5],[000004200, 0] .........]
where the first value is a timestamp that ignores the year, month, and day, and only considers the time of day.
I have considered using moment.js in some capacity but I'm not sure how. Any help with this problem would be great.
I created a jsFiddle for you. The motion increment logic should look like (I'm using jQuery here but you get the point)
// Loop through and increment motion
$.each(objs, function (idx, obj) {
var date = new Date(obj.timestamp * 1000); // Convert to milliseconds
var minutesInDay = date.getUTCHours() * 60 + date.getUTCMinutes(); // Remove UTC for local time!
var minuteRange = Math.floor(minutesInDay / sampleDuration);
finalResultItem[minuteRange][1] += obj.motion;
});
EDIT: Removed some discussion after your edit. I also used more generic logic based on sampleDuration.
This should do it:
_forEach(objects, function (object) {
var date = new Date(objec.timestamp*1000);
var minuteOfDay = date.getUTCHours()*60+date.getUTCMinutes();
finalResultItem[minuteOfDay][1] += object.motion;
})
For a variable sample rate, employ a secondOfDay and divide that by your sampleDuration, then floor it to get your array index.
I am selecting time slot on dragging on time slot cell. After selecting time slot, I enter patient name in textbox and click on select button then patient name goes to selected time slot. The user can select multiple time slot for multilpe patient name and onclick of allot button I have to insert patient name with time slot (From time To time) to database.
I have problem in getting alloted time slot ie.From time and To time in jquery.
$("#btnAllot").click(function () {
//how i get alloted time here.
$('tr').each(function () {
$(this).find('td').each(function () {
if ($(this).hasClass('yell')) {
alert($(this).closest('tr').find('td:eq(0)').text());
};
});
});
}
see jsbin on dragging on time slot cell
Ok, here is one way to do it:
You iterate over each row whose third cell has a rowspan attribute. This indicates the start of a new appointment. You can get the start time by examining the siblings (sort of) and the end time by getting the row that is rowspan - 1 elements away.
There might be better ways, but this might give you a start.
For example:
var find_closest_hour = function($row) {
var $cell = $row.children('td:first-child'),
hour = "";
// probably add something here
while($cell.length && !(hour = $.trim($cell.text()))) {
$cell = $cell.parent().prev().children('td:first-child');
}
return hour;
};
var $all_tds = $('#tableAppointment tr td:nth-child(3)'),
$tds = $all_tds.filter('[rowspan]');
// will contain a list of objects [{patient: name, start: time, end: time},...]
var appointments = $tds.map(function() {
var $this = $(this),
$row = $this.parent(),
$cells = $row.children('td'),
patient = $.trim($this.text()),
start = find_closest_hour($row).split(':', 1) + ":" + $.trim($cells.eq(1).text()),
$end_row, end;
if(this.rowspan == 1) {
end = start;
}
else {
$end_row = $all_tds.eq($all_tds.index(this) + this.rowSpan - 1).parent();
end = find_closest_hour($end_row).split(':', 1) + ":" + $.trim($end_row.children('td').eq(1).text());
}
return {patient: patient, start: start, end: end};
}).get();
DEMO
I will let you figure out how to format the times properly ;)
Note: This very much depends on your current table structure and is likely to break if you change it. To make things more flexible, you could add classes to cells that contain the important information, for example hour to each first cell that contains the hour of the day and appointment_start to the cell of an appointment. Then you could search for/filter by these.
I have a form that asks for addresses. After each address, we ask how long the person has lived in that address, with <select> dropdowns for Years and Months.
I have a jQuery event each time the <select> is changed:
var prev_addresses = 0;
$('select.months, select.years').change(function() {
// Calculate total months
var months = $('select.months').val();
var years = $('select.years').val();
var total_months = parseInt(months) + parseInt(years*12); // We parseInt() to avoid concatenation
console.log('Total months: '+total_months);
if(total_months < 12) {
// Find the next div.hidden-address
prev_addresses = prev_addresses+1;
console.log('Number of previous addresses: '+prev_addresses);
console.log('');
$('div.hidden-address').clone(true).appendTo('#previous-addresses').slideToggle();
}
});
I want this to keep on happening all the while a person has less than 12 months of addresses. However after the first time the event fires, every time a <select> is updated the console just logs the first set of values (from the original Year and Month selects, even though there are now multiple ones).
I want to total up the values of every <select> element on a page, even after more are added dynamically. How can I do this?
Hope that makes sense, I'm happy to clarify if you need further details.
Thanks,
Jack
Loop through all select boxes, and add the value to a variable, something like this:
var totalMonths = 0;
$('select.months').each(function () {
totalMonths += $(this).val();
});
$('select.years').each(function () {
totalMonths += 12 * $(this).val();
});
I have an array that has 30 date objects. The date objects are indexed in the array from the minimum date value to the maximum date value. What I would like to do is retrieve only 7 dates from the array. Out of the 7, the first one should be the minDate and the last should be the maxDate, with 5 dates in the middle. The 7 numbers should increment evenly from the minDate to the maxDate. How would I accomplish this? Hope I was clear.
Thanks,
Tonih
well if you were trying to evenly distribute by date then make sure all your objects are in the date class then do array[29].getTime()-array[0].getTime() /7 for your average step, then do something like array.forEach() with a comparason function to try and get the closest to each step.
--edit--
try something like:
//dateArray is array of dates
var targetTime:Number;
var filteredarray:Array = new Array();
var step = dateArray[29].getTime()-dateArray[0].getTime() /7
var smallestdist:Number;
var currentIndex:int;
filteredarray.push(dateArray[0]); //Add the first entry
targetTime = dateArray[29].getTime(); //set the lowest point
for(var i=1; i<7; i++){ //loop 6 more times
smallestdist = Number.POSITIVE_INFINITY; //set a large smalldist
currentIndex = 0; //Set a small index
targetTime += step; //increment the target time
dateArray.forEach(testDate); //loop through the array and test with testDate function
filteredarray[i] = dateArray[currentIndex] //Add the result to the dateArray
}
function testDate(item:Date, index:int, array:Array){
//Check the absolute value against current stored distance
if(Math.abs(item.getTime() - targetTime) < smallestdist){
//if less then set this as new target
smallestdist = Math.abs(item.getTime() - targetTime);
currentIndex = index;
}
}
of course this is dealing with a preumed even spread of dates, there could be the posibility of adding the same date to several different points if all of dateArray are clumped together, could be optimised, but see what you can do with it.
i havnt tested this code, but it should work pretty out of the box. have a look at these if you have a problem:
Array::forEach()
Date::getTime()