0

The following Model has Required attributes for certain parameters:

   public class EModel
    {        
        [Required]
        [Display(Name = "Name")]
        public string Name { get; set; }

        [Required]
        [Display(Name = "Tel")]
        public string Phone { get; set; }

        public float Long { get; set; }
        public float Lat{ get; set; }
    }

In my Views, I have Name, Phone, and 2 float Parameters: longitude and latitude that I keep in a hidden input, they are set by a map marker to be saved later.

I am validating the required parameters like the following:

<div>
    @Html.EditorFor(model => model.Name, new { htmlAttributes = new { placeholder = "Name" } })
    @Html.ValidationMessageFor(model => model.Name, "", new { @class = "danger" })
</div>
<div>
    @Html.EditorFor(model => model.Phone, new { htmlAttributes = new { placeholder = "Phone" } })
    @Html.ValidationMessageFor(model => model.Phone, "", new { @class = "danger" })
</div>
<div>
    @Html.HiddenFor(x => x.Long, new { @id = "Long"})
    @Html.HiddenFor(x => x.Lat, new { @id = "Lat"})
</div>
<div>
    <button type="submit">Save</button>
</div>

I need to add a validation to the long and lat parameters, because I dont want the user to save without choosing a location first. so long and lat should not be lesser than 0.001, so I added the following attribute:

[Range(0.001, float.MaxValue)]
public float Long { get; set; }
[Range(0.001, float.MaxValue)]
public float Lat{ get; set; }

I want to validate on Submit click, the fact that Long and Lat are both not 0.00.

How can i do this? @Html.ValidationMessageFor(x=>x.Long) did not work.

HelpASisterOut
  • 3,085
  • 16
  • 45
  • 89
  • 1
    Why do you want to validate a field that cannot be set by user input? By default client validation will not work for hidden fields. Server side validation should still work though – ste-fu Nov 14 '16 at 15:16
  • @ste-fu I edited to explain more. the float value is set by a map marker. I dont want to let the user save without choosing a location first – HelpASisterOut Nov 14 '16 at 15:20
  • *I dont want to let the user save without choosing a location first*.. so you want to check if there is a value or not? or check if long & lat are < .001? – Grizzly Nov 14 '16 at 15:23
  • Did you see http://stackoverflow.com/questions/24572749/mvc-how-to-enable-client-side-validation-on-hidden-fields? – L-Four Nov 14 '16 at 15:23
  • @BviLLe_Kid value of long and lat is by default 0.00. I want to see if it changed – HelpASisterOut Nov 14 '16 at 15:29
  • Are you opposed to checking this via server-side? You can check that server-side and return an error message. – Grizzly Nov 14 '16 at 15:30
  • If the location is on the Greenwich Meridian then the latitude will be zero. If the location is on the equator then the longitude will be zero. It seems failing on zero values makes a significant number of locations unavailable. – Richard Nov 14 '16 at 15:45
  • @Richard Think you got that the wrong way round, but you make a valid point. There are valid inputs that would have lat or long of 0 (albeit a bit unlikely to select on using a pin on a map) – ste-fu Nov 14 '16 at 15:56
  • 1
    @ste-fu The change of me getting them the right way round should be 50%, but in practice is about 5% :-( . – Richard Nov 14 '16 at 16:20
  • @Richard I want to put a condition where both should be different than 0 for that reason – HelpASisterOut Nov 14 '16 at 16:34

3 Answers3

1

By default, the $.validator does not validate hidden inputs. You can override this behavior by adding the following script

$.validator.setDefaults({ 
    ignore: [] 
});

or if you want to validate just these 2 hidden inputs and ignore other hidden inputs, give these a class name (say new { @class = "coordinates" }) and use

$.validator.setDefaults({ 
    ignore: ':hidden:not('.coordinates')'
});

An alternative would be to generate the values as readonly textboxes which would also give extra feedback to the user

@Html.TextBoxFor(x => x.Long, new { @readonly = "readonly"})

Note that is is not necessary to use new { @id = "Long"}) - the HtmlHelper methods that generate form controls already adds an id attribute based on the name of the property.

However, your range validation does not really make sense since zero and negative values are valid for coordinates. If your wanting to ensure that the user has selected a location (and the values have been set via your script), then make the properties nullable and add a RequiredAttribute

[Required(ErrorMessage = "Please select a location")]
public float? Long { get; set; } // nullable
  • That's a great answer thanks. But on document load now by default the marker in the map is set on 0,0. If i make it nullable the map will take coordinates of null and the marker won't be set. Which is an issue. – HelpASisterOut Nov 15 '16 at 07:32
  • So your using the same property to set an initial value? (you did not show any of the script). You could always test for `null` and if so, set the initial lat/long to 0,0 –  Nov 15 '16 at 07:38
0

Given that Lat/Long can be negative as well as positive I would suggest populating a different field to indicate that a location has been selected:

public float Long { get; set; }
public float Lat{ get; set; }

[MinValue(1, "Please select a location")
public int LatLongCheck { get; set; }

Then in whatever code you use to set the Lat & Long, you can also set the value of LatLongCheck to 1 (or whatever).

Use whatever technique works for you in the link (as per L-Four's comment) MVC : How to enable client side validation on hidden fields to enable the client side validation.

You could also take a look at Foolproof Validation which has a [NotEqualTo] validation attribute which you could use instead of an alternative field. Finally you could consider displaying the Lat / Long values as readonly fields, which are validated by default.

Community
  • 1
  • 1
ste-fu
  • 6,879
  • 3
  • 27
  • 46
0

You can hide the longitude and latitude input with CSS

<div style="visibility: hidden;">
    @Html.EditorFor(model => model.Long, new { @id = "Long"})
    @Html.EditorFor(model => model.Lat, new { @id = "Lat"})
</div>
<div>
    @Html.ValidationMessageFor(model => model.Long)
    @Html.ValidationMessageFor(model => model.Lat)
</div>


And set it as required in your model
public class EModel
{        
    [Required]
    [Range(0.001, float.MaxValue)]
    [Display(Name = "Long")]
    public string Long { get; set; }

    [Required]
    [Range(0.001, float.MaxValue)]
    [Display(Name = "Lat")]
    public string Lat { get; set; }

}
Yanga
  • 2,885
  • 1
  • 29
  • 32