I have written code in jsfiddle.net/udgeet/VUb5r/
I have to disable the previously selected date
You can use datePicker's beforeShowDay option to specify which dates you want to enable or disable.
Then it's just a case of writing a functions to
a) get the dates from the select into an array:
function daysToDisable() {
var dates = [];
for (i = 0; i < $('#inputdates option').length; i++) {
dates[i] = new Date($('#inputdates option').eq(i).val()).toString();
}
return dates;
}
and b) return true or false if the current date is in the array
function disableDates(date) {
var days = daysToDisable();
for (i = 0; i < days.length; i++) {
if ($.inArray(date.toString(), days) != -1) {
return [false];
}
}
return [true];
}
http://jsfiddle.net/vy562/1/
Related
I want to create a spreadsheet where I can add people on it and see which hours everyone is available to do a online meeting. It's mandatory to consider the timezone but I have no clue how to do it.
Person1 sheet example:
Matching hours:
I think my idea of showing 'matches 4 out of 5' is nice, cause the remaining one can make an effort to show up and edit it so it can be like 'matches 5 out of 5'. But any other suggestion is welcome.
The link of the actual spreadsheet(copy to your own drive so you can edit): https://docs.google.com/spreadsheets/d/1yun8uMW2LZUumlm6cy3hqPT-FLQipADSIjLQPNiwXl4/edit?usp=sharing
PS: It would be nice to support DST (daylight save time) but it's not mandatory. The person who is in DST will adjust it.
Assuming your timezone values are all offsets of the Match Sheet (if the match sheet says 01:00 and your timezone is -1, your local time would be 00:00), here is some code that will show you the text in the way that you want:
function availablePeople(startTime, dayOfWeek) { //All slots are 1 hour long
const sheetsNames = ["person1", "person2", "person3", "person4"]; //Edit this to update possibilities
const dayHeaderRow = 2;
const startTimeCol = 1;
const endTimeCol = 2;
var sheets = SpreadsheetApp.getActive();
var referenceHourRow = sheets.getSheetByName("match").getRange(dayHeaderRow+1, startTimeCol, 24).getValues().map(function (x) {return x.toString()}).indexOf(startTime.toString());
var referenceDayCol = sheets.getSheetByName(sheetsNames[0]).getRange(dayHeaderRow, endTimeCol+1, 1, 7).getValues()[0].indexOf(dayOfWeek);
var availablePeople = 0;
if (referenceHourRow != -1) {
for (var i = 0; i<sheetsNames.length; i++) {
var personSheet = sheets.getSheetByName(sheetsNames[i]);
var timezone = -personSheet.getRange(1, 4).getValue();
var thisDayCol = referenceDayCol;
var thisHourRow = referenceHourRow;
if (timezone!=0) {
if (thisHourRow+timezone<0) {
//Went back a day.
thisDayCol = (thisDayCol+6)%7;
thisHourRow = 24-(referenceHourRow-timezone);
} else if (thisHourRow+timezone>=24) {
//Went forward a day
thisDayCol = (thisDayCol+1)%7;
thisHourRow = (thisHourRow+timezone)%24;
} else {
thisHourRow += timezone;
}
}
var cell = personSheet.getRange(dayHeaderRow+1+thisHourRow, endTimeCol+1+thisDayCol);
if (cell.getValue()=="Available") {
availablePeople++;
}
}
}
return availablePeople+" out of "+sheetsNames.length;
}
This is how to use this function: =availablePeople(<START TIME>,<DAY OF THE WEEK>).
To allow this to be dragged and autocompleted, write =availablePeople($A3,C$2) in the "Monday" "00:00" and then drag it horizontally and vertically to update the formula.
I want to accomplish something like this:
I have a sort of "Relational" Spreadsheet, and I want rows to be colored according.
I manually choosing a unique color for each Category on the "Categories" Sheet or generating a unique color based on the string content, either would work for my use case.
Not the best solution but it works
function onEdit(e) {
if(e){
var ss = e.source.getActiveSheet();
var range = e.source.getActiveRange();
var r1 = range.getRow();
var c1 = range.getColumn();
var rowsCount = range.getNumRows();
for(var i=0; i<rowsCount; i++){
var row = ss.getRange(r1+i,1,1,ss.getMaxColumns());
updateRow(row, ss);
}
}
}
function updateRow(row, ss){
if (ss.getName() == "Entries") { // This is the sheet name
var cell = row.getCell(1,1);
var firstCellValue = cell.getValue();
if(firstCellValue){
cell.setBackgroundColor(stringToColor(firstCellValue));
}
else{
cell.setBackgroundColor(null);
}
}
}
function stringToColor(str) {
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = str.charCodeAt(i) + ((hash << 5) - hash);
}
var colour = '#';
for (var i = 0; i < 3; i++) {
var value = (hash >> (i * 8)) & 0xFF;
colour += ('00' + value.toString(16)).substr(-2);
}
return colour;
}
Based on this answer
in conditional formatting select the range you want to apply colors, select color, choose Text is exactly and set value:
How to disable the past dates in the Kendo date picker ? ( Date Picker validation)
That will allow the user to select only the current date and future date.
In the HTML :
#Html.EditorFor(Model => Model.AppointmentDate)
In the JQuery :
$('#AppointmentDatee').data('kendoDatePicker')
The shortest way to disable past dates is using min parameter with current date value:
var presentDate = new Date();
$(function () {
var datepicker = $('#AppointmentDate').kendoDatePicker({
value: presentDate,
min: presentDate,
}).data('kendoDatePicker');
});
If you're using Razor with #Html.Kendo() helper, use DatePickerBuilderBase.Min() method:
#(Html.Kendo().DatePicker().Name("AppointmentDate").Min(DateTime.Today))
However, the min parameter will remove all disabled past dates (i.e. they're not shown in calendar view). If you want to show disabled dates but the user cannot interact with them (by clicking the date), use k-state-disabled CSS class in empty option inside month parameter:
var datepicker = $('#AppointmentDate2').kendoDatePicker({
value: presentDate,
min: presentDate,
month: {
empty: '<div class="k-state-disabled">#= data.value #</div>'
}
}).data('kendoDatePicker');
If #(Html.Kendo()) helper is used, use DisabledDates to call a function which disables past dates like example below:
<script>
var getPastDates = function(begin, end) {
for (var dtarr = [], date = start; date < end; date.setDate(date.getDate() + 1)) {
dtarr.push(new Date(dt));
}
return dtarr;
}
function disablePastDates(date) {
var pastDate = getPastDates(new Date('0001-01-01T00:00:00Z'), new Date());
if (date && compareDates(date, dates)) {
return true;
}
else {
return false;
}
}
function compareDates(date, dates) {
for (var i = 0; i < dates.length; i++) {
if (dates[i].getDate() == date.getDate() &&
dates[i].getMonth() == date.getMonth() &&
dates[i].getYear() == date.getYear()) {
return true;
}
}
}
</script>
Helper usage:
#(Html.Kendo().DatePicker().Name("AppointmentDate").DisableDates("disablePastDates"))
Working examples:
JSFiddle demo 1 (hidden past dates)
JSFiddle demo 2 (grayed-out past dates)
References:
Kendo.Mvc.UI.Fluent.DatePickerBuilderBase.Min(DateTime)
Show Out-of-Range Dates as Disabled
Kendo MVC DatePicker - Disable dates
Similar issue (with different approach):
How to disable past dates without hiding them in Kendo date picker?
if you use jquery for your kendoDatePicker , this code may help you!
$("#MyDatapickerElement").kendoDatePicker({
value: new Date(),
disableDates: function (date) {
if (date <= new Date()) {
return true;
} else {
return false;
}
}
});
If using Html.Kendo().DatePicker() you can show the disabled dates using the MonthTemplate. Example below shows the Minimum Date set to DateTime.Today and sets the MonthTemplate to show past dates as disabled.
Html.Kendo().DatePicker()
.Name("MyDate")
.Min(DateTime.Today)
.MonthTemplate(m=>m
.Empty("<div class=\"k-state-disabled\">#= data.value #</div>")
)
I have a spreadsheet for project data with time-sheet for each month logged against each project ID
I want to iterate through each sheet and if there is matching project ID , I want to sum up the number of hours logged for each project.
I have written the following code but keep getting the
TypeError: Cannot read property "0" from undefined. (line 31).
This is my sheet : https://goo.gl/rrsSxI
And this is my Code.
function TotalHours(TaskID) {
var a = SpreadsheetApp.getActiveSpreadsheet().getSheets().length;
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
var sum = 0;
// var fcol = 0;
for (var i = 1; i <= a; ++i) {
// var sheetname = sheets[i].getName();
//var cell = sheets[i].getActiveCell();
//Set active cell to A1 on each sheet to start looking from there
SpreadsheetApp.setActiveSheet(sheets[i])
//var sheet = sh.getActiveSheet();
var range = sheets[i].getRange("A1");
//* sheets[i].setActiveRange(range);
var data = sheets[i].getDataRange().getValues();
for (var row = 2; row <= data.length; ++row) {
if (data[row][0] == TaskID) {
for (var col = 2; col <= 31; ++col) {
sum += sheets[i].getRange(row, col).getValue();
}
}
}
}
return sum;
}
Can someone help me with what I am doing wrong.
I assume you want to exclude the sheet where the formula is going to be used ("Tracker" ?
See if this works ?
function TotalHours(TaskID) {
var sum = 0,
s = SpreadsheetApp.getActive(),
active = s.getActiveSheet().getName(),
sheets = s.getSheets();
for (var i = 0, slen = sheets.length; i < slen; i++) {
if(sheets[i].getName() != active) {
var sheetVal = sheets[i].getDataRange()
.getValues();
for (var j = 0, vlen = sheetVal.length; j < vlen; j++) {
if (sheetVal[j][0] == TaskID) {
for (var k = 2, rlen = sheetVal[j].length; k < rlen; k++) {
var c = sheetVal[j][k]
sum += c && !isNaN(parseFloat(c)) && isFinite(c)? c : 0; //check if cell holds a number
}
}
}
}
}
return sum;
}
I am making a game using Swift and SpriteKit where i move an object to random locations based on an array.
The array that is made up of CGPoints:
let easyArray = [CGPointMake(0,0), CGPointMake(126.6,0), CGPointMake(253.4,0), CGPointMake(0,197.5), CGPointMake(126.7,197.5), CGPointMake(253.4,197.5), CGPointMake(0,395), CGPointMake(126.7,395), CGPointMake(253.4,395)]
I use this function to generate a random number:
func randomNumber(maximum: UInt32) -> Int {
var randomNumber = arc4random_uniform(maximum)
while previousNumber == randomNumber {
randomNumber = arc4random_uniform(maximum)
}
previousNumber = randomNumber
return Int(randomNumber)
}
I used this to move the object based on the random number generated:
let greenEasy = randomNumberNew(9)
let moveSelector = SKAction.moveTo(easyArray[greenEasy], duration: 0)
selector.runAction(moveSelector)
I have done some reading online and found that the "While" condition should make it so that the same random number isn't generate twice in a row. But it still happens.
Can anyone please help me on how to make it so i don't get the same number twice in a row?
The code below doesn't random the same number.
var currentNo: UInt32 = 0
func randomNumber(maximum: UInt32) -> Int {
var randomNumber: UInt32
do {
randomNumber = (arc4random_uniform(maximum))
}while currentNo == randomNumber
currentNo = randomNumber
return Int(randomNumber)
}
I think Larme's suggestion is pretty clever, actually.
easyArray.append(easyArray.removeAtIndex(Int(arc4random_uniform(UInt32(easyArray.count)-1))))
selector.runAction(SKAction.moveTo(easyArray.last!, duration: 0))
I would recommend to not use while() loops with randomizers.
Theoretically it can cause infinite loops in worst case scenario, in more positive scenario it will just take few loops before you get desired results.
Instead I would advice to make an NSArray of all values, remove from this NSArray last randomized element and randomize any of other existing elements from such an array - that is guarantee result after only one randomize iteration.
It can be easily achieved by making NSArray category in Objective-C:
- (id) randomARC4Element
{
if(self.count > 0)
{
return [self objectAtIndex:[self randomIntBetweenMin:0 andMax:self.count-1]];
}
return nil;
}
- (int)randomIntBetweenMin:(int)minValue andMax:(int)maxValue
{
return (int)(minValue + [self randomFloat] * (maxValue - minValue));
}
- (float)randomFloat
{
return (float) arc4random() / UINT_MAX;
}
If you can use linq then you can select a random value that doesn't match the last value. Then for any left over values you can loop through and find valid places to insert them.
It's not the most efficient but it works.
public static List<int> Randomize(List<int> reps, int lastId) {
var rand = new Random();
var newReps = new List<int>();
var tempReps = new List<int>();
tempReps.AddRange(reps);
while (tempReps.Any(x => x != lastId)) {
var validReps = tempReps.FindAll(x => x != lastId);
var i = rand.Next(0, validReps.Count - 1);
newReps.Add(validReps[i]);
lastId = validReps[i];
tempReps.Remove(validReps[i]);
}
while (tempReps.Any()) {
var tempRep = tempReps.First();
bool placed = false;
for (int i = 0; i < newReps.Count; i++) {
if (newReps[i] == tempRep) {
continue;
}
else if ((i < newReps.Count - 1) && (newReps[i + 1] == tempRep)) {
continue;
}
else {
newReps.Insert(i + 1, tempRep);
placed = true;
break;
}
}
if (placed) {
tempReps.Remove(tempRep);
}
else {
throw new Exception("Unable to randomize reps");
}
}
return newReps;
}