model binding from ajax for date value passing as null - javascript

I have a page called bookprogram and below is its model!
public class BookViewModel
{
[Required(ErrorMessage = "Field cannot be blank!", AllowEmptyStrings = false)]
[Display(Name="Name *")]
public string name { get; set; }
[Required(ErrorMessage = "Field cannot be blank!", AllowEmptyStrings = false)]
[DataType(DataType.PhoneNumber)]
public string contact { get; set; }
[Required(ErrorMessage = "Field cannot be blank!", AllowEmptyStrings = false)]
[RegularExpression("[A-Za-z0-9._%+-]+#[A-Za-z0-9.-]+.[A-Za-z]{2,4}", ErrorMessage = "Invalid Email Id")]
public string email { get; set; }
[Required(ErrorMessage = "Please select a category")]
public string category { get; set; }
[Required(ErrorMessage = "Field cannot be blank!", AllowEmptyStrings = false)]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime dateofprogram { get; set; }
[Required(ErrorMessage = "Field cannot be blank!", AllowEmptyStrings = false)]
[StringLength(200,ErrorMessage="Max length exceeded! Should be less than 200 characters")]
public string Message { get; set; }
}
Here is my js for performing AJAX Post
function ValidateBookProgramAndPost(form)
{
$(form).on("submit", function (e) {
e.preventDefault();
ValidateForm(form);
var selectedVal = $(form).find('select').children(":selected").val();
if(selectedVal=="")
{
$(form).find('div.bootstrap-select').children(":first").addClass('alert-danger');
$(form).find('div.bootstrap-select').next('.text-danger').html('Please select a category!');
}
var dateofprog = moment().format($('#txtDate').val());
console.log(dateofprog);
$.ajax({
url: '/BookProgram/',
type: "POST",
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: JSON.stringify({ model:{
name: $('#txtName').val(),
contact: $('#txtPhone').val(),
email: $('#txtEmail').val(),
category: $("#hdnSelectedCategory").val(),
dateofprogram: dateofprog,
Message: $("#txtMessage").val()
}
}),
success: function (data) {
if (data.result) {
$(form).find('input[type=text], textarea').val('').removeClass("alert-success");
$('.selectpicker').selectpicker('refresh');
}
else {
if (data.result == "Email Validation failed on server side!") {
$("#txtEmail").addClass("alert-danger");
}
else {
//display error message
}
return false;
}
return true;
}
}
$(form).unbind('submit');
return false;
});
and here is my controller:
[HttpPost]
public ActionResult BookProgram(BookViewModel model)
{
bool valid = false;
bool val = false;
if (ModelState.IsValid)
{
if (model.name != "" && model.category != "" && model.contact != "" && model.dateofprogram.ToShortDateString() != "" && model.email != "" && model.Message != "")
{
if (v.validateEmail(model.email) && v.validatePhone(model.contact))
{
valid = true;
}
else
{
return Json(new { result = "Email/Phone Validation failed on server side!" });
}
}
else
{
return Json(new { result = "One of the field has been modified and has been sent empty!!" });
}
if (valid)
{
using (var context = new MConnectionString())
{
tbl_programs book = new tbl_programs();
book.cont = model.contact;
book.date = model.dateofprogram;
book.email = model.email;
book.msg = model.Message;
book.category = model.category;
book.status = "";
book.name = model.name;
context.tbl_programs.Add(book);
context.SaveChanges();
val = true;
}
if (val)
{
return Json(new { result = true });
}
else
{
return Json(new { result = "Could not book the program. Please try again!" });
}
}
return Json(new { result = "Could not book the program. Please try again!" });
}
return Json(new { success = false });
}
But when I check in the controller the date value is coming null and Model.IsValid fails. how I should pass date value from ajax then? Console.log shows selected date[dateofprog] as "14/02/2015"[example] but it will not be assigned to model. Where is the problem actually I cannot make it out. Can anyone help me on this??

You are posting a invalid format for dateofprogram. It cases a failure at the binding process. You must specify the culture in at system.web section of the web.config to get the right date parsed from the json, for exemple:
<globalization uiCulture="pt-BR" culture="pt-BR" />
The code above informs the culture of the application, then if I inform a DateTime in BR format like dd/MM/yyyy it will bind correctly.

Related

Cascading DropDown Lists - What am I missing?

I've been following a tutorial on how to have one dropdown cascade from another, but am unable to get it to work. Any assistance would be greatly appreciated. I do not know javascript well, so fudging my way thru. I am not entirely sure I have the URL portion correct?
I am attempting to populate the ArrestDept dropdown and then filter and populate the ArrestOfficer dropdown based on the selected ArrestDept.
Here is what I have so far:
Relevant Part of View:
<td style="width: 20%">
<div class="mb-3">
<label asp-for="Incident.ArrestDept"></label>
<select id="agency" class="form-select"></select>
</div>
</td>
<td style="width: 20%">
<div class="mb-3">
<label asp-for="Incident.ArrestOfficer"></label>
<select id="officer" class="form-select"></select>
</div>
</td>
#section Scripts at bottom of View:
#section Scripts
{
<partial name="_ValidationScriptsPartial" />
<script type="text/javascript">
$(document).ready(function () {
$('#agency').attr('disabled', true);
$('#officer').attr('disabled', true);
LoadAgencies();
});
function LoadAgencies() {
$('#agency').empty();
$.ajax({
url: '/CreateModel/GetAgencies',
success: function (response) {
if (response != null && response != undefined && response.length > 0) {
$('#agency').attr('disabled', false);
$('#agency').append('
<option>---Select Arresting Agency---</option>');
$('#officer').append('
<option>---Select Arresting Officer---</option>');
$.each(response, function (i, data) {
$('#agency').append('
<option value=' + data.id + '>' + data.AgencyName + '</option>');
});
}
else {
$('#agency').attr('disabled', true);
$('#officer').attr('disabled', true);
$('#agency').append('
<option>---Arresting Agencies Not Available---</option>');
$('#officer').append('
<option>---Arresting Officers Not Available---</option>');
}
},
error: function (error) {
alert(error);
}
});
}
}
function LoadOfficers(agencyId) {
$('#officer').empty();
$.ajax({
url: '/CreateModel/GetOfficers?Id=' + agencyId,
success: function (response) {
if (response != null && response != undefined && response.length > 0) {
$('#officer').attr('disabled', false);
$('#officer').append('
<option>---Select Arresting Officer---</option>');
$.each(response, function (i, data) {
$('#officer').append('
<option value=' + data.id + '>' + data.OfficerDisplayName + '</option>');
});
}
else {
$('#officer').attr('disabled', true);
$('#officer').append('
<option>---Arresting Officers Not Available---</option>');
}
},
error: function (error) {
alert(error);
}
});
</script>
}
.cs for the View:
using DWITracker.Data;
using DWITracker.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
namespace DWITracker.Pages.Incidents;
[BindProperties]
public class CreateModel : PageModel
{
private readonly ApplicationDbContext _db;
public Incident Incident { get; set; }
public CreateModel(ApplicationDbContext db)
{
_db = db;
}
public IEnumerable<City> DisplayCityData { get; set; }
public IEnumerable<County> DisplayPIAddressCountyData { get; set; }
public IEnumerable<Ethnicity> DisplayPIEthnicityData { get; set; }
public IEnumerable<ArrestMethod> DisplayArrestMethodData { get; set; }
public IEnumerable<Test> DisplayTestGivenData { get; set; }
public IEnumerable<Charge> DisplayChargeData { get; set; }
public IEnumerable<DrinkLocation> DisplayLastDrinkData { get; set; }
public IEnumerable<DrugRecognitionExpert> DisplayDrugExpertData { get; set; }
public async Task OnGet()
{
await _db.City.Select(a => a.CityName).ToListAsync();
DisplayCityData = await _db.City.ToListAsync();
await _db.County.Select(a => a.CountyName).ToListAsync();
DisplayPIAddressCountyData = await _db.County.ToListAsync();
await _db.Ethnicity.Select(a => a.EthnicityName).ToListAsync();
DisplayPIEthnicityData = await _db.Ethnicity.ToListAsync();
await _db.ArrestMethod.Select(a => a.ArrestMethodDesc).ToListAsync();
DisplayArrestMethodData = await _db.ArrestMethod.ToListAsync();
await _db.Test.Select(a => a.TestDesc).ToListAsync();
DisplayTestGivenData = await _db.Test.ToListAsync();
await _db.Charge.Select(a => a.ChargeCode).ToListAsync();
DisplayChargeData = await _db.Charge.ToListAsync();
await _db.DrinkLocation.Select(a => a.LastDrinkLocation).ToListAsync();
DisplayLastDrinkData = await _db.DrinkLocation.ToListAsync();
await _db.DrugRecognitionExpert.Select(a => a.DrugRecExpert).ToListAsync();
DisplayDrugExpertData = await _db.DrugRecognitionExpert.ToListAsync();
}
public JsonResult GetAgencies()
{
var agencies = _db.Agency.OrderBy(x => x.AgencyName).ToList();
return new JsonResult(agencies);
}
public JsonResult GetOfficers(int id)
{
var officers = _db.Officer.Where(x => x.Agency.Id == id).OrderBy(x => x.OfficerDisplayName).ToList();
return new JsonResult(officers);
}
public async Task<IActionResult> OnPost()
{
if (ModelState.IsValid)
{
_db.Incident.Add(Incident);
await _db.Incident.AddAsync(Incident);
await _db.SaveChangesAsync();
TempData["success"] = "Incident added successfully.";
return RedirectToPage("Index");
}
return Page();
}
}
Relevant part of Incident Model:
public class Incident
{
[Key]
public int Id { get; set; }
[Display(Name = "Arresting Dept")]
public string? ArrestDept { get; set; }
[Display(Name = "Arresting Officer")]
public string? ArrestOfficer { get; set; }
}
Relevant part of Agency Model:
public class Agency
{
[Key]
public int Id { get; set; }
[Required]
[Display(Name = "Agency")]
public string AgencyName { get; set; }
}
Relevant Part of Officer Model:
public class Officer
{
[Key]
public int Id { get; set; }
[Display(Name ="Officer Name (Last, First, MI)")]
public string? OfficerDisplayName { get; set; }
[Display(Name = "First Name")]
public string? OfficerFirstName { get; set; }
[Display(Name = "MI")]
public string? OfficerMiddleInitial { get; set; }
[Display(Name = "Last Name")]
public string? OfficerLastName { get; set; }
public Agency Agency { get; set; }
}
***An additional question is if this would be easier to accomplish using ONE table as I can easily combine the Officer and Agency models into ONE table. Actually, this would be my preference, but have not been able to find a tutorial that addresses how to do this.
I'm thinking I could easily eliminate the Agency model and simply combine them on the Officer model, so have edited to add the Agency to the Officer model. There could be many officers to a single 'OfficerAgency'.
using System.ComponentModel.DataAnnotations;
namespace DWITracker.Model
{
public class Officer
{
[Key]
public int Id { get; set; }
[Display(Name ="Officer Name (Last, First, MI)")]
public string? OfficerDisplayName { get; set; }
[Display(Name = "First Name")]
public string? OfficerFirstName { get; set; }
[Display(Name = "MI")]
public string? OfficerMiddleInitial { get; set; }
[Display(Name = "Last Name")]
public string? OfficerLastName { get; set; }
[Display(Name = "Agency")]
public string? OfficerAgency { get; set; }
[Display(Name = "Added/Updated By")]
public string UpdatedBy { get; set; }
[Display(Name = "Date Added/Updated")]
[DataType(DataType.Date)]
public DateTime UpdateDate { get; set; }
public Agency Agency { get; set; }
}
}
How would this change the code? Hoping it would make it simpler?
Just not sure how I would change the .cs to work on the single table, specifically the OnGetGetOfficers(int id):
public JsonResult OnGetGetAgencies()
{
var agencies = _db.Officer.OrderBy(x => x.OfficerAgency).ToList();
return new JsonResult(agencies);
}
public JsonResult OnGetGetOfficers(int id)
{
var officers = _db.Officer.Where(x => x.OfficerAgency == id).OrderBy(x => x.OfficerDisplayName).ToList();
return new JsonResult(officers);
}
Your js contains multiple problems here:
1.You add an extra } in LoadAgencies function.
2.You miss a } in LoadOfficers function.
3.You can see each time you use append, the string in this method you always write in a new line, you need concatenate strings in JavaScript using the + operator like below(just an example, your js contains many this type problems):
$('#agency').append(''+
'<option>---Select Arresting Agency---</option>');
Or just move to the same line:
$('#agency').append('<option>---Select Arresting Agency---</option>');
4.The response data is camel case format, for example, you need change data.AgencyName to data.agencyName:
$('#agency').append('<option value=' + data.id + '>' + data.agencyName + '</option>');
5.Razor Pages routing is not like MVC, Razor pages uses OnGet and OnPost to deal with the Http Get and Post request. And the url is related to the PageModelName and folder name, e.g: IndexModel in Pages/Student folder, the url is:/Student/Index. If it is just in Pages folder, the url is:/Index. If you need another Get or Post method in current PageModel, you need define the method name like: OnGetHandlerName or OnPostHandlerName. The url is: /FolderName/PageModelName?handler=HandlerName.
Whole working code:
Page
#page
#model CreateModel
<table>
<tr>
<td style="width: 20%">
<div class="mb-3">
<label asp-for="Incident.ArrestDept"></label>
#*add onchange function*#
<select id="agency" class="form-select" onchange="LoadOfficers(this.value)"></select>
</div>
</td>
<td style="width: 20%">
<div class="mb-3">
<label asp-for="Incident.ArrestOfficer"></label>
<select id="officer" class="form-select"></select>
</div>
</td>
</tr>
</table>
JS in page:
#section Scripts
{
<partial name="_ValidationScriptsPartial" />
<script type="text/javascript">
$(document).ready(function () {
$('#agency').attr('disabled', true);
$('#officer').attr('disabled', true);
LoadAgencies();
});
function LoadAgencies() {
$('#agency').empty();
$.ajax({
url: '/Create?handler=GetAgencies', //change here....
success: function (response) {
if (response != null && response != undefined && response.length > 0) {
$('#agency').attr('disabled', false);
$('#agency').append('<option>---Select Arresting Agency---</option>');//change to one line...
$('#officer').append('<option>---Select Arresting Officer---</option>');//change to one line...
$.each(response, function (i, data) {
//change to camel case here...
$('#agency').append('<option value=' + data.id + '>' + data.agencyName + '</option>');
});
}
else {
$('#agency').attr('disabled', true);
$('#officer').attr('disabled', true);
$('#agency').append('<option>---Arresting Agencies Not Available---</option>');//change to one line...
$('#officer').append('<option>---Arresting Officers Not Available---</option>');//change to one line...
}
},
error: function (error) {
alert(error);
}
});
}
//}
function LoadOfficers(agencyId) {
$('#officer').empty();
$.ajax({
url: '/Create?handler=GetOfficers&Id=' + agencyId, //change here....
success: function (response) {
if (response != null && response != undefined && response.length > 0) {
$('#officer').attr('disabled', false);
$('#officer').append('<option>---Select Arresting Officer---</option>'); //change to one line...
$.each(response, function (i, data) {
//change to camel case here...
$('#officer').append('<option value=' + data.id + '>' + data.officerDisplayName + '</option>');
});
}
else {
$('#officer').attr('disabled', true);
$('#officer').append('<option>---Arresting Officers Not Available---</option>'); //change to one line...
}
},
error: function (error) {
alert(error);
}
});
} //add this '}'
</script>
}
PageModel
public JsonResult OnGetGetAgencies()
{
//...
return new JsonResult(agencies);
}
public JsonResult OnGetGetOfficers(int id)
{
//...
return new JsonResult(officers);
}

How to pass in nested data from the client to the controller

I have a form that has two sections. 3 input fields and another section with 10 checkboxes.
public class Customerproductdto
{
public string CustomerNumber { get; set; }
public string CustomerName { get; set; }
public string CustomerPhone { get; set; }
List<ProductDetails> GetAllChecked {get;set;}
}
public class ProductDetails
{
public string ProductName{ get; set; }
}
Here is jquery code I am using to get all the values of the checkboxes that were
checked on my form. They are about 10 and users could check everything.
var yourArray[]
$("input:checkbox[name=type]:checked").each(function(){
yourArray.push($(this).val());
});
Here is javascript that I use to collect the data and pass to my controller.
How can I pass in my array here all in one shot?
var objdata =
({
CustomerNumber: txtcustnumber,
CustomerName: txtcustname,
CustomerPhone: txtphone
//How do I pass the yourArray here?
});
var url = "#Url.Action("WriteToDb", "Home")";
var completeData = JSON.stringify({ 'Information': objdata });
$.get(url, { 'objdata': completeData }, function (data) {
$('#mainListContent').html(data);
});
Please note that I will like to deserialize this once I get to the controller.
Here is the method.
public ActionResult WriteToDb(string objdata)
{
Customerproductdto getAllTaskSaved = null;
try
{
var stripOffObjectName = JObject.Parse(objdata)["Information"];
var cleanedData = JsonConvert.DeserializeObject<Customerproductdto>(stripOffObjectName.ToString());
getAllTaskSaved = _dtcDataService.WriteTaskToDb(cleanedData, "Add");
}
catch (Exception ex)
{
logger.Error(ex);
}
return PartialView("_Taskdisplay", getAllTaskSaved);
}

Mistake in js/spring boot/hibernate project

I am trying to do some project on Spring Boot with JavaScript, but I have strage mistakes. Here they are:
org.springframework.web.method.annotation.MethodArgumentTypeMismatchException:
Failed to convert value of type [java.lang.String] to required type
[int]; nested exception is java.lang.NumberFormatException: For input
string: "filterByData"
Caused by: java.lang.NumberFormatException: For input string:
"filterByData"
I can`t find this "filterByData" in my project and what parameter I give like int insteed of String.
My entities:
#NamedQueries({
#NamedQuery(name = Contact.GET, query = "SELECT cont FROM Contact cont WHERE cont.id=:id AND cont.user.id=:userId"),
#NamedQuery(name = Contact.ALL_SORTED, query = "SELECT cont FROM Contact cont WHERE cont.user.id=:userId ORDER BY cont.firstName DESC"),
#NamedQuery(name = Contact.DELETE, query = "DELETE FROM Contact cont WHERE cont.id=:id AND cont.user.id=:userId"),
#NamedQuery(name = Contact.GET_FILTERED, query = "SELECT cont FROM Contact cont WHERE cont.user.id=:userId " +
"AND cont.firstName LIKE :fName AND cont.lastName LIKE :lName " +
"AND cont.mobilePhone LIKE :mPhone ORDER BY cont.firstName DESC"),
})
#Entity
#Table(name = "contacts")
public class Contact extends BaseEntity{
public static final String GET = "Contact.GET";
public static final String ALL_SORTED = "Contact.ALL_SORTED";
public static final String DELETE = "Contact.DELETE";
public static final String GET_FILTERED = "Contact.GET_FILTERED";
#Column(name = "first_name", nullable = false)
#NotEmpty
#Length(min = 4)
private String firstName;
#Column(name = "last_name", nullable = false)
#NotEmpty
#Length(min = 4)
private String lastName;
#Column(name = "patronymic", nullable = false)
#NotEmpty
#Length(min = 4)
private String patronymic;
#Column(name = "mobile_phone_number", nullable = false)
#NotEmpty
#Pattern(regexp = "\\+380\\([1-9]{2}\\)[0-9]{7}", message = "format should be like +380(66)1234567" +
"")
private String mobilePhone;
#Column(name = "home_phone_number")
private String homePhone;
#Column(name = "address")
private String address;
#Email
#Column(name = "email", nullable = false)
private String email;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "user_id", nullable = false)
#JsonBackReference
private User user;
public Contact() {
}
public Contact(String firstName, String lastName, String patronymic, String mobilePhone, String homePhone, String address, String email ) {
this(null,firstName,lastName,patronymic,mobilePhone,homePhone,address,email);
}
public Contact( Integer id, String firstName, String lastName, String patronymic, String mobilePhone, String homePhone, String address, String email ) {
super(id);
this.firstName = firstName;
this.lastName = lastName;
this.patronymic = patronymic;
this.mobilePhone = mobilePhone;
this.homePhone = homePhone;
this.address = address;
this.email = email;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPatronymic() {
return patronymic;
}
public void setPatronymic(String patronymic) {
this.patronymic = patronymic;
}
public String getMobilePhone() {
return mobilePhone;
}
public void setMobilePhone(String mobilePhone) {
this.mobilePhone = mobilePhone;
}
public String getHomePhone() {
return homePhone;
}
public void setHomePhone(String homePhone) {
this.homePhone = homePhone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
#Override
public String toString() {
return "Contact{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", patronymic='" + patronymic + '\'' +
", mobilePhone='" + mobilePhone + '\'' +
", homePhone='" + homePhone + '\'' +
", address='" + address + '\'' +
", email='" + email + '\'' +
'}';
}
}
#NamedEntityGraphs({
#NamedEntityGraph(name = User.GRAPH_WITH_ROLES, attributeNodes = #NamedAttributeNode("roles")),
#NamedEntityGraph(name = User.GRAPH_WITH_ROLES_AND_CONTACTS, attributeNodes =
{
#NamedAttributeNode("roles"),
#NamedAttributeNode("contacts")
})
})
#NamedQueries({
#NamedQuery(name = User.DELETE, query = "DELETE FROM User u WHERE u.id=:id"),
#NamedQuery(name = User.BY_LOGIN, query = "SELECT DISTINCT u FROM User u LEFT JOIN FETCH u.roles WHERE u.login=:login"),
#NamedQuery(name = User.ALL_SORTED, query = "SELECT DISTINCT u FROM User u LEFT JOIN FETCH u.roles ORDER BY u.login"),
})
#Entity
#Table(name = "users", uniqueConstraints = {#UniqueConstraint(columnNames = "login", name = "users_unique_login_idx")})
public class User extends NamedEntity{
public static final String GRAPH_WITH_ROLES = "User.WithRoles";
public static final String GRAPH_WITH_ROLES_AND_CONTACTS = "User.WithRolesAndContacts";
public static final String DELETE = "User.DELETE";
public static final String BY_LOGIN = "User.BY_LOGIN";
public static final String ALL_SORTED = "User.All_SORTED";
#Column(name = "password", nullable = false)
#Length(min = 5, max = 100, message = "your password should have 5 or more symbols")
#JsonView(View.REST.class)
#NotEmpty
private String password;
#Column(name = "full_name", nullable = false)
#Length(min = 5, max = 100, message = "your fullName should have 5 or more symbols")
private String fullName;
#Enumerated(EnumType.STRING)
#CollectionTable(name = "user_roles", joinColumns = #JoinColumn(name = "user_id"))
#Column(name = "role")
#ElementCollection(fetch = FetchType.LAZY)
protected Set<Role> roles;
#OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.LAZY, mappedBy = "user")
#OrderBy("firstName DESC")
#JsonManagedReference
protected List<Contact> contacts;
public User() {
}
public User(User u) {
this(u.getId(), u.getLogin(), u.getPassword(), u. getFullName(), u.getRoles());
}
public User(Integer id, String login, String password, String fullName, Role role, Role... roles) {
this(id, login, password, fullName, EnumSet.of(role, roles));
}
public User(Integer id, String login, String password, String fullName, Set<Role> roles) {
super(id, login);
this.password = password;
this.fullName = fullName;
setRoles(roles);
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getFullName() {
return fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = CollectionUtils.isEmpty(roles) ? Collections.emptySet() : EnumSet.copyOf(roles);
}
public List<Contact> getContacts() {
return contacts;
}
#Override
public String toString() {
return "User{" +
"password='" + password + '\'' +
", fullName='" + fullName + '\'' +
", roles=" + roles +
'}';
}
}
Controllers:
#Controller
public class RootController extends AbstractUserController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public String root() {
return "redirect:/contacts";
}
#RequestMapping(value = "/contacts", method = RequestMethod.GET)
public String contactList() {
return "contacts";
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
#PreAuthorize("hasRole('ROLE_USER')")
public String login(ModelMap model,
#RequestParam(value = "error", required = false) boolean error,
#RequestParam(value = "message", required = false) String message) {
model.put("error", error);
model.put("message", message);
return "login";
}
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String register(ModelMap model) {
model.addAttribute("userDTO", new UserDTO());
model.addAttribute("register", true);
return "contacts";
}
#RequestMapping(value = "/register", method = RequestMethod.POST)
public String saveRegister(#Valid UserDTO userDTO, BindingResult result, SessionStatus status, ModelMap model) {
if (!result.hasErrors()) {
try {
super.create(UserUtil.createNewUserFromDTO(userDTO));
status.setComplete();
return "redirect:login?message=app.registered";
} catch (DataIntegrityViolationException ex) {
result.rejectValue("Login", "---");
}
}
model.addAttribute("register", true);
return "contacts";
}
}
#RestController
#RequestMapping(value = "/ajax/contacts")
public class ContactAjaxController extends AbstractContactController{
#RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public List<Contact> getAll() {
return super.getAll();
}
#RequestMapping(value = "/{id}")
public Contact get(#PathVariable("id") int id) {
return super.get(id);
}
#RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public void delete(#PathVariable("id") int id) {
super.delete(id);
}
#RequestMapping(method = RequestMethod.POST)
public void updateOrCreate(#Valid Contact contact) {
if (contact.isNew()) {
super.create(contact);
} else {
super.update(contact, contact.getId());
}
}
#RequestMapping(value = "/filter", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public List<Contact> getFiltered(
#RequestParam(value = "fName", required = false) String fName,
#RequestParam(value = "lName", required = false) String lName,
#RequestParam(value = "mPhone", required = false) String mPhone) {
return super.getFiltered(fName, lName, mPhone);
}
}
#RestController
#RequestMapping("/ajax/users")
public class UserAjaxController extends AbstractUserController{
#RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#JsonView(View.UI.class)
public List<User> getAll() {
return super.getAll();
}
#RequestMapping(value = "/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#JsonView(View.UI.class)
public User get(#PathVariable("id") int id) {
return super.get(id);
}
#RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
public void delete(#PathVariable("id") int id) {
super.delete(id);
}
#RequestMapping(method = RequestMethod.POST)
public void createOrUpdate(#Valid UserDTO userTo) {
if (userTo.isNew()) {
super.create(UserUtil.createNewUserFromDTO(userTo));
} else {
super.update(userTo);
}
}
}
JavaScript files:
var ajaxUrl = 'ajax/contacts/';
var datatableApi;
function updateTable() {
$.ajax({
type: "POST",
url: ajaxUrl + 'filter',
data: $('#filter').serialize(),
success: updateTableByData
});
return false;
}
$(function () {
datatableApi = $('#datatable').DataTable({
"ajax": {
"url": ajaxUrl,
"dataSrc": ""
},
"paging": false,
"info": true,
"columns": [
{
"data": "firstName"
},
{
"data": "lastName"
},
{
"data": "patronymic"
},
{
"data": "mobilePhone"
},
{
"data": "homePhone"
},
{
"data": "address"
},
{
"data": "email"
},
{
"defaultContent": "",
"orderable": false,
"render": renderEditBtn
},
{
"defaultContent": "",
"orderable": false,
"render": renderDeleteBtn
}
],
"order": [
[
0,
"desc"
]
],
"initComplete": function () {
$('#filter').submit(function () {
updateTable();
return false;
});
makeEditable();
}
});
});
var form;
function makeEditable() {
form = $('#detailsForm');
form.submit(function () {
save();
return false;
});
$(document).ajaxError(function (event, jqXHR, options, jsExc) {
failNoty(event, jqXHR, options, jsExc);
});
// var token = $("meta[name='_csrf']").attr("content");
// var header = $("meta[name='_csrf_header']").attr("content");
// $(document).ajaxSend(function(e, xhr, options) {
// xhr.setRequestHeader(header, token);
// });
}
function add() {
form.find(":input").val("");
$('#id').val(null);
$('#editRow').modal();
}
function updateRow(id) {
$.get(ajaxUrl + id, function (data) {
$.each(data, function (key, value) {
form.find("input[name='" + key + "']").val(value);
});
$('#editRow').modal();
});
}
function deleteRow(id) {
$.ajax({
url: ajaxUrl + id,
type: 'DELETE',
success: function () {
updateTable();
successNoty('Deleted');
}
});
}
function updateTableByData(data) {
datatableApi.clear().rows.add(data).draw();
}
function save() {
$.ajax({
type: "POST",
url: ajaxUrl,
data: form.serialize(),
success: function () {
$('#editRow').modal('hide');
updateTable();
successNoty('Saved');
}
});
}
var failedNote;
function closeNoty() {
if (failedNote) {
failedNote.close();
failedNote = undefined;
}
}
function successNoty(text) {
closeNoty();
noty({
text: text,
type: 'success',
layout: 'bottomRight',
timeout: true
});
}
function failNoty(event, jqXHR, options, jsExc) {
closeNoty();
var errorInfo = $.parseJSON(jqXHR.responseText);
failedNote = noty({
text: 'Failed: ' + jqXHR.statusText + '<br>' + errorInfo.cause + '<br>' + errorInfo.details.join('<br>'),
type: 'error',
layout: 'bottomRight'
});
}
function renderEditBtn(data, type, row) {
if (type == 'display') {
return '<a class="btn btn-xs btn-primary" onclick="updateRow(' + row.id + ');">Edit</a>';
}
return data;
}
function renderDeleteBtn(data, type, row) {
if (type == 'display') {
return '<a class="btn btn-xs btn-danger" onclick="deleteRow(' + row.id + ');">Delete</a>';
}
return data;
}
My basic CRUD methods work fine without 'filter' and I got this mistake every time. Can someone tell my what I am doing wrong? Thanks.
public abstract class AbstractUserController {
#Autowired
private UserService service;
public List<User> getAll() {
return service.getAll();
}
public User get(int id){
return service.get(id);
}
public User create(User user) {
user.setId(null);
return service.save(user);
}
public void delete(int id){
service.delete(id);
}
public void update(User user, int id) {
user.setId(id);
service.update(user);
}
public void update(UserDTO userDTO) {
service.update(userDTO);
}
public User getByLogin(String login) {
return service.getByLogin(login);
}
}

How to load angular-formly vm.fields from server

i am trying to use Angular-Formly to build dynamically forms starting from a set of .NET classes.
I serialize the class properties information in json and return that to Formly, but no fields is shown.
I follow suggestions find in: How to load angular-formly vm.fields object from remotely-generated json?
but not seems to work for me.
My form code is:
<form ng-submit="vm.onSubmit()" novalidate>
<formly-form model="vm.model" fields="vm.formFields">
<button type="submit" class="btn btn-primary submit-button">Submit</button>
</formly-form>
</form>
The angular code is:
<script>
/* global angular */
(function () {
'use strict';
var app = angular.module('formlyExample', ['formly', 'formlyBootstrap'], function config(formlyConfigProvider) {
// set templates here
//formlyConfigProvider.setType({
// name: 'custom',
// templateUrl: 'custom.html'
//});
});
app.factory('User', function ($http) {
return {
getFields: getFields
};
function getFields() {
return $http.post('TestFormly.aspx/LoadData', { headers: { 'Cache-Control': 'no-cache' } });
}
});
app.controller('MainCtrl', function MainCtrl($scope, $http, User) {
var vm = this;
// funcation assignment
vm.onSubmit = onSubmit;
vm.loadingData = User.getFields().then(function (result) {
vm.fields = JSON.parse(result.data.d);
vm.originalFields = angular.copy(vm.fields);
});
vm.model = {
};
// function definition
function onSubmit() {
alert(JSON.stringify(vm.model), null, 2);
}
});
})();
</script>
The CSharp.Net code is:
[WebMethod]
public static string LoadData()
{
string retValue = null;
List<FieldItem> m_fields = new List<FieldItem>();
FieldItem item1 = new FieldItem();
item1.key = "text";
item1.type = "input";
item1.templateOptions = new TemplateOptions() { label = "Text", placeholder = "Formly is terrific!" };
FieldItem item2 = new FieldItem();
item2.key = "story";
item2.type = "textarea";
item2.templateOptions = new TemplateOptions() { label = "Some sweet story", placeholder = "It allows you to build and maintain your forms with the ease of JavaScript :-)" };
m_fields.Add(item1);
m_fields.Add(item2);
retValue = JsonConvert.SerializeObject(m_fields);
return retValue;
}
The JSON result is:
[
{
"key":"text",
"type":"input",
"templateOptions":{
"label":"Text",
"placeholder":"Formly is terrific!"
}
},
{
"key":"story",
"type":"textarea",
"templateOptions":{
"label":"Some sweet story",
"placeholder":"It allows you to build and maintain your forms with the ease of JavaScript :-)"
}
}
]
Debugging with firebug i see the JSON passed correctly to the vm.fields but no input box is shown, only the Sumbit button.
I noticed that nor the Formly example shows the fields.
Can you help ?
Thanks in advance,
Giuseppe.
Here is a solution I've quickly hacked as a proof of concept for myself.
Basically the FormlyModelBuilder does scan a ViewModel class and builds a formly fields model.
Sample usage
public IActionResult Index()
{
return Ok(new ViewModels.Account.FormlyModelBuilder<ViewModels.Account.RegisterViewModel>().JsonStringify(new ViewModels.Account.RegisterViewModel { Email = "test#test.com" }));
}
Transforms this
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare ("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
into this
{
"fields": [{
"key": "Email",
"type": "email",
"templateOptions": {
"isRequired": false,
"label": "Email"
},
"expressionProperties": {
"templateOptions.focus": "Email"
}
}, {
"key": "Password",
"type": "password",
"templateOptions": {
"isRequired": false,
"label": "Password"
},
"expressionProperties": {}
}, {
"key": "ConfirmPassword",
"type": "password",
"templateOptions": {
"label": "Confirm password"
},
"expressionProperties": {}
}],
"model": {
"email": "test#test.com"
},
"expressionProperties": {}
}
Source Code
public class FormlyModelBuilder<T>
{
internal T GetAttributeFrom<T>(object instance, string propertyName) where T : Attribute
{
var property = instance.GetType().GetProperty(propertyName);
return GetAttributeFrom<T>(property);
}
internal T GetAttributeFrom<T>(PropertyInfo property) where T : Attribute
{
var attrType = typeof(T);
T t = (T)property.GetCustomAttributes(attrType, false).FirstOrDefault();
if (t == null)
{
var metaAttr = (MetadataTypeAttribute[])property.ReflectedType.GetCustomAttributes(typeof(MetadataTypeAttribute), true);
if (metaAttr.Length > 0)
{
foreach (MetadataTypeAttribute attr in metaAttr)
{
var subType = attr.MetadataClassType;
var pi = subType.GetField(property.Name);
if (pi != null)
{
t = (T)pi.GetCustomAttributes(attrType, false).FirstOrDefault();
return t;
}
}
}
}
else
{
return t;
}
return null;
}
internal FormlyModel<T> Build(T dataModel)
{
if (dataModel == null) throw new ArgumentNullException(nameof(dataModel));
//
var modelType = typeof(T);
var model = new FormlyModel<T>(dataModel);
foreach (var property in modelType.GetProperties(BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.SetProperty | BindingFlags.Public))
{
var type = GetAttributeFrom<DataTypeAttribute>(property);
var field = new FormlyField(property.Name, GetInputTypeFromDataType(type?.DataType, property.PropertyType));
model.AddField(field);
//
var display = GetAttributeFrom<DisplayAttribute>(property);
field.TemplateOptions.Label = display?.Name;
//
var required = GetAttributeFrom<RequiredAttribute>(property);
field.TemplateOptions.IsRequired = required?.AllowEmptyStrings;
//
}
var focusField = model.Fields.First();
focusField.ExpressionProperties["templateOptions.focus"] = focusField.Key;
return model;
}
internal string JsonStringify(T dataModel)
{
if (dataModel == null) throw new ArgumentNullException(nameof(dataModel));
//
var dcr = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
dcr.DefaultMembersSearchFlags |= System.Reflection.BindingFlags.NonPublic;
//
return Newtonsoft.Json.JsonConvert.SerializeObject(Build(dataModel),
new Newtonsoft.Json.JsonSerializerSettings
{
NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore,
ContractResolver = dcr
});
}
private string GetInputTypeFromDataType(DataType? dataType, Type propertyType)
{
if (dataType != null)
{
//
switch (dataType)
{
case DataType.Text:
return "input";
case DataType.Password:
return "password";
case DataType.EmailAddress:
return "email";
case DataType.Html:
case DataType.MultilineText:
case DataType.Custom:
case DataType.DateTime:
case DataType.Date:
case DataType.Time:
case DataType.Duration:
case DataType.PhoneNumber:
case DataType.Currency:
case DataType.Url:
case DataType.ImageUrl:
case DataType.CreditCard:
case DataType.PostalCode:
case DataType.Upload:
default:
break;
}
}
switch (propertyType.Name)
{
case nameof(System.Boolean):
return "checkbox";
default:
return "input";
}
}
}
internal class FormlyModel<T>
{
internal FormlyModel(T dataModel)
{
if (dataModel == null) throw new ArgumentNullException(nameof(dataModel));
//
this.Fields = new List<FormlyField>();
this.Model = dataModel;
this.ExpressionProperties = new Dictionary<string, string>();
}
internal IEnumerable<FormlyField> Fields { get; }
internal T Model { get; }
internal Dictionary<string, string> ExpressionProperties { get; }
internal void AddField(FormlyField field)
{
if (field == null) new ArgumentNullException(nameof(field));
//
((List<FormlyField>)this.Fields).Add(field);
}
}
internal class FormlyField
{
internal FormlyField(string key, string type)
{
if (string.IsNullOrWhiteSpace(key)) throw new ArgumentNullException(nameof(key));
if (string.IsNullOrWhiteSpace(type)) throw new ArgumentNullException(nameof(type));
//
TemplateOptions = new TemplateOptions();
ExpressionProperties = new Dictionary<string, string>();
Key = key;
Type = type;
}
internal string Key { get; }
internal string Type { get; }
internal string HideExpression { get; set; }
internal TemplateOptions TemplateOptions { get; }
internal Dictionary<string, string> ExpressionProperties { get; }
}
internal class TemplateOptions
{
public bool? IsRequired { get; set; }
public string Label { get; set; }
public string Placeholder { get; set; }
}
Apparently, the version of Angular-Formly (6.0.0-beta.1) being used in the example is throwing exception. I remember this was working before. Any way I reverted it to a stable version and its working again.
Here is the jsbin with your formly json that is working as it should:
http://jsbin.com/towozegiqu/edit

How to return response.valid instead of response.d ASP.NET ajax

In my asp.net site I need simple WebMethod that returns to jquery ajax:
{ "valid": true } or { "valid": false }
http://bootstrapvalidator.com/validators/remote/
for that I use code:
public class IsValid
{
public bool valid { get; set; }
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static IsValid ValidUser(string userName)
{
JavaScriptSerializer js = new JavaScriptSerializer();
var jsonData = new IsValid
{
valid = true
};
if (userName.IsEmpty())
{
// it's for other validator.
return jsonData;
}
User user = DbContext.Entity.Users.FirstOrDefault(c => c.UserName == userName.Trim());
if (user != null)
{
jsonData = new IsValid
{
valid = false
};
}
return jsonData;
}
but it returns value in response.d.valid insted of response.valid in js function
xhr.then(function(response) {
dfd.resolve($field, 'remote', response.valid === true || response.valid === 'true', response.message ? response.message : null);
});
How should I change my code to return response.valid ?
Thanks.
Unfortunately you cant adjust Framework 3.5 and plus Services not to return ".d". But if you make some changes on coding like that, you can use as response.valid.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static string ValidUser(string userName)
{
JavaScriptSerializer js = new JavaScriptSerializer(null);
jsonData = new IsValid
{
valid = false
};
return js.Serialize(jsonData);
}
xhr.then(function(response) {
response = jQuery.parseJSON(response);
dfd.resolve($field, 'remote', response.valid === true || response.valid === 'true', response.message ? response.message : null);
});

Categories

Resources