MVC MultiSelect Control for Day of week - asp.net-mvc

I have a ASP.NET MVC 4 project with EF and I have a table Orders with a field ShipmentDay varchar(7)/string where I want to save in the database in witch days of the week the order can be shipped : 1000100 for Monday and Friday.
Right now I have a ListBox :
#Html.ListBoxFor(model => model.ShipmentDay, new MultiSelectList(ViewBag.ShipmentDay))
List<string> lbSDay = new List<string>();
ZileLiv.Add("Monday"); ...
public ActionResult Create()
{
ViewBag.lbSDay = lbSDay ;
return View();
}
Q: How can I make a custom multiselect control to select the days of week ?

I'd start out by getting rid of the varchar(7) and storing the shipment days in a single byte with the following weekday values...
private const byte MONDAY = 1;
private const byte TUESDAY = 2;
...
private const byte SUNDAY = 64;
Create a html helper extension method to build up a multiselect using those values
to give, e.g.
<select multiple>
<option value=1>Monday</option>
...
<option value=64>Sunday</option>
</select>
Calculate if the option should be selected using something like
bool checked = ((byte)(shipDays & MONDAY) == MONDAY);

Related

Can I Compare the day name with the date Entity Framework 6

I am working on news function. News model contains publishing date....
Is there a way to filter my record from db on the base of Publishing Date's day name such as in controller action:
var data1 = db.News.Where(x => x.PublishingDate >= DateTime.Now
&& x.PublishingDate.Day == (int)DayOfWeek.Sunday);
ViewBag.SundayNews = data1;
Or if there is another way around or any reference.
Try this solution: http://c-sharp-snippets.blogspot.ru/2011/12/getting-dayofweek-in-linq-to-entities.html
var firstSunday = new DateTime(1753, 1, 7);
var filtered = from e in dbContext.Entities
where EntityFunctions.DiffDays(firstSunday, e.SomeDate) % 7 == (int)DayOfWeek.Monday
select e;
firstSunday stores the minimal value for MS SQL DATETIME type.

ASP.NET MVC calculate week

I have a ASP.NET MVC 4 project with EF. In my (create) view I want to display beside an EditorFor for a date the week number of the current year.
I have a helper:
#model Helios.Models.tablename
#helper Week(DateTime dt)
{
CultureInfo ciCurr = CultureInfo.CurrentCulture;
int weekNum = ciCurr.Calendar.GetWeekOfYear(dt, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
#weekNum
}
...
<div class="editor-field">
#Html.TextBoxFor(model => model.date_birth, new {onchange="?"}) #Week(date_birth?)
</div>
I'm not sure if this can be acomplished in Razor, but I need to update the week number if I change the date
Q : How can I display the week no. beside the datepicker and update it if the date is changed ?
Here is a post on that deals with calculating the week number.
How can I calculate/find the week-number of a given date?
But it all depends on if you plan to set it on the server or if the client is to be able to change date. If the client can change the date then you would need javascript instead.
function(d) {
var day = d.getDay();
if(day == 0) day = 7;
d.setDate(d.getDate() + (4 - day));
var year = d.getFullYear();
var ZBDoCY = Math.floor((d.getTime() - new Date(year, 0, 1, -6)) / 86400000);
return 1 + Math.floor(ZBDoCY / 7);
}
From: http://jquery142.blogspot.se/2010/04/how-to-get-week-number-for-date-in.html

Multiple Dropdowns all need null value if value hasnt changed... Also Need selected value to be default

MVC 3 VB.NET razor. I have a view that has 4 dropdown boxes in it.. This is for setting up a staff member.. If that staff member is to work certain classes then that class will be set for each day. If he is not then the value needs to stay null. This is a edit view so it may have to be accessed multiple times and still keep the original selectlist values if none changed. The below is what I have right now that is working only on its face. The Old selected value is shown first. However this isnt being returned on the save... The only way that it will save correctly is if I select the value that was set in each box then click save. The next problem is that not all staff members will have classes to work on every one of the 4 days. So how do I set a value to null and keep it that way unless a class Is actually selected..
Dim _staff As confstaff = db.confstaffs.Single(Function(a) a.id = id)
ViewBag.role = _staff.Conf_Role.ToString
ViewBag.confRole = db.conf_roles.ToList
ViewData("tue_Class") = New SelectList(db.courses.ToList.Where(Function(r) r.course_day = "Tuesday").Select(Function(r) r.course_ref), New With {.value = _staff.tue_class})
ViewData("wed_Class") = New SelectList(db.courses.ToList.Where(Function(r) r.course_day = "Wednesday").Select(Function(r) r.course_ref), New With {.value = _staff.wed_class})
ViewData("thur_Class") = New SelectList(db.courses.ToList.Where(Function(r) r.course_day = "Thursday").Select(Function(r) r.course_ref), New With {.value = _staff.thur_class})
ViewData("fri_Class") = New SelectList(db.courses.ToList.Where(Function(r) r.course_day = "Friday").Select(Function(r) r.course_ref), New With {.value = _staff.fri_class})
Return View(_staff)
And the view is:
<label>Tuesday Class</label>
#Html.DropDownList("tue_class", "Select One")
<label class="small_spacing">Wednesday Class</label>
#Html.DropDownList("wed_class", "Select One")
<label class="small_spacing">Thursday Class</label>
#Html.DropDownList("thur_class", "Select One")
<label class="small_spacing">Friday Class</label>
#Html.DropDownList("fri_class", "Select One")
I already expect someone to point out that I should use a view model instead of viewbag but I dont see how a view model would be practical with there being over 100 different courses but I am open for ideas...
Any Ideas???????
if you look at your page source after the page is loaded you will see your top item set from your viewbag value has no value only text so when it is submitted it thinks you are submitting blank. I ran into this before.
What you need to do is to manually create each of your dropdown lists by iterating through the collection and setting the one that matches your viewbag item to selected, that way you can be sure a selected item has a selected value. I have some Razr code around here somewhere. Will update when I find it.
EDIT
<select name="Type1" id="Type1">
<option value=""></option>
#foreach (var name in ViewBag.BackOfficeTypes)
{
if (name == ViewBag.SelectedType1Value)
{
<option value="#name" selected="selected">#name</option>
}
else
{
<option value="#name">#name</option>
}
}
</select>
I have several of these on the same page building from different sets of items. Hope this helps.
EDIT 2
If you want to do it all from codebehind I am not a VB guy but here is a way to do it but you need to change your linq statement to manually create the list items instead of dumping from the toList Method.
var courses = db.getCourses();
IEnumerable<SelectListItem> selectList =
from c in courses
where c.course_day = "Tuesday"
select new SelectListItem
{
Selected = (c.CourseID == selectedCourseID),
Text = c.Name,
Value = c.CourseID.ToString()
};
If you can translate this into the VB equivalent it might solve your issue instead of building them in the Razor end.

How do I get only unique month and year combinations?

Using VBNET, MVC 3 and Entity Framework to write my first mvc application - a single user blog application. I am trying to create an archive sidebar that will render something like October 2011 and when the user clicks they will see all posts in october. Right now all my attempts show either duplicate dates - if there are 3 posts in october then i see october 2011 3 times or i only get back one month year combo say oct 2011.
Using groupby with firstordefault i only get back one month yaear combo.
posts = _rdsqlconn.Posts.Where(Function(p) p.PostIsPublished = True).GroupBy(Function(d) d.PostDatePublished).FirstOrDefault
How can i get back unique month year combos with EF?
Additional info
I have that function in my repository. I want to pull the month and year pairs so that i have only one pair for say ocotober even if there are 3 posts in october.
In the repository:
Public Function SelectPostsByDate() As IEnumerable(Of Entities.Post) Implements Interfaces.IPostRepository.SelectPostsByDate
Using _rdsqlconn As New RDSQLConn
Dim posts
posts = _rdsqlconn.Posts.Where(Function(p) p.PostIsPublished = True).GroupBy(Function(p) New With {p.PostDateCreated.Year, p.PostDateCreated.Month}).Select(Function(g) g.Key)
'posts = _rdsqlconn.Posts.Where(Function(p) p.PostIsPublished = True).GroupBy(Function(p) New With {p.PostDatePublished.Value.Year, p.PostDatePublished.Value.Month})
Return posts
End Using
End Function
In my controller i have
Function DateViewPartial() As PartialViewResult
Return PartialView(_postRepository.SelectPostsByDate)
End Function
My partial view has:
#ModelType IEnumerable (of RiderDesignMvcBlog.Core.Entities.Post)
<hr />
<ul style="list-style: none; margin-left:-35px;">
#For Each item In Model
#<li> #Html.ActionLink(item.PostDatePublished.Value.ToString("Y"), "Archives", "Blog", New With {.year = item.PostDatePublished.Value.Year, .month = item.PostDatePublished.Value.Month}, Nothing)</li>
Next
</ul>
In _Layout.vbhtml i call the partial view to render in the sidebar:
<h3>Posts by Date</h3>
#code
Html.RenderAction("DateViewPartial", "Blog")
End Code
I would try this (in C#):
var yearMonths = _rdsqlconn.Posts
.Where(p => p.PostIsPublished)
.GroupBy(p => new { p.PostDatePublished.Year, p.PostDatePublished.Month })
.Select(a => a.Key)
.ToList();
It gives you a list of anonymous objects. Each object has a Year and a Month property - for instance yearMonths[0].Year and yearMonths[0].Month, etc. By applying the Select you actually throw away the elements in each group and you get only a list of group keys (year and month).
Edit
I think, for your purpose the best way is to introduce a "ViewModel" for your sidebar partial view. The ViewModel would describe the year and month group, for instance:
public class ArchiveMonthViewModel
{
public int Year { get; set; }
public int Month { get; set; }
}
Then you don't group with an anonymous type but use this ViewModel type:
var archiveViewModels = _rdsqlconn.Posts
.Where(p => p.PostIsPublished)
.GroupBy(p => new ArchiveMonthViewModel
{
Year = p.PostDatePublished.Year,
Month = p.PostDatePublished.Month
})
.Select(a => a.Key)
.ToList();
archiveViewModels is now a named type: List<ArchiveMonthViewModel> which you can return from your method:
public IEnumerable<ArchiveMonthViewModel> SelectPostsByDate()
{
// code above ...
return archiveViewModels;
}
Now your partial view should be based on a model of type IEnumerable<ArchiveMonthViewModel> (and not IEnumerable<Post>). In your foreach loop (#For Each item In Model) you pull out the ArchiveMonthViewModel elements which are the item in the loop now and then create the action link using item.Year and item.Month.
(Hopefully you can translate this sketch into VB.)
In VB:
Dim groupedPosts = _rdsqlcon.Posts.
Where(Function(p) p.PostIsPublished = True).
GroupBy(Function(p) New With {p.PostDatePublished.Year, p.PostDatePublished.Month }).
Select(g => g.Key)
This just returns the unique Years and Months. If you want to include the Posts for each, try the following:
Dim groupedPosts = _rdsqlcon.Posts.
Where(Function(p) p.PostIsPublished = True).
GroupBy(Function(p) New With {p.PostDatePublished.Year, p.PostDatePublished.Month
From there, you can show the year/month groupings and the associated posts for each:
For Each group In groupedPosts
Console.WriteLine(group.Key.Year & "-" & group.Key.Month)
For Each post In group
Console.WriteLine(post.PostDatePublished)
Next
Next

Very odd event behaviour for onChange on Telerik MVC DatePicker

To the question started, my code (I'll try to only include relevant portions to start), starting with my script:
function RaceDate_onChange() {
var pickedDate = $(this).data('tDatePicker').value();
var month = pickedDate.getMonth() + 1;
$.get("/RaceCard/Details?year=" + pickedDate.getFullYear() + "&month=" + month + "&day=" + pickedDate.getDate());
}
Then my markup:
#Html.Telerik().DatePickerFor(model => model.RaceDate).ClientEvents(events => events.OnChange("RaceDate_onChange"))
And finally a bit of the receiving action:
[HttpGet]
public ActionResult Details(int year, int month, int day)
{
var viewModel = new RaceCardModel {Metadata = DetailModelMetadata.Display, RaceDate = new DateTime(year, month, day)};
I'm trying to get the selection of a new date to trigger a GET, to refresh the page without submitting a form. This works fine, except for this problem:
In GET requests to the Details action, the day value is always one day behind the DatePicker. E.g. The first value is set from a view model property, when the view is rendered, say 3. I then click on 14 and hit my breakpoint in the action method. The day value is 3. When I click on 29 and hit the breakpoint, the day value is 14.
Besides asking what is wrong, I'll take a liberty and ask if there is a better way that is no more complicated. I am fairly novice and would rather deliver working code that needs revision than get bogged down in tangents and details.
Try using e.value instead as shown in the client-side events example. You are probably using an older version where the value() method returned the previous value during the OnChange event.
UPDATE:
"e.value" means the value field of the OnChange arguments:
function onChange(e) {
var date = e.value; // instead of datePicker.value()
}
As far as the 1 month difference you are getting, that's normal, and it is how the getMonth() method works in javascript on a Date instance:
The value returned by getMonth is an
integer between 0 and 11. 0
corresponds to January, 1 to February,
and so on.
So adding +1 is the correct way to cope with the situation, exactly as you did.
Just a little remark about your AJAX call: never hardcode urls. Always use url helpers when dealing with urls:
var year = pickedDate.getFullYear();
var month = pickedDate.getMonth() + 1;
var day = pickedDate.getDate();
var url = '#Url.Action("Details", "RaceCard")';
$.get(url, { year: year, month: month, day: day }, function(result) {
// process the results of the AJAX call
});

Resources