Using Where on a page property - umbraco

My blogposts has the property WrittenDate (writtendate) DatePicker type. How could I use Where to filter the list to only contain blogpost where WrittenDate is set (not null?)
I've tried
var posts = CurrentPage.Children.Where(p => p.writtendate != null)
but this does not work and crashes the site :) How can I fetch a property and check if it is set (DatePicker in this example)?

The Umbraco DatePicker type returns a DateTime, which is not nullable.
Empty fields will return DateTime.MinValue, so to return content with the WrittenDate property set:
var posts = CurrentPage.Children.Where("writtendate != #0", DateTime.MinValue);
Note, that with a dynamic node, the razor parser doesn't allow you to use lambda syntax to filter objects.

Related

Define editor template that makes use of ModelState

Please help me to implement the editor template when Model and ModelState mismatch.
For example: Model.A == 'x', ViewData.ModelState['A'] == 'y'.
That can occur when form was posted invalid.
Native templates take this in account and display right value from the ModelState. But i could't find their sources.
I need to implement this in my own temlate. Should i just check for a present value in ModelState and use it if it is set. Or may you suggest a better way?
I had a look at the HtmlHelpers (editors) and came up with this. In the example the model/ value is an integer:
var value = Model; //value according to the model
var fieldName = ViewData.TemplateInfo.GetFullHtmlFieldName("");
ModelState modelState;
if(ViewData.ModelState.TryGetValue(fieldName, out modelState) && modelState.Value != null)
{
value = (int?) modelState.Value.ConvertTo(typeof(int?), null);
}
Now the value contains the model value or the posted ModelState value (the attemptedValue).

HTML Helper checking if the date is MinValue

Can I configure the HTML Helper to display String.Empty if my date is MinValue?
${Html.TextBoxFor(v=>v.Date)}
How can I do this?
Why don't you do it in your View?
Caution: Razor syntax
#if(v.Date != DateTime.MinValue)
{
Html.TextBoxFor(v => v.Date);
}
else {
//show whatever
}
There are a few similar questions like
Html.TextboxFor default value for Integer/Decimal to be Empty instead of 0
Display empty textbox using Html.TextBoxFor on a not-null property in an EF entity
If you have full control over the viewmodel, one option would be to make the date field nullable and have the accessor return null if the date is equal to DateTime.MinValue.
If you don't want to change your viewmodel, you can write your own html helper and put the logic to create an empty textbox there. That allows you to keep logic out of your view, where it's difficult to test.
Make your property nullable and it won't default to the min date. If that's a database field and you can't do that then you should create a ViewModel property that is and have it compare against the min value and return null in the get{}

How will model binder deals with Readonly & disabled

I have the following two items , one which is readonly:-
#Html.TextBoxFor(model => model.Technology.Tag, new
{ #readonly = "readonly" })
While the other is Disabled:-
#Html.DropDownListFor(model => model.Customer.NAME, ((IEnumerable<TMS.Models.AccountDefinition>)ViewBag.Customers).Select(option => new SelectListItem
{
Text = (option == null ? "None" : option.ORG_NAME),
Value = option.ORG_NAME.ToString(),
Selected = (Model != null) && (Model.Customer != null) & (option.ORG_NAME == Model.Customer.NAME)
}), "Choose...", new { disabled = "disabled" })
so will the asp.net mvc model binder bind the two items? , or it will ignore any read-only and any disabled fields ?
It will bind them, but as long as you have populated them with the correct data, that shouldn't matter. Also, you can have your code that maps these models to the entity, assuming you are using view models, just ignore the values in question. Assuming this is a standard HTTP Post from the form, HTTP will not post disabled or readonly fields, which means they will be null or the default value in the model, so you need to account for that.
If you want the binder to ignore these values, use TextBox and DropDownList and make sure they are not named the same as your properties. If you do not use 'For' you will need to add code in the view to set the values.
ReadOnly text fields get bound.
I've been trying to find a way around the unbound dropdownboxfor values. Here's what I came up with:
$('#xxx').change(function() {$(this).val(lastSel_xxx);});
var lastSel_xxx = $("#xxx option:selected").val();
Use the code above for each HTML element in your view (this will require you to document each ID output) and replace 'xxx' with the element name.
When a user selects another option besides the initial option selected, it reverts back to the original.
HOpe this helps!

Client-side validation for custom editor templates in MVC4

I have a viewModel that contains an object. I've defined a custom editor template for that object, which allows me to edit each of the children of that object. The children values aren't required serverside (so I don't have any Required annotations), however if the user reaches this particular input, it should be required.
Is there any way I can inspect the values of these children objects (within the viewModel) in the POST method, and return some errors to the view if they are null?
I'm using Razor.
On the server-side, you could check the child objects of the class in your action,
[HttpPost]
public ActionResult Edit(MyClass myClass)
{
if (myClass.Children.Any(child => child == null))
{
foreach(var child in myClass.Children
.Where(child => child == null)
.Select((item, index) => new { Item = item, Index = index))
{
ModelState.AddModelError(
string.Format("Children[{0}]", child.Index),
"Must be required");
}
return this.View("...");
}
}
What you can do is to write a function that will be check user input (on change in that field)
if the user reaches this particular input
and if user reaches that particular input you use jQuery to add #class = "required" HTML attribute to your object. From that moment on it will become required
Take a look here: this is jQuery validator for required field based on some condition. I think this is exactly what you're after
Edit
Your other option is to use AJAX to go back to server to verify what you're looking for. Example is here
Hope this makes sense and is of help to you.

Getting all selected checkboxes from a FormCollection

I have a form which contains a whole bunch of checkboxes and some other types of control too. I need to retrieve the names of each selected checkbox.
What is the best way to do this? Can I do it with a linq query maybe?
So in pseudocode, I'm looking to do something like this:
var names = formCollection
.Where(c => c is Checkbox && c.Checked)
.Select(c => c.Name);
Update It seems the way MVC submits checkboxes is different from how a normal form would behave, as an hidden field is also rendered. I found the details here: How to handle checkboxes in ASP.NET MVC forms?
Anywho, I've got it working with the help of that thread and the answer from BuildStarted below. The following code did the trick.
var additionalItems = form.AllKeys
.Where(k => form[k].Contains("true") && k.StartsWith("addItem"))
.Select(k => k.Substring(7));
Unfortunately that type of information isn't available in the collection. However if you prepend all your checkboxes with something like <input type='checkbox' name='checkbox_somevalue' /> then you can run a query like
var names = formCollection.AllKeys.Where(c => c.StartsWith("checkbox"));
Since only the checked values will be posted back you don't need to validate that they're checked.
Here's one that grabs only checked values
var names = formCollection.AllKeys.Where(c => c.StartsWith("test") &&
formCollection.GetValue(c) != null &&
formCollection.GetValue(c).AttemptedValue == "1");
This is one of the old questions not active for years but I stumbled on it. My problem was that I have an array of check boxes - let's say the name is 'IsValid' and wanted to get the status of each of the check boxes (my project was in MVC 5). On form submit i did the loop of form collection and got the values as...
if (key.Contains("IsValid"))
sV = (string[])collection.GetValue(key.ToString()).RawValue;
Since on form post the hidden field value was also posted with the checked check boxes; the array contained one additional value of 'false' for ONLY checked check box. To get rid of those i used following function; I hope that it helps somebody and if my approach is wrong then a better solution would be helpful to me as well!
sV = FixCheckBoxValue(sV);
private string[] FixCheckBoxValue(string[] sV)
{
var iArrayList = new List<string>(sV);
for (int i = 0; i < iArrayList.Count; i++)
{
if (iArrayList[i].ToString() == "true")
{
iArrayList.RemoveAt(i + 1);
}
}
return iArrayList.ToArray();
}
Answering the post about the array of checkboxes, you could initially filter out the checkboxes by name.
var keys = formCollection.AllKeys.Where(x => x.StartsWith("IsValid");
Then you could just loop through them as a collection.

Resources