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.
Related
Specific situation.. I'm having an array filled with datetimes I pull in via an api.
Users should be able to select a date from a datepicker (only showing dates available in the array) and afterwards see the corresponding time.
So what I've done..
The original array is obtained via php, so before starting to populate the datepicker with possible dates I create an extra array with dates only.
Since I maintain the key's it's possible to put these 2 arrays next to eachother.
Array looks as following:
["8-8-2017,07:00", "26-8-2017,07:00"];
So far so good...
After a user picks a date I trigger this to be able to start digging for the time corresponding that date.
Now it's getting messy...
$('#datepick').datepicker().on("input change", function(e) {
$("#uur").text('');
var selecteddate = e.target.value;
var searchArr = datesArray;
var ind = searchArr.indexOf(selecteddate.toString());
var result = datesArray.filter(function(item) {
return typeof item == 'string' && item.indexOf(selecteddate.toString()) > -1;
});
var afterComma = result.toString().substr(result.toString().indexOf(",") + 1);
var final = afterComma.replace(":", "u");
$("#uur").text("De warming up party gaat van start rond " + final);
});
The result is that this only works on the last element of the array.
Because I'm splitting based on the comma's. Now I know the easiest way to work arround this would be to change the , that's seperating date and time in another symbol but still I'm wondering why this couldn't be easier.
You convert whole array to string every time. You should change following code:
var afterComma = result.toString().substr(result.toString().indexOf(",") + 1);
To this;
var afterComma = item.toString().substr(item.toString().indexOf(",") + 1);
Edit:
I also missed the loop above
//for every item in result, afterComma will refer to related minute string
for (var item in result) {
var afterComma = item.toString().substr(item.toString().indexOf(",") + 1);
// Do rest here
}
I have a table which works as expected, show all the data that falls between start and end dates(please look on comments for more info). only issue I am having right now is when I click next button on a table, the table header moves dates to next week dates and shows the data for that week but also it shows the data from last week as well. what I needed was if it goes to next week date it should show data only for that week (no rows/data from last week).
//this is only an eg:
function test() {
//this is the table header start date(in pic)6/4/17
var test1 = document.getElementById("testing").innerHTML;
//this is the table header close date(in pic)6/10/17
var test2 = document.getElementById("testin").innerHTML;
//this is the function if dates is between start and end its displays the data in a tabel
function dateInRange(dbdates, start, end) {
if (end >= dbdates && start <= dbdates) {
return true;
} else {
return false;
}
}
var columns = ['orange']
var table = document.getElementById('tablet');
for (var i = 0; i < (testvalues.length - 1); i = i + 5) { //looping all values from db
if (dateInRange(testvalues[i + 2], test1, test2)) {
var row = table.insertRow(-1);
var cell1 = row.insertCell(-1);
var cell2 = row.insertCell(-1);
//more logic
//this is just an ex:
//this is next button on table
$("next").click(
test();
}
You need something like the following at the start of your dateInRange function:
function dateInRange(dbdates, start, end) {
dbdates=Date(dbdates);
start=Date(start);
end=Date(end);
//rest of function
}
This will allow you to do the Date comparison you are attempting. You could convert the values to Dates before passing them to the function but this keeps your code cleaner.
In regards to removing/replacing all the existing rows except for the header, a good solution is here: Delete all rows in an HTML table
In order to compare dates, you need to tell Javascript your string is a date and not just a regular string.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
You should remove the data of table before for loop , try it:
$("#tablet tbody tr").remove();
I have a sheet that employees will update daily with information about tasks done that day. Each column has a date in the header row (row 3 in this case), and after the end of the following day I want that column to lock so it cannot be edited further except by myself and one other. This is to prevent people from covering up mistakes or accidentally changing or deleting data.
I am looking for a script or something that will accomplish this. This sheet has about 45 tabs and I need the same thing applied to all of them.
My idea is possibly a script that triggers at a certain time based off the date in the header row, so if the date is May 5th 2017, the respective column would lock itself at midnight on the 6th.
A link to a copy of my sheet, minus data is here.
Alternatively, if there is a way to simply lock any cell 24 hours after the most recent data is entered into it, and prevent further editing by everyone except select people, that could work too if the ideal method isn't doable.
Yes, there is a way to do this.
I will briefly describe the solution:
Let's say that the first row has 1:1 contains consecutive dates.
Create function lockColumns which would create new protected range.
Add function lockColumns to time trigger, which triggers every day between 0:01 and 1:00 am.
And now some code:
function lockColumns() {
var ss = SpreadsheetApp.getActive().getSheetByName('Sheet 1')
var range = ss.getRange('1:1').getValues()[0];
var today = new Date();
var todayCol = null;
for (var i=0; i<range.length; i++) {
if (today.isSameDateAs(range[i])) {
todayCol = i;
break;
}
}
var rangeToProtect = ss.getRange(1, todayCol +1, ss.getMaxRows(), 1)
var protection = rangeToProtect.protect().setDescription('Protected range');
// Ensure the current user is an editor before removing others. Otherwise, if the user's edit
// permission comes from a group, the script will throw an exception upon removing the group.
var me = Session.getEffectiveUser();
protection.addEditor(me);
protection.removeEditors(protection.getEditors());
if (protection.canDomainEdit()) {
protection.setDomainEdit(false);
}
protection.addEditor('email#gmail.com'); // second person with edit permissions
}
/*
http://stackoverflow.com/a/4428396/2351523
*/
Date.prototype.isSameDateAs = function(pDate) {
return (
this.getFullYear() === pDate.getFullYear() &&
this.getMonth() === pDate.getMonth() &&
this.getDate() === pDate.getDate()
);
}
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 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();
});