Create Day view calendar and display event in React - reactjs

I'm using React Native to create a Day view calendar like Google that display event time block.
I have an array that have many object with title, start time, end time and duration. For example:
[
{title: "Event A", startTime: "01:00:00", endTime: "02:00:00",duration: "60 min"},
{title: "Event B", startTime: "01:00:00", endTime: "03:00:00",duration: "120 min"},
{title: "Event C", startTime: "02:00:00", endTime: "04:00:00",duration: "120 min"},
{title: "Event D", startTime: "03:00:00", endTime: "04:00:00",duration: "60 min"},
]
And I want it to display event like this
Example calendar ( I draw it with GG sheet )
I have look through this library https://github.com/duyluonglc/ but it's last updated 3 years ago. So I clone that Repo and review the code. But his code really hard for me to understand the part that he calculated number of columns and expand the event time block width.
I understand that he using position absolute style to draw black line of hours, start time is for position for the block, duration and end time is for the height of block. But the part that he calculated to divide columns and width of many event block in the same hour this really complicated.
If anyone understand the algorithm or have better way to calculate it, please explain it clearly so I can understand how it display. Thank you.

Related

Sorting array by time and date using date-fns

I have an array with blog posts that I wanted sorted by newest entry. I'm able to map through the array just fine but I want the newest entry located at the very top of the page and right now it's going to the bottom. If I sort the array by time/date I know it will work but having issues getting it to sort.
const BlogTopic = [
{
title: "First Post",
message: "test",
author: "Dagger",
date: format(new Date(), "2/13 2:09a"),
},
{
title: "Second Post",
message: "test",
author: "Dagger",
date: format(new Date(), "2/13 3:48a"),
},
];
I'm also using a form to add new entries and it's saving all the above information and adding a new object at the end of the array. When it comes to adding a date I'm using this format.
date: format(new Date(), "M/dd h:mma"),
And this is my code for sorting the array.
const [topic, setTopic] = useState(BlogTopic);
{topic
.sort((a, b) => new Date(b.date) - new Date(a.date))
.map(({ title, author, date }, index) => (
<tr>
<td className="blog__topic">
{title}
</td>
<td>{author}</td>
<td>{date}</td>
</tr>
))}
UPDATE
Here is my full state. Any ideas for how I can change the 2/17 3:48a below so it automatically takes the current date and time?
const [title, setTitle] = useState();
const addTopic = (e) => {
e.preventDefault();
setTopic([
...topic,
{
title: title,
message,
author: "Dagger",
count: 1,
date: parse("2/17 3:48a", "M/dd h:mma", new Date()),
},
]);
setTitle("");
};
Ok, so, there are a few issues with your code. I'll try to fix them by reducing your code to the simplest form possible and work our way up to what you expect.
Let's start the simplification by taking a look at the dates in the array's objects. For the first object, you have format(new Date(), "2/13 2:09a"). Given that you stated that the format is M/dd h:mma, I can easily convert this date into an ISO one: 2023/02/13 02:09:00. The benefit of doing this is that this can be feed to new Date() very easily. If we apply those operations on both objects, we have the resulting array:
const BlogTopic = [
{
title: "First Post",
message: "test",
author: "Dagger",
date: new Date("2023/02/13 02:09:00"),
},
{
title: "Second Post",
message: "test",
author: "Dagger",
date: new Date("2023/02/13 03:48:00"),
},
];
Ok, so far so good. Now, let's move to the next bit: sorting. Since the dates are now as a Date object, sorting is trivial. In fact you already provided the code for sorting, you just needed to reverse the operands:
BlogTopic.sort((a, b) => b.date - a.date)
Please, note the following:
I kept the parameters order as you had them a, b
I reversed the substraction b - a instead of a - b
Since the date parameter is already a Date object, we don't need to wrap it again
Great! Now we have an array properly sorted. The next step is about displaying this. As you saw, if you try {new Date()}, React will complaint because you are trying to display an object. What we need to do, therefore, is to turn this object into some string representation before giving it to React. For now, we will keep it simple and use the toUTCString() method (this is just for the sole purpose of simplifying your code, keep reading for your expected solution). So, now, we can do the following (again, keep in mind I'm simplifying your code for the sake of explaining all this, I know there are other parameters like title and author);
BlogTopic.map(({ date }) => (
<tr><td>{date.toUTCString()}</td></tr>
)}
Very well! So far we have managed to have an array with dates, sort it and display it so, the final piece to the puzzle is to use the format you need. As you pointed out, we will use date-fns to assist us with this. Among many other methods, this library has the following 2 that we will be using:
format: Which takes a Date object and a pattern string and outputs an string with the date in the given format
parse: Which takes a string with the date, a pattern declaring which format your date currently is and a Date object to provide defaults
The good thing about those functions is that they use the same format for the pattern string... that's handy!
Let's focus on the data input, this is your array. What you want here is to turn a string with a date in it (f.e. "2/13 2:09a") into a Date object which means that, from those functions, you need parse. Let's rewrite the array with this function:
const BlogTopic = [
{
title: "First Post",
message: "test",
author: "Dagger",
date: parse("2/13 2:09a", "M/dd h:mma", new Date()),
},
{
title: "Second Post",
message: "test",
author: "Dagger",
date: parse("2/13 3:48a", "M/dd h:mma", new Date()),
},
];
The benefit here is that, because parse returns a Date object, any operations we do afterwards (like the sorting itself) can be kept as they are since we haven't changed the expected data type.
Finally, for displaying the date, we need a function that will take a Date object and turn it into a string, this is the job of the format function:
BlogTopic.map(({ date }) => (
<tr><td>{format(date, "M/dd h:mma")}</td></tr>
)}
And there you have it! If you have been following all along, you should now have a code that works the way you expected.

Can't filter or order by using relational-pouch plugin

Since last two days I have been trying to sort and/or filter documents in pouchdb using a plugin relational-pouch but its not working for some reason
I have read the docs from Pouch DB's official documentation and followed the steps, i.e, I created an index and then called the find('type',options) method with document type and options as given in the code below, but the results I get is ordered by id's, the tricky part is I can pass the "limit" option in the options and it works but on the same place "sort" option doesen't seems to work, also it would be help full if someone can point me to a place where I can find how to filter in relational-pouch, the official GitHub docs won't help
get() {
this.db.createIndex({
index: {
fields: ['title']
}
}).then((data)=>{
this.db.rel.find('content', {
limit : 1,
sort: ['title']
}).then((data)=>{console.log(data)});
}).catch(console.log)
}
// the schema applied
this.db.setSchema([
{singular: 'user', plural: 'users', relations: { contents: {hasMany: 'content'}}},
{singular: 'content', plural: 'contents', relations: { user: {belongsTo: 'user'}}}
]);
I am expecting results which are ordered by title(i even tried ordering by created), but I am getting the following:
{title: "Test title 5", description: "Test description 5", created: "2018-12-20T02:44:59.127Z", modified: "2018-12-20T02:44:59.127Z", id: "2A57FB9C-4E29-590C-AA4E-751FAA0F0AD9", …}
{title: "Test title 2", description: "Test description 2", created: "2018-12-19T03:40:56.302Z", modified: "2018-12-19T03:40:56.302Z", id: "2F568411-D955-42ED-9622-1C191AD6532D", …}
{title: "Test title 4", description: "Test description 4", created: "2018-12-20T02:44:51.654Z", modified: "2018-12-20T02:44:51.654Z", id: "319D2427-5862-477A-AAEA-CB2536C2430E", …}
{title: "Test title 1", description: "Test description 1", created: "2018-12-19T03:40:50.166Z", modified: "2018-12-19T03:40:50.166Z", id: "4D982FA6-99A9-4545-BC10-CBEF9530B3FA", …}
{title: "Test title 6", description: "Test description 6", created: "2018-12-20T02:45:06.927Z", modified: "2018-12-20T02:45:06.927Z", id: "7C4637AB-B626-E5FD-9353-5A7F926B98ED", …}
If you expect to retrieve large numbers of records, there is only one good way to do it: allDocs.
relational-pouch is intended for work on a small collection of records related to one, or at most a small few, individual records.
The two tools are quite compatible and, with some experimentation and planning, work very well together. I work on large datasets with allDocs, render lists in the browser with live-find and, when the end-user picks a single item, retrieve it's related records for display/alteration with db.rel.find(). In such a case sorting is not an issue at all.
In other words ... if you NEED sorting and filtering you probably ought to get a short list of primary (master) records first, and only then use their key properties in db.rel.find() to retrieve their secondary (supporting, related, detail) records.
To emphasize ... allDocs should be your main tool and your design decisions should focus on it, not on relational-pouch.
Update: 2018/12/23 16:00 est
If all you need to do is ensure your records are in date order, just ensure that your IDs are in date order...
{id: "Test_2_20181219034050166", title: "Test title 1", description: "Test description 1", created: "2018-12-19T03:40:50.166Z", modified: "2018-12-19T03:40:50.166Z", …}
Check out the reference to sorting in the comand db.rel.find(type). You generate such specialized IDs with the class method db.rel.makeDocID(parsedID).

how to change the date control in day pilot scheduler using in angularjs

Hi I'm new to day pilot scheduler,
I have referred this day pilot scheduler https://code.daypilot.org/54503/angularjs-timesheet-tutorial-javascript-php to use my time sheet.
here what I want is I want to select date depend upon sidebar calender.
Here I don't know how the current date is selected.
In timesheet I want to show only the selected week.
days: new DayPilot.Date().daysInMonth(),
startDate: new DayPilot.Date().firstDayOfMonth(),
I tried to understand the code but it is little bit difficult to me.
can any one tell me how to set the selected date depends upon side calender control.
Thanks
$scope.scheduler = {
viewType: "Days",
showNonBusiness: false,
businessBeginsHour: 9,
businessEndsHour: 17,
cellWidthSpec: "Auto",
scale: "CellDuration",
cellDuration: "15",
useEventBoxes: "Never",
days: 7,
startDate: (new DayPilot.Date().firstDayOfWeek())}
after using days:7
it return 7 days only
https://forums.daypilot.org/Topic.aspx/3974/daypilot-scheduler-end-date-set-as-current

amCharts convert unixtime to readable date

I want to show stacked area chart using amCharts, anything else worked as well but date on it was parsed incorrectly.
"dataProvider": [{
"date": 1482192000,
"cars": 1587,
"motorcycles": 650,
"bicycles": 121
}
Property named as date on above data package cannot be converted to readable date like "DD/MM/YYYY"
Finally, the chart must show 30 days of chosen month.
Here is my CodePen: CodePen Stacked Area Chart
Your data and setup are both incorrect. Here's a list of what's wrong and how to fix them
1) dataDateFormat is used for parsing string dates, not formatting them. Since you're using unix timestamps, you don't need this property at all, so you can remove it.
2) Your unix timestamps must also be in milliseconds in order for this to work. Seconds will give you invalid times.
3) Your data must be sorted in ascending date order for it to render correctly. Your data is currently in mixed order.
As for your other questions:
To format your dates, you have to set the dateFormats array in your categoryAxis to the desired format strings as described here. For DD/MM/YYYY:
"categoryAxis": {
// other properties omitted:
"dateFormats": [{period:'fff',format:'JJ:NN:SS'},
{period:'ss',format:'JJ:NN:SS'},
{period:'mm',format:'JJ:NN'},
{period:'hh',format:'JJ:NN'},
{period:'DD',format:'DD/MM/YYYY'}, //you may need to change the entries for 'WW' and 'MM' as well, depending on the amount of visible data
{period:'WW',format:'MMM DD'},
{period:'MM',format:'MMM'},
{period:'YYYY',format:'YYYY'}]
// ...
}
To automatically zoom on chart load, you can add a rendered event similar to how the demos on the AmCharts website does it and call any of the zoom methods, for example:
"listeners": [{
"event": "rendered",
"method": function(e) {
// different zoom methods can be used - zoomToIndexes, zoomToDates, zoomToCategoryValues
e.chart.zoomToDates(new Date(2017, 1, 1), new Date(2017, 1, 15));
}
}]
Here's an updated codepen with all of the aforementioned fixes here.

Evaluating google calendar "quick add" string instead of creating event

Google calendar supports "quick add" strings, such as adding "meeting with Peter tomorrow 15:00 in room 2".
Do anyone know of a way to evaluate the string without before a calendar entry? Something along the lines of the following example:
REQUEST:
action: "just_parse_don't_insert"
text: "Lunch tomorrow 15:00 in room 2"
RESPONSE:
text: "Lunch"
date: "05-03-2013"
location: "room 2"
I can understand why Google would not offer this functionality, so alternatively, I'm looking for services/scripts (preferably JS) that offers similar functionality.

Resources