Error populate textbox JS - MVC - javascript

I have this code.
The objective of this js is through the dropwdown load the textbox UserMR
But it never finds the UserMR.
I call UserMr model inside Star instantiating a new object.
relationships:
Star contains idModel
Model does not contain IDStar
What is going on?
Model
[CustomValidation(typeof(StarValidation), "DateValidate")]
public partial class Star
{
public virtual string UserMR { get { return this.User.UserMR; } set { this.UserMR = value;} }
public Model User = new Model();
View inside "STAR"
#Html.EditorFor(i => i.IdModel, "StarModel", new { onchange = "updateUserMR($(this))" })
#Html.DisplayFor(i => i.UserMR)
<script type="text/javascript">
function updateUserMR(model) {
var user = model.brother("#Html.NameFor(x => x.UserMR)");
var idModel = model.val();
user.empty();
if (idModel != null && idModel != "")
user.loadOptions("#Url.Action("ListJsonUserMR", "Model")?idModel=" + idModel, true, true);
}
</script>
Controller
public JsonResult ListJsonUserMR(int idModel)
{
var model = this.service.GetUserMr(idModel).Select(x => new
{
Value = x.Id,
Description = x.UserMR
});
return this.Json(model, JsonRequestBehavior.AllowGet);
}
Service
public IEnumerable<Model> GetUser(int idModel)
{
return base.context.Models
.Where(x => x.Id == idModel);
}
Error

Related

Can not load book follow by category id in dropdownlist using javascript

i'm having trouble while choose each category, it can't show book of each category. My index code here
#using (Html.BeginForm("Index", "BorrowBook", FormMethod.Post, new { name = "demoForm" }))
{
#Html.DropDownList("id_category", (IEnumerable<SelectListItem>)ViewBag.listTest, "-- Select Category --",
new { onchange = "SelectedIndexChanged()" })
<div> Show list of book in the middle </div>
}
And my controller like that
// GET: BorrowBook
public ActionResult Index(string mess)
{
var query = context.categories.Select(c => new { c.id_category, c.name });
var userInfomatiom = (LibraryAsp.Models.User)Session["USER"];
if (userInfomatiom.Role.id_role == 1)
{
ViewBag.listP = publisherDao.getAll();
ViewBag.listC = categoryDao.getAll();
ViewBag.list = bookDao.getAll();
ViewBag.listTest = new SelectList(query.AsEnumerable(), "id_category", "name");
ViewBag.mes = mess;
return View();
}
else
{
return RedirectToAction("Error", "Home");
}
}
[HttpPost]
public ActionResult Index (Category category)
{
ViewBag.listP = publisherDao.getAll();
ViewBag.listC = categoryDao.getAll();
ViewBag.list = context.books.Where(p => p.id_category == category.id_category).ToList();
return View();
}
When debugging, i found that id category, form, or value is loaded like this
But when i choose each category, i get bug like that:
I think my java script is having problem. But i can't figure out this. Any body can help me, many thanks.
Problem solve, my bad to forget pass data. Should be like that
[HttpPost]
public ActionResult Index (Category category)
{
var query = context.categories.Select(c => new { c.id_category, c.name });
ViewBag.listP = publisherDao.getAll();
ViewBag.listC = categoryDao.getAll();
ViewBag.list = context.books.Where(p => p.id_category == category.id_category).ToList();
ViewBag.listTest = new SelectList(query.AsEnumerable(), "id_category", "name");
return View();
}

Compilation error in foreach statement while looping an object of type 'System.Threading.Tasks.Task<System.Collections.Generic.List' i

In the Asp.Net Project MVC with SignalR, I am trying to iterate over a object returned by Service in the Javascript Client. I get the below compile error for the foreach statement present in the below code
foreach statement cannot operate on variables of type 'System.Threading.Tasks.Task>' because 'System.Threading.Tasks.Task>' does not contain a public definition for 'GetEnumerator'
Can someone advise what changes should be done either in View/Service call ?
View Code
#model System.Threading.Tasks.Task<List<JobCurrentStatusDetails>>
<script type="text/javascript">
var connection = $.hubConnection();
var hub = connection.createHubProxy("JobDetailsHub");
hub.on('updateData',function(jSonRefreshData){
console.log(jSonRefreshData);
});
hub.invoke('NotifyUpdates').done(function(jSonRefreshData){
#Model = jSonRefreshData
#{int countTiles = 0;}
#foreach(item in Model)
{
if(item.color == "red")
{}
if(item.color == "green")
{}
}
});
</script>
Adding Server Side code
public async Task<List<JobCurrentStatusDetails>> NotifyUpdates()
{
var hubContext = lobalHost.ConnectionManager.GetHubContext<JobDetailsHub> ();
if (hubContext != null)
{
db = DataAccess.DataAccessModels.GetDashboardCounts();
return await hubContext.Clients.All.updateData(db);
}
else return null;
}
The Controller code is below :
public ActionResult Index()
{
DataAccess da = new DataAccess();
var jobDetailService = new JobDetailsService(da);
return View(jobDetailService.NotifyUpdates());
}
You are returning a Task as the Model. You could do this instead:
public List<JobCurrentStatusDetails> NotifyUpdates()
{
var hubContext = lobalHost.ConnectionManager.GetHubContext<JobDetailsHub>();
if (hubContext != null)
{
db = DataAccess.DataAccessModels.GetDashboardCounts();
return hubContext.Clients.All.updateData(db).Result;
}
else return null;
}

MVC 4 Razor - Creating a dynamic DropDownList

I'm trying to create a view which has two DropDownLists. The options available in the second DropDownList depend upon what the user has selected in the first. I'm passing this data to my view in the ViewBag as follows:
List<SelectListItem> firstBoxChoices = ViewBag.firstBoxChoices;
Dictionary<string, List<SelectListItem>> secondBoxDict = ViewBag.secondBoxDict;
The first object has the choices for the first DropDownList. When the user selects one of those, I need to get the appropriate list of choices for the second DropDownList from my Dictionary. I just can't figure out how to achieve this. If I get the new selection of the first DropDownList in a Javascript onchange() function, there doesn't seem to be any way to use this value as the key for my C# dictionary.
Of course, I've seen this functionality on the web so I know it must be possible somehow. How can I achieve this?
Thanks!
There are a couple ways of doing this without forcing you to store all the possible data items in the model, my preference is to use Javascript/JQuery. Here is an example of a Country/State cascading drop down:
Javascript used to get states when a country is selected:
<script type="text/javascript">
function AppendUrlParamTokens(url, params) {
for (var param in params) {
if (params[param] == null) {
delete params[param];
}
}
return url + "?" + jQuery.param(params);
}
function OnCountriesChange(ddl) {
jQuery.getJSON(AppendUrlParamTokens('#Url.Action("GetStates", "Data")', { countryId: ddl.options[ddl.selectedIndex].value }), function (result) {
var target = jQuery('#states_ddl');
target.empty();
jQuery(result).each(function() {
jQuery(document.createElement('option'))
.attr('value', this.Value)
.text(this.Text)
.appendTo(target);
});
});
};
</script>
Country dropdown:
#Html.DropDownListFor(model => model.Country, new SelectList(Model.Countries, "Value", "Text", Model.PreviousCountrySelected), "(Select One)", new { id = "countries_ddl", onchange = "OnCountriesChange(this)" })
State dropdown:
Html.DropDownListFor(model => model.State,
Model.States != null
? new SelectList(Model.States, "Value", "Text", Model.PreviousStateSelected)
: new SelectList(new List<SelectListItem>(), "Value", "Text"),
new { id = "states_ddl" })
Controller method to retrieve states:
public ActionResult GetStates(short? countryId)
{
if (!countryId.HasValue)
{
return Json(new List<object>(), JsonRequestBehavior.AllowGet);
}
var data = GetAllStatesForCountry(countryId.Value).Select(o => new { Text = o.StateName, Value = o.StateId });
return Json(data, JsonRequestBehavior.AllowGet);
}
The idea is that on selection of dropdown 1 you use ajax to go retrieve your second dropdown's value.
Edit: Forgot to include utility method for constructing urls
The .change event of your first select should populate the second select by calling a server method that returns the option data based on the selected value. Given the following view model
public class MyModel
{
[Required(ErrorMessage = "Please select an organisation")]
[Display(Name = "Organisation")]
public int? SelectedOrganisation { get; set; }
[Required(ErrorMessage = "Please select an employee")]
[Display(Name = "Employee")]
public int? SelectedEmployee { get; set; }
public SelectList OrganisationList { get; set; }
public SelectList EmployeeList { get; set; }
}
Controller
public ActionResult Edit(int ID)
{
MyModel model = new MyModel();
model.SelectedOrganisation = someValue; // set if appropriate
model.SelectedEmployee = someValue; // set if appropriate
ConfigureEditModel(model); // populate select lists
return View(model);
}
[HttpPost]
public ActionResult Edit(MyModel model)
{
if(!ModelState.IsValid)
{
ConfigureEditModel(model); // reassign select lists
return View(model);
}
// save and redirect
}
private void ConfigureEditModel(MyModel model)
{
// populate select lists
model.OrganisationList = new SelectList(db.Organisations, "ID", "Name");
if(model.SelectedOrganisation.HasValue)
{
var employees = db.Employees.Where(e => e.Organisation == model.SelectedOrganisation.Value);
model.EmployeeList = new SelectList(employees, "ID",
}
else
{
model.EmployeeList = new SelectList(Enumerable.Empty<SelectListItem>());
}
}
[HttpGet]
public JsonResult FetchEmployees(int ID)
{
var employees = db.Employees.Where(e => e.Organisation == ID).Select(e => new
{
ID = e.ID,
Name = e.Name
});
return Json(employees, JsonRequestBehavior.AllowGet);
}
View
#model MyModel
....
#Html.LabelFor(m => m.SelectedOrganisation)
#Html.DropDownListFor(m => m.SelectedOrganisation, Model.OrganisationList, "-Please select-")
#Html.ValidationMessageFor(m => m.SelectedOrganisation)
#Html.LabelFor(m => m.SelectedEmployee)
#Html.DropDownListFor(m => m.SelectedEmployee, Model.EmployeeList, "-Please select-")
#Html.ValidationMessageFor(m => m.SelectedEmployee)
....
Script
var url = '#Url.Action("FetchEmployees")';
var employees = $('SelectedEmployee');
$('#SelectedOrganisation').change(function() {
employees.empty();
if(!$(this).val()) {
return;
}
employees.append($('<option></option>').val('').text('-Please select-'));
$.getJson(url, { ID: $(this).val() }, function(data) {
$.each(data, function(index, item) {
employees.append($('<option></option>').val(item.ID).text(item.Text));
});
});
});

FluentValidation Validate checkbox and password on the client with EqualValidator

I implemented the code below to have a way to validate a checkbox unobtrusively found this code posted by Darin Dimitrov. It works really well for the checkbox, but it does not work if you also have password and confirm password validated with the EqualValidator. I wonder if the custom Validator can be changed to take the checkbox and password validation into account. Or do I need to write a custom Validator for the password?
Model
[Validator(typeof(MyViewModelValidator))]
public class MyViewModel
{
public bool IsChecked { get; set; }
}
Validator
public class MyViewModelValidator : AbstractValidator<MyViewModel>
{
public MyViewModelValidator()
{
RuleFor(x => x.IsChecked).Equal(true).WithMessage("Please check this checkbox");
}
}
Controller
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
return View(model);
}
}
View
#model MyViewModel
#using (Html.BeginForm())
{
#Html.LabelFor(x => x.IsChecked)
#Html.CheckBoxFor(x => x.IsChecked)
#Html.ValidationMessageFor(x => x.IsChecked)
#Html.LabelFor(model => model.Password, new { }, ":")
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
#Html.LabelFor(model => model.ConfirmPassword, new { }, ":")
#Html.EditorFor(model => model.ConfirmPassword)
#Html.ValidationMessageFor(model => model.ConfirmPassword)
<button type="submit">OK</button>
}
Custom FluentValidationPropertyValidator
public class EqualToValueFluentValidationPropertyValidator : FluentValidationPropertyValidator
{
public EqualToValueFluentValidationPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator)
: base(metadata, controllerContext, rule, validator)
{
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
if (!this.ShouldGenerateClientSideRules())
{
yield break;
}
var validator = (EqualValidator)Validator;
var errorMessage = new MessageFormatter()
.AppendPropertyName(Rule.GetDisplayName())
.AppendArgument("ValueToCompare", validator.ValueToCompare)
.BuildMessage(validator.ErrorMessageSource.GetString());
var rule = new ModelClientValidationRule();
rule.ErrorMessage = errorMessage;
rule.ValidationType = "equaltovalue";
rule.ValidationParameters["valuetocompare"] = validator.ValueToCompare;
yield return rule;
}
}
Global.asax
FluentValidationModelValidatorProvider.Configure(provider =>
{
provider.AddImplicitRequiredValidator = false;
provider.Add(typeof(EqualValidator), (metadata, context, description, validator) => new EqualToValueFluentValidationPropertyValidator(metadata, context, description, validator));
});
jQuery
(function ($) {
$.validator.unobtrusive.adapters.add('equaltovalue', ['valuetocompare'], function (options) {
options.rules['equaltovalue'] = options.params;
if (options.message != null) {
options.messages['equaltovalue'] = options.message;
}
});
$.validator.addMethod('equaltovalue', function (value, element, params) {
if ($(element).is(':checkbox')) {
if ($(element).is(':checked')) {
return value.toLowerCase() === 'true';
} else {
return value.toLowerCase() === 'false';
}
}
return params.valuetocompare.toLowerCase() === value.toLowerCase();
});
})(jQuery);
<script src="#Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/customadapter.js")" type="text/javascript"></script>
I know this is a few months old, but I was having the same problem. I posted a solution in Darin's original thread -> Validate checkbox on the client with FluentValidation/MVC 3
Here it is:
First, I updated the javascript function with the following.
$.validator.addMethod('equaltovalue', function (value, element, params) {
if ($(element).is(':checkbox')) {
value = $(element).is(':checked') ? "true" : "false";
}
return params.valuetocompare.toLowerCase() === value.toLowerCase();
});
Secondly, I updated EqualToValueFluentValidationPropertyValidator with the following:
public class EqualToValueFluentValidationPropertyValidator : FluentValidationPropertyValidator
{
EqualValidator EqualValidator
{
get { return (EqualValidator)Validator; }
}
public EqualToValueFluentValidationPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator) : base(metadata, controllerContext, rule, validator) {
ShouldValidate = false;
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules() {
if (!ShouldGenerateClientSideRules()) yield break;
var propertyToCompare = EqualValidator.MemberToCompare as PropertyInfo;
if(propertyToCompare != null) {
// If propertyToCompare is not null then we're comparing to another property.
// If propertyToCompare is null then we're either comparing against a literal value, a field or a method call.
// We only care about property comparisons in this case.
var comparisonDisplayName =
ValidatorOptions.DisplayNameResolver(Rule.TypeToValidate, propertyToCompare, null)
?? propertyToCompare.Name.SplitPascalCase();
var formatter = new MessageFormatter()
.AppendPropertyName(Rule.GetDisplayName())
.AppendArgument("ComparisonValue", comparisonDisplayName);
string message = formatter.BuildMessage(EqualValidator.ErrorMessageSource.GetString());
yield return new ModelClientValidationEqualToRule(message, CompareAttribute.FormatPropertyForClientValidation(propertyToCompare.Name)) ;
}
else
{
var validator = (EqualValidator)Validator;
var errorMessage = new MessageFormatter()
.AppendPropertyName(Rule.GetDisplayName())
.AppendArgument("ValueToCompare", validator.ValueToCompare)
.BuildMessage(validator.ErrorMessageSource.GetString());
var rule = new ModelClientValidationRule();
rule.ErrorMessage = errorMessage;
rule.ValidationType = "equaltovalue";
rule.ValidationParameters["valuetocompare"] = validator.ValueToCompare;
yield return rule;
}
}
}
For FluentValidation v8
public class EqualToValueFluentValidationPropertyValidator : FluentValidationPropertyValidator
{
EqualValidator EqualValidator
{
get { return (EqualValidator)Validator; }
}
public EqualToValueFluentValidationPropertyValidator(ModelMetadata metadata, ControllerContext controllerContext, PropertyRule rule, IPropertyValidator validator)
: base(metadata, controllerContext, rule, validator)
{
ShouldValidate = false;
}
public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
{
if (!ShouldGenerateClientSideRules())
yield break;
var propertyToCompare = EqualValidator.MemberToCompare as PropertyInfo;
if (propertyToCompare != null)
{
// If propertyToCompare is not null then we're comparing to another property.
// If propertyToCompare is null then we're either comparing against a literal value, a field or a method call.
// We only care about property comparisons in this case.
var comparisonDisplayName =
ValidatorOptions.DisplayNameResolver(Rule.TypeToValidate, propertyToCompare, null)
?? propertyToCompare.Name.SplitPascalCase();
var formatter = new MessageFormatter()
.AppendPropertyName(Rule.GetDisplayName())
.AppendArgument("ComparisonValue", comparisonDisplayName);
string message;
try
{
message = EqualValidator.Options.ErrorMessageSource.GetString(null);
}
catch (FluentValidationMessageFormatException)
{
// User provided a message that contains placeholders based on object properties. We can't use that here, so just fall back to the default.
message = ValidatorOptions.LanguageManager.GetStringForValidator<EqualValidator>();
}
message = formatter.BuildMessage(message);
#pragma warning disable 618
yield return new ModelClientValidationEqualToRule(message, CompareAttribute.FormatPropertyForClientValidation(propertyToCompare.Name));
#pragma warning restore 618
}
else
{
var errorMessage = new MessageFormatter()
.AppendPropertyName(Rule.GetDisplayName())
.AppendArgument("ValueToCompare", EqualValidator.ValueToCompare)
.BuildMessage(EqualValidator.Options.ErrorMessageSource.GetString(null));
var rule = new ModelClientValidationRule
{
ErrorMessage = errorMessage,
ValidationType = "equaltovalue"
};
rule.ValidationParameters["valuetocompare"] = EqualValidator.ValueToCompare;
yield return rule;
}
}
}

Pass data from one controller action to another view in mvc

I require to pass a variable from one controller action to javascript in another view..
In controller Action A:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection args)
{
var obj = new ProjectManagernew();
var res = new ProjectViewModelNew();
try
{
UpdateModel(res);
if (obj.AddUpdateOrderField(res))
{
ViewBag.RecordAdded = true;
ViewBag.Message = "Project Added Successfully";
TempData["Name"] = "Monjurul Habib";
}
return View(res);
}
catch (Exception)
{
//ModelState.AddRuleViolations(res.GetRuleViolations());
return View(res);
}
}
In another javascript:
function gridA() {
var message = '#TempData["Name"]';
$('#mylabel').text(message);
}
Only Tempdata works But not the first time its working from the second time after iam calling the action controller
I want to temp data to work rom the first time
I want t clear the data after using
If your javascript is inside the same view that takes the ProjectViewModelNew, you can use a different type for your view, for example you can use composition:
public class MyCompositeClass
{
ProjectViewModelNew ProjectViewModel{get;set;};
string Name{get;set;}
}
and then your action method would be:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection args)
{
var obj = new ProjectManagernew();
var res = new ProjectViewModelNew();
var myView = new MyCompositeClass();
try
{
UpdateModel(res);
myView.ProjecViewModel = res;
if (obj.AddUpdateOrderField(res))
{
ViewBag.RecordAdded = true;
ViewBag.Message = "Project Added Successfully";
myView.Name= "Monjurul Habib";
}
return View(myView);
}
catch (Exception)
{
//ModelState.AddRuleViolations(res.GetRuleViolations());
return View(myView);
}
}
and your js would be:
function gridA() {
var message = '#Model.Name';
$('#mylabel').text(message);
}

Categories