Calendar Control/Event Display alternative for Umbraco 7?
I'm looking for a calendar control alternative to the asp:Calendar method I used to use with Umbraco 6 Webforms. I learned that MVC doesn't allow these sorts of controls, but I'm hoping there's some alternative out there that will give me what I need in my layout:
Rendering on the frontend of the site, it would be two-columns, with a calendar visual control on one side and a list of events entered into Umbraco on the other. Visitors to the site would be able to select days, weeks, or whole months in the present or future and the event display would change accordingly.
I do not want an Umbraco package or plugin, only tips on the best way to accomplish this. I'd prefer to make it as self-contained as possible and limit my use of external code files, to prevent any problems that might occur without complete control over the code.
That just looks like an Agenda version of the events being inside the calendar.
I need the calendar visible and the list of events visible at the same time, as separate things, while being able to use the calendar to sort the events. I used to do it with a Calendar Control fairly easily with Webforms.
From our discussion on Twitter, what you are after is some sort of filter control on the front end of your site. For example has a "Start date" and "End date" input fields where the visitor can select the dates for the start and end and then submit them.
This then filters your list of events shown to the visitor.
There are 2 elements to this, 1) the form and 2) the filtering.
And there are different options as well.
First option is that you could load all future events and then use JavaScript to filter them on the front end of the site (this would have no requests being posted back to the server for each filter).
Second option is that you could post the form back to the server and get the page to refresh showing new data.
Third option is a combination of options 1 and 2 where you use an Ajax javascript request to submit the filter critiera to the server and then get the updated list and replace the existing list.
Going back to the form side of things, it would be useful to know what sort of front end styling you want to have as this can heavily influence how you create your Date pickers. For example, for a proof of concept could be to have two text inputs and a button to make your form. Then later, you could look at using something like https://jqueryui.com/datepicker/ or https://eonasdan.github.io/bootstrap-datetimepicker/ to style your input into calendar pickers. These plugins (yes I know you want to avoid plugins where you can) are not dependent on Umbraco, they are front end only plugins and to be honest, that is the easiest way to style the front end in my honest opinion.
From the Umbraco side of things, you'll want to start by creating a surface controller, this would have an action on it that returns a partial view that is your form.
eg:
public class EventFilterController : SurfaceController
{
[ChildActionOnly]
public ActionResult FilterForm()
{
//--- might need some code here to populate a view model --//
// Ensure you a file called EventFilterForm.cshtml exists in the /views/partials/ directory.
return PartialView("EventFilterForm");
}
}
In the view this returns you'd have some HTML for rendering your form, maybe something like this:
I should probably state that my experience with MVC is less than a month old, so I'm starting off pretty lost already.
To clarify: I would have three separate files, one inheriting my UmbracoTemplatePage (i.e., it's the skeleton setup of every page on the site), one inheriting SurfaceController, and then the UmbracoViewPage? Is there a standard organization people use with these setups I should implement, or is it just a matter of shoving all the Partials into sub-folders for my own purposes?
I think what might help would be if I could knock up a demo site for you. I'll see if I can do that for you tonight into a GitHub repository.
I can then give you the link to it and you can clone it :-).
I'll try and follow a reasonable best practice (although there are differing views on the best way to approach things) which should give you a reasonable view on how to think about structuring your site.
It won't be a complete site at this stage and we can work together to build up the functionality relating to this question to help with your understanding.
Something to remember though, Umbraco, although MVC, isn't 100% MVC in the .Net sense. The reason I say that is that Umbraco runs it's own routing in the MVC pipeline so it's behaviour is slightly different to if you were googling ASP.Net MVC. The basic principles are the same however. Just keep that in mind when you are reading advise off of the internet :-)
Directly in regards to your response, this would be the setup I would have:
UmbracoTemplatePage (call it layout for example) would exist in the "Views" folder, however you'd create this in the Umbraco back office, under the "settings" section. You should see a node called "Templates", these are your template files for pages and for your "master" layout.
Then you would create a partial view (call it EventFilterForm for example) under the "Partial Views" folder, this could be created either via the Umbraco back office, or via Visual Studio but should exist in the Partials folder located under the Views folder (when looking at disk structure). You can create additional sub folders if you want to help organising your files.
Finally, the surface controller file will be a .cs file. I would create this in a folder called "controllers" on your disk.
Basically you should end up with a file structure that looks something like this (note, various files missing from example)
/src/MyProjectFolder/App_Data
/src/MyProjectFolder/Views
/src/MyProjectFolder/Views/layout.cshtml (this is your template file, bit like a master file in WebForms)
/src/MyProjectFolder/Views/Partials
/src/MyProjectFolder/Views/Partials/EventFilterForm.cshtml (the partial view for this form)
/src/MyProjectFolder/Controllers
/src/MyProjectFolder/Controllers/EventFilterController.cs
Terrific! This is super helpful. I've been confused about the best way to organize things from the start, and this is definitely the most straightforward answer I've gotten.
I would also seriously appreciate an example setup/demo site. I think that would help me visualize things significantly better.
Hopefully you should have no issues cloning it down to your local machine.
At the minute, I've created a few empty shell elements starting with a master layout file, a Home Page document type (with no properties) and associated template, and a dummy partial view.
Assuming it pulls down correctly to your machine you should find that when you run it you get a white page with a few lines of text showing. Those lines of text tell you where they come from so you can log into Umbraco and have a look and see them.
One thing to note, when creating templates and partials via Umbraco they don't automatically get added to the Visual Studio project so you just need to be aware that you have to tell Visual Studio to include them (assuming you are using visual studio).
Okay so if you create a Partial View or a Template via the Umbraco back office it does pre-populate the file with some boiler plate code. It is good practice to change this boilerplate code slightly though.
1) First thing is to update the @inherts statement. If the statement reads @inherits UmbracoTemplatePage you should change it to @inherits UmbracoViewPage. The reason for this change is predominantly to prevent accidental use of dynamics as they are being depreciated in the future. They have some performance issues (I believe) and it's much nicer to use typed models.
2) If you are editing a template for a page, update the Master Template property (if in the back office) or update the actual file to change the Layout = line from Layout = null to Layout = Layout (or what ever the name of your template file is. If you make this change in the back office using the Master Template property it will automatically update the Layout = line in the file it self.
Okay, so this evening I've updated the training site. The changes have been pushed to a new branch called "Creating-Events". If you pull that branch down you should see the site is slightly different.
I've added 2 new document types, an Events document type which is to be used as a repository and an Event document type to represent the event.
I've also create the C# cs file in a Controllers folder called EventFilterController. This is where the MVC style behaviour starts to kick in.
MVC, if you are unaware (I apologise if you are), stands for "Model", "View", "Controller", which are the parts that make up the paradigm.
Essentially, what will happen is during the rendering of a page, we will call a method (action) on the controller which will return a partial view.
Pull down the branch and let me know if it is still continuing to make sense.
I think I have everything so far, but just so I know where all the dots are connecting -- in this segment:
@Html.Action("FilterForm", "EventFilter")
I can see that the "FilterForm" is calling the ActionResult within the Controller, but where is "EventFilter" coming in? Is that going to be the partial?
Okay, so you see how the Controller is called EventFilterController in the EventFilterController.cs file? That is part of the naming convention for .Net MVC Controllers. You have (I believe), to call them somethingController in our case EventFilterController. When the .Net MVC kicks in, it maps the route to your controller by removing the Controller part of the name.
The @Html.Action method, in this instance, takes 2 parameters. The first is the name of the Action (method) on our controller, and the second is the name of the controller. This tells it which controller to call and which action on that controller to call.
The name of the partial view is defined in the FilterForm action on the EventFilterController. If you look at the return statement, that is where we are defining what view it should render.
Something to be aware of, a partial view is a very small section of a larger view. You can use multiple partial views to build up your overall page.
So we have:
Layout.cshtml
+ homepage.cshtml + [ MyExamplePartial.cshtml and EventFilterForm.cshtml ]
These are all the views and partial views that are, at this stage, making up our page.
So to help your understanding, it would be worth you trying to create your own action on the surface controller which returns your own partial view and then updating the home page template to also call your action.
I managed to make the edits on my local site. Another question arose while I was working, though: what is "[ChildActionOnly]" for, and will that be necessary whenever I make controllers?
In regards to do you need to use it, no not at all. If you are creating actions that are called via Javascript for example, you wouldn't put this attribute on them as it would result in an error.
It covers creating a form and submitting it back to the surface controller. Which is essentially something we are going to be wanting to do when we submit your date filters for your events.
Have a read of that to start with, and then try and work through it. If you have any questions just shout :-)
That's no problem. How are you getting on with the concept of Models and Forms etc? Once you've got that sussed we can start looking at the idea of a form submission that filters some results for you :-)
I think I've got it. I've managed to make something work on my local site, so I think I'm ready for actual form submission actions.
EDIT: I do have a general MVC organization question, though. What's the standard policy on combining actions within one file? Like, if I have to have multiple variations of a form, plus this calendar controller, would I have to create around three files (ViewModel, Controller, .cshtml Partial) for each? Or could I have, say, SiteWideController.cs with different namespaces or classes for each action?
Sorry if it's a silly question. I'm just not used to having so many moving parts for one thing -- a Webforms form, for example, would generally just be a Usercontrol with connected codebehind and if you wanted to do fancy things with the submitted data, you might have to throw in a .cs file that would connect some way.
I've successfully made a functioning contact form on my site (it sends to the database rather than via email, since I haven't figured out the SMTP deal yet), so as far as that's concerned, I have the Model/Form relationship down.
I'm just not making much progress on figuring out how to filter through things for the Calendar controller. Especially since I have to implement an external calendar display, regardless of what method I use.
I settled on a jquery UI calendar display, but I'm not totally happy with what it offers and it seems to just add another element of confusion.
Nice work on getting that far. The reason for you to do that was for you to understand how to submit data to a controller because this essentially will allow you to post requests to the controller and get back your filtered results.
I'm away at the minute, but when I get back in a few days time I'll add a new branch to the example site with an example of doing what you are trying to achieve which you can then pull down and explore.
I'm the mean time, I would suggest you look into some from end bits such as how best to style in an input as a date picker. Maybe try the jqueryui date picker control or something as there isn't a fully supported date picker html element yet.
I've been messing around with the jqueryui date picker a bit. It looks like there are some styling limitations for it, like I'm not entirely sure I'll be able to select a full week as the start/end points for the filter, and I don't know if I'd be able to change a day's styling based off whether or not that day contains events.
I guess I'm giving up on this. I just can't get it to work or wrap my brain around making it work, and there's nothing online that does exactly what I want. The jQueryUI is the closest I've gotten, but I don't know enough to send data from the calendar to the control or vice-versa. I'm just not good enough at MVC.
Really sorry it's taken me so long but I've knocked up a very "rough and ready" example of having some date based filtering on events.
If you pull down the Create-Events branch of the git repo I created previously it's been updated with an example.
It's using two inputs of type DateTime (first is the start date and second is end date) and it then submits and filters your results.
Currently I've only put in 3 example events which are on the following dates:
14/3 - 21/3 - 28/3
:-)
Hope it helps :-)
But yes, MVC removed some of the convenience that ASP.Net WebForms had but it gives you a lot more flexibility once you get your head around the approach :-)
Calendar Control/Event Display alternative for Umbraco 7?
I'm looking for a calendar control alternative to the asp:Calendar method I used to use with Umbraco 6 Webforms. I learned that MVC doesn't allow these sorts of controls, but I'm hoping there's some alternative out there that will give me what I need in my layout:
Rendering on the frontend of the site, it would be two-columns, with a calendar visual control on one side and a list of events entered into Umbraco on the other. Visitors to the site would be able to select days, weeks, or whole months in the present or future and the event display would change accordingly.
I do not want an Umbraco package or plugin, only tips on the best way to accomplish this. I'd prefer to make it as self-contained as possible and limit my use of external code files, to prevent any problems that might occur without complete control over the code.
Why not use something like this? The events can be populated by a JSON feed you could create of your umbraco events easily: https://fullcalendar.io/
I saw this, but I couldn't find any way to make the calendar and events separate columns. I don't want the events to be inside the calendar.
You could try this view, you could also just output the list in razor like any other list: https://fullcalendar.io/releases/fullcalendar/3.10.0/demos/list-views.html
That just looks like an Agenda version of the events being inside the calendar.
I need the calendar visible and the list of events visible at the same time, as separate things, while being able to use the calendar to sort the events. I used to do it with a Calendar Control fairly easily with Webforms.
Hi Mizzle,
Are you using any front end framework for your CSS/JS, such as BootStrap?
Thanks
Nik
Hi Nik. I'm not currently using anything.
Okay, so HTML has an input type of Date or of Time however, looking at CanIUse.com it has limited support https://caniuse.com/#feat=input-datetime
From our discussion on Twitter, what you are after is some sort of filter control on the front end of your site. For example has a "Start date" and "End date" input fields where the visitor can select the dates for the start and end and then submit them.
This then filters your list of events shown to the visitor.
There are 2 elements to this, 1) the form and 2) the filtering.
And there are different options as well.
First option is that you could load all future events and then use JavaScript to filter them on the front end of the site (this would have no requests being posted back to the server for each filter).
Second option is that you could post the form back to the server and get the page to refresh showing new data.
Third option is a combination of options 1 and 2 where you use an Ajax javascript request to submit the filter critiera to the server and then get the updated list and replace the existing list.
Going back to the form side of things, it would be useful to know what sort of front end styling you want to have as this can heavily influence how you create your Date pickers. For example, for a proof of concept could be to have two text inputs and a button to make your form. Then later, you could look at using something like https://jqueryui.com/datepicker/ or https://eonasdan.github.io/bootstrap-datetimepicker/ to style your input into calendar pickers. These plugins (yes I know you want to avoid plugins where you can) are not dependent on Umbraco, they are front end only plugins and to be honest, that is the easiest way to style the front end in my honest opinion.
From the Umbraco side of things, you'll want to start by creating a surface controller, this would have an action on it that returns a partial view that is your form.
eg:
In the view this returns you'd have some HTML for rendering your form, maybe something like this:
This would be your starting point for getting a form to render.
Does this make sense so far?
Please note, I've not included all the name spaces you will need and there may be typo's in my code above :-)
Nik
Thank you for the breakdown, Nik!
I should probably state that my experience with MVC is less than a month old, so I'm starting off pretty lost already.
To clarify: I would have three separate files, one inheriting my UmbracoTemplatePage (i.e., it's the skeleton setup of every page on the site), one inheriting SurfaceController, and then the UmbracoViewPage? Is there a standard organization people use with these setups I should implement, or is it just a matter of shoving all the Partials into sub-folders for my own purposes?
Hi Mizzle,
I think what might help would be if I could knock up a demo site for you. I'll see if I can do that for you tonight into a GitHub repository.
I can then give you the link to it and you can clone it :-).
I'll try and follow a reasonable best practice (although there are differing views on the best way to approach things) which should give you a reasonable view on how to think about structuring your site.
It won't be a complete site at this stage and we can work together to build up the functionality relating to this question to help with your understanding.
Something to remember though, Umbraco, although MVC, isn't 100% MVC in the .Net sense. The reason I say that is that Umbraco runs it's own routing in the MVC pipeline so it's behaviour is slightly different to if you were googling ASP.Net MVC. The basic principles are the same however. Just keep that in mind when you are reading advise off of the internet :-)
Directly in regards to your response, this would be the setup I would have:
UmbracoTemplatePage (call it layout for example) would exist in the "Views" folder, however you'd create this in the Umbraco back office, under the "settings" section. You should see a node called "Templates", these are your template files for pages and for your "master" layout.
Then you would create a partial view (call it EventFilterForm for example) under the "Partial Views" folder, this could be created either via the Umbraco back office, or via Visual Studio but should exist in the Partials folder located under the Views folder (when looking at disk structure). You can create additional sub folders if you want to help organising your files.
Finally, the surface controller file will be a .cs file. I would create this in a folder called "controllers" on your disk.
Basically you should end up with a file structure that looks something like this (note, various files missing from example)
Make sense?
Nik
Terrific! This is super helpful. I've been confused about the best way to organize things from the start, and this is definitely the most straightforward answer I've gotten.
I would also seriously appreciate an example setup/demo site. I think that would help me visualize things significantly better.
Thank you so much!
That's no worries, I'll try and knock something up for you tonight.
Thanks
Nik
Hi Mizzle,
I've started knocking up a test site. The git repository can be found here: https://github.com/NikRimington/UmbracoTrainingSite
Hopefully you should have no issues cloning it down to your local machine.
At the minute, I've created a few empty shell elements starting with a master layout file, a Home Page document type (with no properties) and associated template, and a dummy partial view.
Assuming it pulls down correctly to your machine you should find that when you run it you get a white page with a few lines of text showing. Those lines of text tell you where they come from so you can log into Umbraco and have a look and see them.
One thing to note, when creating templates and partials via Umbraco they don't automatically get added to the Visual Studio project so you just need to be aware that you have to tell Visual Studio to include them (assuming you are using visual studio).
Nik
Hi Nik,
It looks like everything pulled down correctly.
Thanks again.
That's great,
Okay so if you create a Partial View or a Template via the Umbraco back office it does pre-populate the file with some boiler plate code. It is good practice to change this boilerplate code slightly though.
1) First thing is to update the
@inherts
statement. If the statement reads@inherits UmbracoTemplatePage
you should change it to@inherits UmbracoViewPage
. The reason for this change is predominantly to prevent accidental use of dynamics as they are being depreciated in the future. They have some performance issues (I believe) and it's much nicer to use typed models.2) If you are editing a template for a page, update the Master Template property (if in the back office) or update the actual file to change the
Layout =
line fromLayout = null
toLayout = Layout
(or what ever the name of your template file is. If you make this change in the back office using the Master Template property it will automatically update theLayout =
line in the file it self.Make sense so far?
Nik
With you so far, Nik.
That's good to know.
Okay, so this evening I've updated the training site. The changes have been pushed to a new branch called "Creating-Events". If you pull that branch down you should see the site is slightly different.
I've added 2 new document types, an Events document type which is to be used as a repository and an Event document type to represent the event.
I've also create the C# cs file in a Controllers folder called EventFilterController. This is where the MVC style behaviour starts to kick in.
MVC, if you are unaware (I apologise if you are), stands for "Model", "View", "Controller", which are the parts that make up the paradigm.
Essentially, what will happen is during the rendering of a page, we will call a method (action) on the controller which will return a partial view.
Pull down the branch and let me know if it is still continuing to make sense.
Nik
Hi Nik,
I think I have everything so far, but just so I know where all the dots are connecting -- in this segment:
I can see that the "FilterForm" is calling the ActionResult within the Controller, but where is "EventFilter" coming in? Is that going to be the partial?
Thanks!
Hi Mizzle,
Always best to ask.
Okay, so you see how the Controller is called EventFilterController in the EventFilterController.cs file? That is part of the naming convention for .Net MVC Controllers. You have (I believe), to call them
somethingController
in our caseEventFilterController
. When the .Net MVC kicks in, it maps the route to your controller by removing theController
part of the name.The
@Html.Action
method, in this instance, takes 2 parameters. The first is the name of the Action (method) on our controller, and the second is the name of the controller. This tells it which controller to call and which action on that controller to call.The name of the partial view is defined in the FilterForm action on the EventFilterController. If you look at the return statement, that is where we are defining what view it should render.
Something to be aware of, a partial view is a very small section of a larger view. You can use multiple partial views to build up your overall page.
So we have:
Layout.cshtml + homepage.cshtml + [ MyExamplePartial.cshtml and EventFilterForm.cshtml ]
These are all the views and partial views that are, at this stage, making up our page.
Does that clarify it a bit?
Nik
Oh, that clarifies things a lot!
Excellent, really pleased to hear that.
So to help your understanding, it would be worth you trying to create your own action on the surface controller which returns your own partial view and then updating the home page template to also call your action.
Just to help cement the understanding :-)
Nik
Hi Nik,
I managed to make the edits on my local site. Another question arose while I was working, though: what is "[ChildActionOnly]" for, and will that be necessary whenever I make controllers?
Hi Mizzle,
Rather than me try and explain the ChildActionOnly attribute I thought I'd link here as the explanation is pretty good. https://stackoverflow.com/questions/10253769/using-childactiononly-in-mvc
In regards to do you need to use it, no not at all. If you are creating actions that are called via Javascript for example, you wouldn't put this attribute on them as it would result in an error.
Thanks
Nik
Okay, that helps.
Hi Mizzle,
So I've been thinking about what would be a good next step for you to help with your learning, rather than me giving you the next batch of code.
Although slightly off topic, I think it could be worth you following this tutorial:
https://our.umbraco.com/documentation/reference/templating/mvc/forms
It covers creating a form and submitting it back to the surface controller. Which is essentially something we are going to be wanting to do when we submit your date filters for your events.
Have a read of that to start with, and then try and work through it. If you have any questions just shout :-)
Nik
[Edited previous confusion out.]
Thanks for another push in the right direction, Nik!
That's no problem. How are you getting on with the concept of Models and Forms etc? Once you've got that sussed we can start looking at the idea of a form submission that filters some results for you :-)
Nik
I think I've got it. I've managed to make something work on my local site, so I think I'm ready for actual form submission actions.
EDIT: I do have a general MVC organization question, though. What's the standard policy on combining actions within one file? Like, if I have to have multiple variations of a form, plus this calendar controller, would I have to create around three files (ViewModel, Controller, .cshtml Partial) for each? Or could I have, say, SiteWideController.cs with different namespaces or classes for each action?
Sorry if it's a silly question. I'm just not used to having so many moving parts for one thing -- a Webforms form, for example, would generally just be a Usercontrol with connected codebehind and if you wanted to do fancy things with the submitted data, you might have to throw in a .cs file that would connect some way.
I've successfully made a functioning contact form on my site (it sends to the database rather than via email, since I haven't figured out the SMTP deal yet), so as far as that's concerned, I have the Model/Form relationship down.
I'm just not making much progress on figuring out how to filter through things for the Calendar controller. Especially since I have to implement an external calendar display, regardless of what method I use.
I settled on a jquery UI calendar display, but I'm not totally happy with what it offers and it seems to just add another element of confusion.
Hi Mizzle,
Nice work on getting that far. The reason for you to do that was for you to understand how to submit data to a controller because this essentially will allow you to post requests to the controller and get back your filtered results.
I'm away at the minute, but when I get back in a few days time I'll add a new branch to the example site with an example of doing what you are trying to achieve which you can then pull down and explore.
I'm the mean time, I would suggest you look into some from end bits such as how best to style in an input as a date picker. Maybe try the jqueryui date picker control or something as there isn't a fully supported date picker html element yet.
Thanks
Nik
Alright, thank you.
I've been messing around with the jqueryui date picker a bit. It looks like there are some styling limitations for it, like I'm not entirely sure I'll be able to select a full week as the start/end points for the filter, and I don't know if I'd be able to change a day's styling based off whether or not that day contains events.
I guess I'm giving up on this. I just can't get it to work or wrap my brain around making it work, and there's nothing online that does exactly what I want. The jQueryUI is the closest I've gotten, but I don't know enough to send data from the calendar to the control or vice-versa. I'm just not good enough at MVC.
Conclusion: I miss the asp:Calendar control.
Hey Mizzle,
Really sorry it's taken me so long but I've knocked up a very "rough and ready" example of having some date based filtering on events.
If you pull down the Create-Events branch of the git repo I created previously it's been updated with an example.
It's using two inputs of type DateTime (first is the start date and second is end date) and it then submits and filters your results.
Currently I've only put in 3 example events which are on the following dates:
14/3 - 21/3 - 28/3
:-)
Hope it helps :-)
But yes, MVC removed some of the convenience that ASP.Net WebForms had but it gives you a lot more flexibility once you get your head around the approach :-)
is working on a reply...