How to clear textboxes besides using JS - javascript

I am building an app using MVC, and this question pertains to the Create page and action.
Lets say my model has 2 decimal properties along with other properties but aren't necessary for this example:
public class TestClass
{
public int ID { get; set; }
public decimal DecimalProperty { get; set; }
public decimal SecondDecimalProperty { get; set; }
// more properties below this, but deemed unnecessary for this question
}
Obviously these properties are non-nullable, so in my Create View they appear as so on page load (ignore the 2nd textbox):
Now my goal is to clear those textboxes out, so they are just blank.. so I used JS to achieve that by doing:
$(".clear-textbox").val("");
I put a class called clear-textbox on those input fields.. works perfectly.. but now in my HttpPost Create Action I have conditional statements checking to see if other fields are valid, and if not return the object.. like so:
if (object.property== 0)
{
ModelState.AddModelError("property", "This field is required!");
return View(object);
}
This results in the Create view to be redisplayed with the values that the user has already entered, along with an error message below the one property that needs to be changed.. and this is where the problem lies. Once the Create view is reloaded.. then so are the scripts for clear-textbox, resulting in DecimalProperty and SecondDecimalProperty to be empty text-boxes.. instead of keeping what the user originally entered for them.
So my question, is there another way to clear out textboxes for decimal properties other than using javascript?
Any help is appreciated.
UPDATE
Here is the cshtml.
<div class="form-group">
#Html.LabelFor(model => model.DecimalProperty, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
#Html.EditorFor(model => model.DecimalProperty, new { htmlAttributes = new { #class = "form-control clear-textbox" } })
#Html.ValidationMessageFor(model => model.DecimalProperty, "", new { #class = "text-danger" })
</div>
</div>

Either you have to do it via Javascript on load like following
$(".clear-textbox").each(function(){
if($(this).val() <= 0 )
$(this).val("");
});
OR
You can create your own MVC Html Helper which will do things as you need for your special needs. Let me know if you want code for that...
You can also refer this link

You can set the default value as a data- attribute of the textbox and clear it only if they match. Like:
$(".clear-textbox").each(function(){
var $this = $(this);
if( $this.val() == $this.data().defaultvalue ) $this.val('');
});

It's hard to come up with an answer without knowing how the text boxes are being rendered. However, I'm assuming you are using something like
#Html.TextBoxFor
or
#Html.EditorFor
There are two ways to do this.
1. Add a DisplayFormat attribute to the model fields and use EditorFor:
public class TestClass
{
public int ID { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:#.#}")]
public decimal DecimalProperty { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:#.#}")]
public decimal SecondDecimalProperty { get; set; }
}
#Html.EditorFor(model => model.DecimalProperty)
2. Use the inline format attribute:
#Html.TextBoxFor(model => model.DecimalProperty, "{0:#.#}")

Related

Changing font colour conditionally in MVC

I'm new to MVC and still learning the best way to go about things.
My problem is I want to change a font colour conditionally. For example, if something gets deleted. I want the font colour of the item to change to red.
For reference I will add the relevant data to this question below.
VIEW (What I want to be changed to red when deleted)
<div class="well text-center">
<h1><b>Purchase Order #Html.DisplayFor(model => model.OrderID)</b></h1>
</div>
Controller
public ActionResult DeleteConfirmed(int id)
{
PurchaseOrder purchaseOrder = db.PurchaseOrders.Find(id);
purchaseOrder.deleted = !purchaseOrder.deleted;
db.SaveChanges();
db.Entry(purchaseOrder).Reference("Supplier").Load();
if (purchaseOrder.deleted)
{
TempData["message"] = string.Format("Purchase Order - {0} has been deleted\nCompany: {1}\nExpected Date:{2}\nNotes:{3}\n\nLink: {4}/PurchaseOrders/Details/{5}", purchaseOrder.ID, purchaseOrder.Supplier.Company, purchaseOrder.DeliveryDate, purchaseOrder.Details, IGT.baseUrl, purchaseOrder.ID);
}
else
{
TempData["message"] = string.Format("Purchase Order - {0} has been undeleted\nCompany: {1}\nExpected Date:{2}\nNotes:{3}\n\nLink: {4}/PurchaseOrders/Details/{5}", purchaseOrder.ID, purchaseOrder.Supplier.Company, purchaseOrder.DeliveryDate, purchaseOrder.Details, IGT.baseUrl, purchaseOrder.ID);
}
return RedirectToAction("Index");
}
Thanks!
Just keep things simple :)
Put a span around the DisplayFor and use a ternary operator on the deleted property to set a css class that will either turn the text red if deleted or a different color if not.
<div class="well text-center">
<h1>
<b>Purchase Order <span class="#(Model.deleted ? "DeletedCSSClass" : "ActiveCSSClass")"> #Html.DisplayFor(model => model.OrderID)</span></b>
</h1>
</div>
Looks like your using bootstrap so here's one approach.
Create a class representing your colours:
public sealed class TextColour
{
public string CssClass { get; }
private static IDictionary<string, TextColour> _instances = new Dictionary<string, TextColour>();
private TextColour(string cssClass)
{
CssClass = cssClass;
}
private static TextColour GetInstance(string cssClass)
{
if (!_instances.ContainsKey(cssClass))
{
_instances[cssClass] = new TextColour(cssClass);
}
return _instances[cssClass];
}
public static TextColour Primary => GetInstance("text-primary");
public static TextColour Secondary => GetInstance("text-secondary");
// Add others here
}
Add a property to your view model:
public class PurchaseOrderModel
{
public bool Deleted { get; set; }
public TextColour TextColour => Deleted ? TextColour.Primary : TextColour.Secondary;
}
Then in your view:
<div class="well text-center #Model.TextColour.CssClass">
<h1><b>Purchase Order #Html.DisplayFor(model => model.OrderID)</b></h1>
</div>

Struggling with filtering dropdown with another dropdown ASP.NET MVC

This is my first ASP.NET MVC application, and I'm really struggling with some stuffs, right now I have big issue and I'm stucked here for over 5 hours allready, I'm trying to filter my dropdown with selection from another dropdown, before I post my code I want to say that I've followed this post:
How to filter the options of a drop down list using another drop down list
So let's start:
Regardless of the others fields, I have a lets say two dropdowns also, one represent MAIN CATEGORY, another represent SUB CATEGORY, and on MAIN CATEGORY selection, SUB CATEGORY should be loaded in dropdown and user should be able to choose it.
I want to create view where user should be able to fill some date and post it back to server, but before he post it back he need to choose date properly MAINCATEG -> SUBCATEG so this is how I did it so far:
My action result 'Create' method:
public ActionResult Create()
{
// I did not wrote other stuffs because they are not important in my question and code will be clearer.
//First I'm filling MAIN CATEGORY dropdown with data from my database
List<Groups> articleGroups = GroupController.GetActiveMainGroups();
// Attach list on ViewBag, because this view Bag will be used to populate main dropdown
ViewBag.articleGroups = articleGroups;
//Here is second list which should populate second dropdown, right now I get all subgroups from database, because it didn't let me
//run my application if list was empty (probably I don't need this in future because I will filter second dropdown by selecting something from dropdown above)
List<SubGroups> subGroups = GroupController.GetAllSubGroups();
// Attach list on ViewBag, it will be used for generating dropdown list.
ViewBag.subGroups = subGroups;
return View(model);
}
Here is also one method which I thought I can call throught javascript by triggering event 'change' on first (main) dropdown:
public ActionResult GetSubgroupByMainGroup(Guid id)
{
List<SubGroups> subGroups = GroupController.GetAllSubGroupsByMainGroup(id);
return Json(subGroups, JsonRequestBehavior.AllowGet);
}
Here is my VIEW:
#model MyProject.Web.Models.ArticleNewViewModel
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
#using MyProject.Model
#{
ViewBag.Title = "Add new Article";
}
<h3>Adding new article to database</h3>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.MainGroupID, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.MainGroupID, new SelectList(ViewBag.articleGroups , "MainGroupID", "Group.Name"))
#Html.ValidationMessageFor(model => model.MainGroupID)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SubGroupID, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SubGroupID, new SelectList(ViewBag.subGroups , "SubGroupID", "SubGroup.Name"))
#Html.ValidationMessageFor(model => model.SubGroupID)
</div>
</div>
//I don't understand this code really, because I have so little experience with javascript&jquery
<script type="text/javascript">
$(function () {
$("#MainGroupID").change(function () {
var val = $(this).val();
var subItems="";
$.getJSON("#Url.Action("GetSubgroupByMainGroup", "Article")", {id:val} ,function (data) {
$.each(data,function(index,item){
subItems+="<option value='"+item.Value+"'>"+item.Text+"</option>"
});
$("#SubGroupID").html(subItems)
});
});
});
</script>
}
<div>
#Html.ActionLink("Go back", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
It is interesting that when I set breakpoint in my method public ActionResult GetSubgroupByMainGroup(Guid id) it's not being hitted, that means this code is not executed, and here is my
ArticleNewViewModel
:
public class ArticleNewViewModel
{
[Required]
[Display(Name = "Article code")]
public string Code { get; set; }
[Required]
[Display(Name = "Article Title")]
public string Title { get; set; }
//Here is ID's which should represent value from MAIN and value from SUBGROUP
[Required]
[Display(Name = "Main group")]
public Guid MainGroupID { get; set; }
[Required]
[Display(Name = "Sub Group")]
public Guid SubGroupID { get; set; }
}
I probably did few mistakes here but I really don't know where and what, because I'm not familiar with javascript & jquery, and I don't know is there another way to do it :/
Whatever I would like to fix this so if someone of you guys might help me I would appreciate so much!
Thanks guys
Cheers

RadioButtonFor in mvc shows required validation even though not applied required validation

I have one view in which I put two radio button for attribute in my model
I just put data annotation for other field but not the radiobutonfor field but steel it show required validation.Below is my code.I the attribute is int type in model.I used javascript unobtrusive library inn view as well.
<td>
<label>#Html.RadioButtonFor(m => m.OneToOne, 1) Hours </label>
<label>#Html.RadioButtonFor(m => m.OneToOne, 2) Unit </label>
</td>
I am using Html.begin from to post this value.
The RadioButtonFor helper method generates html markup for the radio button input with data-val-required attribute unless you specify the property as nullable type! The jQuery validate plugin does validation on this input because of the existence of this attribute.
If you do not want client side validation on this input, You should change the property type from int to nullable int(int?).
public class YourViewModel
{
// Other properties
public int? OneToOne { set; get; }
}
If radio buttons are not required to select, I personally like to use mutually exclusive checkboxes.
Mainly, if a user accidental selects a radio button, s/he won't be able to uncheck it back unless the user refreshes the entire page. I feel like it is really annoying.
Sample at jsfiddle.net
Model
public class ViewModel
{
public bool OneToOneHours { get; set; }
public bool OneToOneUnit { get; set; }
}
View
#using (Html.BeginForm("Index", "Home", null, FormMethod.Post))
{
<div class="form-control">
#Html.CheckBoxFor(model => model.OneToOneHours, new {#class = "mutually-exclusive"}) Hours
#Html.CheckBoxFor(model => model.OneToOneUnit, new {#class = "mutually-exclusive"}) Unit
</div>
<button id="btnSubmit" type="submit">Submit</button>
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
$('input.mutually-exclusive').click(function () {
var checkedState = $(this).val();;
$('input.mutually-exclusive').attr("checked", false);
$(this).prop("checked", checkedState);
});
</script>
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(ViewModel model)
{
int? oneToOne;
if (model.OneToOneHours)
oneToOne = 1;
else if (model.OneToOneUnit)
oneToOne = 2;
return View(model);
}
}

Update label depending on selected value on dropdownlist with knockout

In ASP.NET MVC, I have a form. In this form the user selects a country, and then the ID is posted back to the server, using a normal #using(Html.BeginForm) .
However, for some UX reasons, I use Knockout. Therefore I need to get my observable value countryId to have the value of a dropdownlist.
I want my label in the markup, to show the countryId, depending on the selected value on the dropdownlist.
Markup:
#Html.DropDownListFor(model => model.SelectedCountry, Model.Countries, new Dictionary<string, object> { { "class", "form-control sendaletter_countrylist" }, { "data-bind", "value:countryId" }})
<label data-bind="text: countryId"></label>
ViewModel:
public class CreateSingleLetterModel
{
public CreateSingleLetterModel()
{
this.Countries = new List<SelectListItem>();
}
public string SelectedCountry { get; set; } // expected to be the ID of the SelectListItem
public List<SelectListItem> Countries { get; set; }
}
Then my question is:
How do I modify my DropDownListFor, so the countryId is being set automatically? :-)
Thanks a lot! I really enjoy learning Knockout, but this one has taken me a long time!
All you've done looks correct.
Now you need to define the client-side view model (where countryId will be ko.observable) and call ko.applyBindings
var viewModel = {
countryId: ko.observable(0)
};
ko.applyBindings(viewModel);
example: http://jsfiddle.net/tabalinas/xJ7mm/

How to pass js variable to #Model.MyModel (MVC4)

Here are my models
public class AddressBook
{
public string UserId { get; set; }
public IList<Address> Addresses { get; set; }
public AddressBook()
{
UserId = "";
Addresses = new List<Address>();
}
}
public class Address
{
public string Company { get; set; }
public string Title { get; set; }
public string FName { get; set; }
...
}
The controller builds the AddressBook with a list of addresses.
The main page uses the AddressBook model (#model mymodel.AddressBook) and I can access the different addresses using Model.Addresses[index].
On the page I display the list of addresses each with an Edit button (I stripped the html code off for clarity):
#model mymodel.AddressBook
...
#for (int i = 0; i < Model.Addresses.Count; i++)
{
#Model.Addresses[i].Company
#Model.Addresses[i].FName
...
#:<input type="image" src="/images/edit.gif" onclick="addressEdit('#i'); return false;" title="Edit" />
}
When the user clicks on the edit button I call javascript addressEdit and pass it the index of the selected address.
<script type="text/javascript">
function addressEdit(index) {
$('#FName').val('#Model.Addresses[index].FName');
$('#Addr1').val('#Model.Addresses[index].Company');
...
}
</script>
The problem is on the jQuery lines $('#FName').val('#Model.Addresses[index].FName'); Variable index is underlined in red in VS2012 with message "the name 'index' does not exist in the current context".
How do you pass the value on 'index' to extract the data I need?
Wrap your elements in a spans with some class name. Wrap everything in the loop a div too. I am also removing the onclick method from the markup because we will do it in the unobtrusive way.
#for (int i = 0; i < Model.Addresses.Count; i++)
{
<div class='entry'>
<span class='spanAddress'> #Model.Addresses[i].Company </span>
<span class='spanFName'> #Model.Addresses[i].FName </span>
<img src="/images/edit.gif" class='editLink' />
</div>
}
Now in your javascript
$(function(){
$(".editLink").click(function(e){
e.preventDefault();
var _this=$(this);
var fname=_this.closest("div.entry").find(".spanFName").html();
var add=_this.closest("div.entry").find(".spanAddress").html();
$('#FName').val(fname);
$('#Address').val(add);
});
});
Well, this is client side code remember. So the best place to look is what is generated client side. This means commenting out your javascript event and looking at what is actually rendered to get an idea of what is going on.
When you do that, you will see that the helper autogenerates the names and ids based on your models names. Keep in mind that the name attribute on the inputs is what allows for model binding on post.
So, with all of that in consideration, I would assume it would be something along these lines:
function addressEdit(index) {
$('#FName').val($("#Addresses_"+index+"__FName").val());
//..etc
}

Categories

Resources