Angular, get data from MVC-method - asp.net-mvc

I know that you can initailise values from an angular controller in a div like this:
View:
<div ng-controller="SimpleController">
<ul>
<li ng-repeat="cust in customers">
{{cust.name}} - {{cust.city}}
</li>
</ul>
</div>
Controller:
function SimpleController($scope) {
$scope.customers = [
{ name: 'Jane', city: 'New York' },
{ name: 'John', city: 'Chicago', }
];
}
But lets say that i want to get the data from a controller (that maybe fetches data from a db) and receive its value in $scope.customers?
Have a look at this method:
public ? PassThisToAngular()
{
var customer = new List<Customer>()
{
new Customer() {Name = "Pauly-D", City = "New Jersey"},
new Customer() {Name = "Snooki", City = "New Jersey"}
};
return ?
}
Can I call this method from my angular-controller and store its values in #scope.customers?
Thank you!

Please check below code, it will help you.
In your script side:
<script>
var SimpleController = function ($scope, $http) {
var result = $http.get("/Contact/PassThisToAngular");
result.success(function (data) {
$scope.customers = data;
});
}
</script>
Controller Side:
public string PassThisToAngular()
{
var customer = new List<MvcApplication1.Models.Customer>()
{
new MvcApplication1.Models.Customer() {Name = "Pauly-D", City = "New
Jersey"},
new MvcApplication1.Models.Customer() {Name = "Snooki", City = "New
Jersey"}
};
var setting = new JsonSerializerSettings{ContractResolver=new
CamelCasePropertyNamesContractResolver()};
return JsonConvert.SerializeObject(customer, Formatting.None, setting);
}

Mvc action
public List<Customer> PassThisToAngular()
{
var customers = new List<Customer>()
{
new Customer() {Name = "Pauly-D", City = "New Jersey"},
new Customer() {Name = "Snooki", City = "New Jersey"}
};
return customers
}
JS:
function SimpleController($scope, $http) {
$scope.customers =[];
$http.get(/[controller name]/PassThisToAngular).then(function(data){
angular.copy(data,$scope.customers )
}, function(){
alert("Can't get data")
});
}

Related

Bootstrap Datetimepicker UK date format posts as US format

I am using the Bootstrap DateTime picker and formatting it to a UK format in a .NET 5 MVC project using a Razor page front end.
The input is as below
<input type="text" asp-for="WeddingDate" class="form-control" onblur="WizardSummary('WeddingDate','SummaryWeddingDate')" required />
And the javascript initialing it
$('.datetimepicker').datetimepicker({
icons: {
time: "fas fa-clock",
date: "fa fa-calendar",
up: "fa fa-chevron-up",
down: "fa fa-chevron-down",
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-screenshot',
clear: 'fa fa-trash',
close: 'fa fa-remove'
},
format: 'DD/MM/YYYY HH:mm:ss'
});
Fairly simple stuff. It all works absolute fine in the front end, it fires, formats the date etc... no issues at all.
However, when I POST the data to the controller for a date with a day > 12 (example todays date - 24/09/2021), it comes through as 0001/01/01 00:00:00 and I think this is because the model expects a standard DateTime, which would be US format and it translates it to this value. I can see in the chrome developer tools it is posting a value in UK format as expected.
Extract of model below
public class WeddingWizardViewModel
{
public DateTime WeddingDate { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
What have I gotten wrong? How can I get my backend to recognise I am posting a valid format?
Update Here is the WizardSummary function, which is purely to copy the content of the input box into a text label that I display on a sumarry screen.
function WizardSummary(input, output) {
var inputvalue = document.getElementById(input).value;
document.getElementById(output).innerHTML = inputvalue;
}
Controller method on submission of form*
[HttpPost]
public async Task<IActionResult> Wizard(WeddingWizardViewModel vm)
{
var user = _userManager.GetUserAsync(User).Result;
vm.TopBar = new TopBarViewModel();
vm.TopBar.PageTitle = "Wedding Wizard";
vm.TopBar.Breadcrumbs = new List<Breadcrumb>();
var level1 = new Breadcrumb
{
Level = 1,
Name = "Weddings",
Controller = "Weddings",
Action = "Index"
};
vm.TopBar.Breadcrumbs.Add(level1);
var level2 = new Breadcrumb
{
Level = 2,
Name = "Wizard",
Controller = "Weddings",
Action = "Wizard"
};
vm.TopBar.Breadcrumbs.Add(level2);
this.ViewData["TopBarViewModel"] = vm.TopBar;
var templatesegments = _context.TemplateSegments.Include(i => i.Shots.OrderBy(i => i.Id)).Where(i => i.TemplateId == vm.TemplateId).ToList() ;
List<Segment> segments = new List<Segment>();
foreach(var templatesegment in templatesegments)
{
Segment newseg = new Segment();
newseg.CompanyId = user.CompanyId;
newseg.Name = templatesegment.Name;
newseg.Created = DateTime.UtcNow;
newseg.Modified = DateTime.UtcNow;
newseg.StartTime = new DateTime(vm.WeddingDate.Year, vm.WeddingDate.Month, vm.WeddingDate.Day, vm.WeddingDate.Hour, vm.WeddingDate.Minute, vm.WeddingDate.Second);
newseg.ReminderInMinutes = 15;
newseg.ClientVisible = templatesegment.ClientVisible;
newseg.Shots = new List<Shot>();
foreach (var templateshot in templatesegment.Shots)
{
Shot newshot = new Shot();
newshot.CompanyId = user.CompanyId;
newshot.Created = DateTime.UtcNow;
newshot.Modified = DateTime.UtcNow;
newshot.Name = templateshot.Name;
newshot.ClientVisible = templateshot.ClientVisible;
newshot.Sequence = templateshot.Sequence;
newseg.Shots.Add(newshot);
}
segments.Add(newseg);
}
Wedding wedding = new Wedding();
wedding.Client1EMail = vm.Client1EMail;
wedding.Client1FirstName = vm.Client1FirstName;
wedding.Client1LastName = vm.Client1LastName;
wedding.Client1FullMobileNumber = vm.Client1FullMobileNumber;
wedding.Client1Role = vm.Client1Role;
wedding.Client2EMail = vm.Client2EMail;
wedding.Client2FirstName = vm.Client2FirstName;
wedding.Client2FullMobileNumber = vm.Client2FullMobileNumber;
wedding.Client2LastName = vm.Client2LastName;
wedding.Client2Role = vm.Client2Role;
wedding.CompanyId = user.CompanyId;
wedding.Description = vm.Description;
wedding.Name = vm.Name;
wedding.Segments = segments;
wedding.WeddingDate = vm.WeddingDate;
_context.Add(wedding);
_context.SaveChanges();
//Image Upload
if (vm.WeddingAvatar != null)
{
var upload = await FileUpload.Upload(vm.WeddingAvatar, _env, user, "weddingavatars", wedding.Id.ToString());
if (upload.Success == true)
{
wedding.WeddingAvatarFileName = upload.FileName;
}
else
{
return BadRequest("Error uploading file");
}
}
_context.Update(wedding);
_context.SaveChanges();
TempData["message"] = "Your wedding has been created and you can now start adding segments and shots to it";
return RedirectToAction("Edit", new { id = wedding.Id });
}
Please, try to set the locale property of your date time picker; in the code bellow sounds an example of UK locale:
$('.datetimepicker').datetimepicker({
icons: {
time: "fas fa-clock",
date: "fa fa-calendar",
up: "fa fa-chevron-up",
down: "fa fa-chevron-down",
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-screenshot',
clear: 'fa fa-trash',
close: 'fa fa-remove',
locale: 'uk'
},
format: 'DD/MM/YYYY HH:mm:ss'
});
And in Back-End, at Controller ActionResult method, add in first line this code bellow:
var cultureInfo = CultureInfo.GetCultureInfo("en-uk");
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;

How can I show related data in full calendar from multiple tables?

I have asp.net mvc site with full calendar. I also created tables like 'Event' and 'Room'. In my event table i have RoomId field.
This is how my function looks:
$(document).ready(function () {
var events = [];
var selectedEvent = null;
FetchEventAndRenderCalendar();
function FetchEventAndRenderCalendar() {
events = [];
$.ajax({
type: "GET",
url: "/CalendarEvent/GetEvents",
success: function (data) {
$.each(data, function (i, v) {
events.push({
eventID: v.Id,
title: v.Job,
description: v.Description,
start: moment(v.Start),
end: v.DutyEnd != null ? moment(v.End) : null,
room: v.RoomId,
});
})
GenerateCalender(events);
},
error: function (error) {
alert('failed');
}
})
}
On this moment, calendar displays Id. How can I refer to another table?
And this is my controller:
public JsonResult GetEvents()
{
using (Context dc = new Context())
{
dc.Configuration.LazyLoadingEnabled = false;
var events = dc.Event.ToList();
return new JsonResult { Data = events, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
}
You will need to join the event table with the room table. In your controller method GetEvents() you can create a select query something along the lines of the following:
var query = (from event in dc.event
join rooms in dc.rooms on event.roomId equals rooms.roomId
select new
{
eventID: event.Id,
title: event.Job,
description: event.Description,
roomId: room.RoomId,
roomName: room.Name
roomSize: room.Size
}).ToList();
Hope this helps.

seeded data is duplicated code first migration

I have seeded the database using code first migration, however I noticed when I view the seeded data in index.html, the data is replicated.
This is the configuration file were I seeded the data:
internal sealed class Configuration : DbMigrationsConfiguration
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(OnlineBookStore.Models.OnlineBookStoreDB context)
{
var books = new System.Collections.Generic.List<Book>
{
new Book {
BookStatus = new BookStatus { Status = "New" },
Genre = new Genre { Name = "Thriller" },
Author = new Author { Name = "Paula Hawkins" },
Title = "The Girl On The Train",
Description = "Rachel catches the same commuter train morning. ",
ISBN = 0552779776,
},
new Book
{
BookStatus = new BookStatus { Status = "Best Seller" },
Genre = new Genre { Name = "Childrens" },
Author = new Author { Name = "Roald Dahl" },
Title = "The Witches",
Description = "Beware. Real witches dress in ordinary clothes",
ISBN = 0141365471,
},
},
};
books.ForEach(s =>context.Books.AddOrUpdate(p => new { p.ISBN, p.Title } ));
context.SaveChanges();
}
}
}
I am really unsure of were I am going wrong, spent days on this!
Really appreciate anyones help! thanks!
You need to specify the key in AddOrUpdate to prevent duplicates since Seed() runs with every update-database issued.
// build your books collection
var books = new []
{
new Book {
BookStatus = new BookStatus { Status = "New" },
Genre = new Genre { Name = "Thriller" },
Author = new Author { Name = "Paula Hawkins" },
Title = "The Girl On The Train",
Description = "Rachel catches the same commuter train morning. ",
ISBN = 0552779776,
},
new Book
{
BookStatus = new BookStatus { Status = "Best Seller" },
Genre = new Genre { Name = "Childrens" },
Author = new Author { Name = "Roald Dahl" },
Title = "The Witches",
Description = "Beware. Real witches dress in ordinary clothes",
ISBN = 0141365471,
},
},
};
context.Books.AddOrUpdate(p => new { p.ISBN, p.Title }, books);
context.SaveChanges();
See http://thedatafarm.com/data-access/take-care-with-ef-4-3-addorupdate-method/

Cannot get value of HtmlAttributes item in kendo MVC treeview

I am using the Kendo MVC wrapper extensions to create a TreeView from my models. I would like to pass some data from the model with HtmlAttributes to the view.
Here is my Action :
public ActionResult Index()
{
var nodeList = new List<TreeViewItemModel>();
nodeList.Add(new TreeViewItemModel
{
Id = "1",
Text = "Item 1",
HasChildren = true,
HtmlAttributes = new Dictionary<string, string>
{
{"class","XXXX"}
},
Items = new List<TreeViewItemModel>
{
new TreeViewItemModel{Id="1.1", Text = "sub Item 1.1",HasChildren = false},
new TreeViewItemModel{Id="1.2", Text = "sub Item 1.2",HasChildren = false}
});
nodeList.Add(new TreeViewItemModel { Id = "2", Text = "Item 2", HasChildren = false });
return View(nodeList);
}
Here is my view :
#using Kendo.Mvc.UI
#model IEnumerable<Kendo.Mvc.UI.TreeViewItemModel>
#(Html.Kendo().TreeView()
.Name("treeView")
.BindTo(Model)
.DragAndDrop(true)
)
Here is the element from Chrome
<li class="k-item k-first" data-id="1" data-uid="6263f4c5-85f3-446c-a843-7d3786fb0f68" role="treeitem" id="treeView_tv_active">
As you can see there isn't any class:XXX in my li Tag So how can I give The XXX class to li Tag?
I can't figure out how to do this automatically, so here's a workaround.
C# passes back a List<Kendo.Mvc.UI.TreeViewItemModel>() to the treeview->datasource->transport->read event:
var items = new List<Kendo.Mvc.UI.TreeViewItemModel>();
////////////////////////////////////////////////////////////////////////////////
// areas of expertise
var aoe = new Kendo.Mvc.UI.TreeViewItemModel()
{
Text = "Areas of Expertise",
Id = "resume-treeview-category-AreasOfExpertise",
HasChildren = false,
HtmlAttributes = new Dictionary<string, string>(){{ "class", "resume-treeview-category"}, {"cat-id", "AreasOfExpertise" }},
};
items.Add(aoe);
return Json(items, JsonRequestBehavior.AllowGet);
I then hook the dataBound event to add the above attributes into the treeview item.
jQuery(document).ready(function ($) {
$("#document-treeview").kendoTreeView({
dataTextField: "Text",
dataSource: {
transport: {
read: {
type: 'POST',
url: "#Url.Action("GetAllTreeData", "Document2")",
contentType: 'application/json; charset=utf-8',
dataType: 'json'
},
parameterMap: function (data, type) {
if (type == "read") {
return JSON.stringify({
id: ResumeId
});
}
}
},
schema: {
model: {
id: "Id",
hasChildren: "HasChildren",
children: "Items"
}
}
},
dataBound: function(e) {
// Apparently reading an item after treeview creation doesn't apply the html attributes. Do that here.
var len = this.dataSource.data().length;
for (var i = 0; i < len; i++)
{
var dataItem = this.dataSource.data()[i];
var uid = dataItem.uid;
var li = $('#document-treeview li[data-uid="' + uid + '"]');
li.addClass(dataItem['HtmlAttributes']['class']);
li.attr('cat-id', dataItem['HtmlAttributes']['cat-id']);
}
}
});
}
Note the HtmlAttributes added from C# are explicitly handled in JavaScript =/

cascading dropdownlist with partial view issue

I have a problem with cascading dropdownlists where the second ddl should appear in a partial view and I can't handle it by myself. Please help me to figure out why I have the following bag?
So, I have a view with the first ddl where the user can choose a brand:
#Html.DropDownList("brands", new SelectList(
#ViewBag.Brands, "Id", "BrandName"),
"--select a Brand--",
new
{
id = "ddlBrands",
data_url = Url.Action("ChooseModel", "Home")
})
<div id="divModel"></div>
The ChooseModel method returns the following partial view :
<div id="chooseModel">
<div class="lead">Model</div>
#Html.DropDownList("models", new SelectList(Enumerable.Empty<SelectListItem>
(), "Id", "ModelName"),
"--select a Model--",
new { id = "ddlModels" })
</div>
When a user selects an item in ddlBrands another dropdownlist for models should appear. So, the script looks like this:
$(function () {
$("#ddlBrands").change(function () {
var url = $(this).data('url');
var value = $(this).val();
$('#divModel').load(url, { id: value });
var brandId = $(this).val();
$('#divModel').html("");
$.getJSON("../Home/LoadModels", { brandId: brandId },
function (modelData) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', {
value: 0,
text: "-- select a Model --"
}));
$.each(modelData, function (index, itemData) {
select.append($('<option/>', {
value: itemData.Value,
text: itemData.Text
}));
});
});
});
});
And, finally, LooksModels method loading the models for the particular brand:
public JsonResult LoadModels(string brandId)
{
if (string.IsNullOrEmpty(brandId))
return Json(HttpNotFound());
var modelList = unitOfWork.ModelRepository
.GetModelListByBrand(Convert.ToInt32(brandId)).ToList();
var modelData = modelList.Select(m => new SelectListItem()
{
Text = m.ModelName,
Value = m.Id.ToString()
});
return Json(modelData, JsonRequestBehavior.AllowGet);
}
So, when I launch the application and choose a brand in the first ddl, the child models showing fine in second one. Then I choose another brand, and again the right models appeared. But when I choose the brand that I chose first time, I can't choose any models - ddlModels shows me only --select a Model--.
Can you please tell me what error in script (I suppose) I have?
Try this Script :
<script type="text/javascript">
$(document).ready(function () {
$("#ddlBrands").change(function () {
firstDDLValue = $("#ddlBrands").val();
$.post('#Url.Action("LoadModels", "Home")', { fstValue: firstDDLValue }, function (result) {
var select = $("#ddlModels");
select.empty();
select.append($('<option/>', { value: '', text: '--Select--' }));
$.each(result, function (index, Data) {
select.append($('<option/>', {
value: Data.Value,
text: Data.Text
}));
});
});
});
});
</script>
Use This at Controller:
public JsonResult LoadModels(string fstValue)
{
YourClassname obj= new YourClassname ();
int Id = 0;
if (fstValue != "")
Id = Convert.ToInt32(fstValue);
var result = obj.GetModelListByBrand(Convert.ToInt32(Id ));
IList<SelectListItem> Data = new List<SelectListItem>();
for (int i = 0; i < result.Count; i++)
{
Data.Add(new SelectListItem()
{
Text = result[i].Text,
Value = result[i].Value,
});
}
return Json(Data, JsonRequestBehavior.AllowGet);
}

Resources