angularjs-datetime-picker formatting from Json object - c#

I asked the question to generic so i made a specific case:
Cant implement https://www.npmjs.com/package/angularjs-datetime-picker
I have a class Employee with a List of timeRegistrations.
<link href="~/Content/Angular-Datetimepicker/angularjs-datetime-picker.css" rel="stylesheet" />
<script src="~/Content/Angular-Datetimepicker/angularjs-datetime-picker.min.js"></script>
I added this to my Module
var app;
(function () { app = angular.module( "WorksheetEdit", ['angularjs-datetime-picker']);
I have the following in my HTML:
This is inside a repeater.
<input datetime-picker date-format="yyyy-MM-dd HH:mm:ss" ng-model="timeregistration.StartDate" />
I'm using a $http.get() to return the data from C# controller.
To serialise i'm using :
string isoJson = JsonConvert.SerializeObject(lst);
return Content(isoJson, "application/json");
The problem here seems to be i cant format the date.
It keeps this notation: 2018-02-01T00:00:00

Related

How to pass generic list of values to external js file from controller/view in ASP.NET MVC

The file name is called clik.js here I have to access some values from controller/view
Using view I have tried this code:
<head>
#if (ViewBag.status != null)
{
<script type="text/javascript">
var tagAccess='#ViewBag.status[0]';
</script>
<script src="~/JavaScript/click.js"></script>
}
</head>
Using this code, I could get single value in js file. But I have to get all values
//var tagAccess='#ViewBag.status';
If I write the code like this, I didn't get any output
You can serialize the Item using this:
<script>
var tagAccess = #Html.Raw(Json.Serialize(#ViewBag.status[0]));
</script>

Unable to display WEBAPI data in Angularjs repeat directive

Can somebody help in displaying webapi data in angularjs repeat directive in my first Angular application?
I'm getting data from the WEBAPI as expected like below
[{"FLAVOR_ID":"BES","FLAVOR_NAME":"BES"},{"FLAVOR_ID":"BUN","FLAVOR_NAME":"BUN"}]
API Controller:
public class ItemMaintenanceController : ApiController
{
ItemMaintenanceRepository itemRepository;
public ItemMaintenanceController(ItemMaintenanceRepository _itemRepository)
{
itemRepository = _itemRepository;
}
[HttpGet]
public IEnumerable<MA_Flavor> GetAllFlavors()
{
return itemRepository.GetAllFlavors();
}
}
Client.html:
<!DOCTYPE html>
<html>
<head>
<title> Client</title>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
<script>
alert("start");
var app = angular.module("myapp", ['ngResource']);
var controller = function ($scope, $resource) { // controller uses $resource, which is part of ngResource
$scope.flavor = {};
$scope.getFlavors = function () {
alert("calling getflvors");
var request = $resource("http://localhost:55762/api/ItemMaintenance/GetAllFlavors?Id=CMN");
$scope.flavor = request.query();
};
////$scope.clear = function () {
//// $scope.flavor = {};
//// $scope.error = "";
////}
$scope.getFlavors();
myapp.controller("ItemMaintenanceController", controller);
</script>
</head>
<body ng-app="contacts">
<div ng-controller="ItemMaintenanceController">
<select ng-model="flavor">
<option ng-repeat="fl in Flavor" value="{{fl.FLAVOR_NAME}}">{{fl.FLAVOR_NAME}}</option>
</select>
<h1>You selected: {{flavor.FLAVOR_NAME}}</h1>
</div>
</body>
</html>
Looks like issue with the names of the ng-controller, ng-module and ng-app. Try to change and hope it will work.
<body ng-app="contacts">
<div ng-controller="ItemMaintenanceController">
<Script>
var app = angular.module('contacts', []);
// To fetch all falvors
app.controller("ItemMaintenanceController", function ($scope, $http) {
.....
...
</script>
I think you're close. based on what you have I think something like this should work:
<select ng-model="selectedFlavorId">
<option ng-repeat="fl in flavor" value="{{fl.FLAVOR_ID}}">{{fl.FLAVOR_NAME}}</option>
</select>
your data is in $scope.flavor and I assume that if you debug it will look like this:
$scope.flavor = [{"FLAVOR_ID":"BES","FLAVOR_NAME":"BES"},{"FLAVOR_ID":"BUN","FLAVOR_NAME":"BUN"}]
you want the id in your value field as that is the bit you need to know which value you selected. the value you see in dropdown should be the name of the flavor.
when you select something, that value will be reflected in the model.
as I chose selectedFlavorId, you will find that populated under $scope.selectedFlavorId. Do not override your API data with the selected value like you've just done.
selectedFlavorId will give you the ID of the item you selected so you need a bit more code after this to get the name of that property from your data array.
There may following issues in your code.
Your angular modules defined as myapp and in ng-app you have used
contacts.
You have to create two different scope variables, one for the flavor
and another is flavors. flavors you need to use under the ng-options
and flavor you have to use for ng-model.
What I understood request.query() will return the resource object,
So have two options to get data from the query. More details about
the resource you can find here
var request = $resource("http://localhost:55762/api/ItemMaintenance/GetAllFlavors?Id=CMN");
Option 1
request.query(function(data) {
$scope.flavor = data;
});
Option 2
request.query().$promise.then(function(data) {
// success
$scope.flavor = data;
}, function(errResponse) {
// fail
});

Pass Data from View to Controller - with model

I need to pass some information from the View to the Controller.
Currently, I am doing something like the following:
var url = '#Url.Action((object)#ViewBag.CompID, "Print", "DataRecords")' + '?location=' + model.Location + '&startDate=' + model.StartDateTime + '&endDate=' + model.EndDateTime;
window.location.href = url;
I wanted to hide the location, startdate and end date from showing up in the browser url.
I was thinking about creating a model as shown below and sending the model to the Controller but not sure how to.
var model = {
Location: $('#Location :selected').val(),
StartDateTime: $("#StartDate").val(),
EndDateTime: $("#EndDate").val()
};
Note that in my case, I do not need to retrieve any data back as the Print method will do the printing.
I am open to accomplishing this besides using
window.location.href
How can this be done using AJAX as I do not need to return back to the view with any data as the Print method action will print the the appropriate view.
If you want to pass data from the front end to the back-end controller, you have two ways:
through a GET(passing parameters on the URL)
with a POST that you can do it via AJAX or simply putting your information inside a form with POST action to the method you want to hit in the controller
MVC will do the binding for you, all the information using the POST, for example, should be inside the form, then on the controller, you can create your model as the input and use the default MVC bindings.
My suggestion if you want to hide that information from the url is to do it via a post(inside a form with a submit), but anyways if you click on the Network tab of the browser in both cases you should see the parameters you are passing to your controller.
There are other ways to achieve the same thing as the use of the TempData dictionary, which keeps information for a roundtrip operation between the controller and the view, but I don't recommend to proceed this way, every time I use that as a backdoor to patch my problems I feel guilty
You can do this.
Controller
public class HomeController : Controller
{
public ActionResult HideQueryString()
{
return View("Tut143");
}
public ActionResult Print(string location, string startDate, string endDate)
{
//print here
return RedirectToAction("HideQueryString");
}
public ActionResult Tut143()
{
return View();
}
View:
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Tut143</title>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(function () {
$("#theButton").click(function () {
var model = {
Location: $('#Location :selected').val(),
StartDateTime: $("#StartDate").val(),
EndDateTime: $("#EndDate").val()
};
var url = '#Url.Action("Print", "Home")' + '?location=' + model.Location + '&startDate=' + model.StartDateTime + '&endDate=' + model.EndDateTime;
window.location.href = url;
})
})
</script>
</head>
<body>
<div>
<select id="Location">
<option value="Arizona">Arizona</option>
<option value="California">California</option>
<option value="Wyoming">Wyoming</option>
<option value="Delaware">Delaware</option>
</select>
<input id="StartDate" type="text" value="default startdate value" />
<input id="EndDate" type="text" value="default enddate value" />
<input id="theButton" type="button" value="Go" />
</div>
</body>
</html>

Add CSS references to page's <head> from a partial view

Is there a way to add CSS references to a page from a partial view, and have them render in the page's <head> (as required by the HTML 4.01 spec)?
If you're using MVC3 & Razor, the best way to add per-page items to your section is to:
1) Call RenderSection() from within your layout page
2) Declare a corresponding section within your child pages:
/Views/Shared/_Layout.cshtml:
<head>
<!-- ... Rest of your head section here ... ->
#RenderSection("HeadArea")
</head>
/Views/Entries/Index.cshtml:
#section HeadArea {
<link rel="Stylesheet" type="text/css" href="/Entries/Entries.css" />
}
The resultant HTML page then includes a section that looks like this:
<head>
<!-- ... Rest of your head section here ... ->
<link rel="Stylesheet" type="text/css" href="/Entries/Entries.css" />
<head>
You could also use the Telerik open source controls for MVC and do something like :
<%= Html.Telerik().StyleSheetRegistrar()
.DefaultGroup(group => group
.Add("stylesheet.css"));
in the head section
and
<%= Html.Telerik().ScriptRegistrar()
.DefaultGroup(group => group
.Add("script.js"));
in the script section at the botttom of your page.
And you can keep adding scripts on any view , or partial view and they should work.
If you don't want to use the component you can always inspire yourself from there and do something more custom.
Oh, with Telerik you also have options of combining and compressing the scripts.
You could have the partial view load in a javascript block that drops in the style to the head, but that would be silly considering that you probably want the javascript block in the head section for the same reason.
I recently discovered something pretty cool though. You can serialize a partial view into a string and send it back to the client as part of a JSON object. This enables you to pass other parameters as well, along with the view.
Returning a view as part of a JSON object
You could grab a JSON object with JQuery and ajax and have it loaded with the partial view, and then another JSON property could be your style block. JQuery could check if you returned a style block, if so then drop it into the head section.
Something like:
$.ajax(
{
url: "your/action/method",
data: { some: data },
success: function(response)
{
$('#partialViewContainer).html(response.partialView);
if (response.styleBlock != null)
$('head').append(response.styleBlock);
}
});
You can use a HttpModule to manipulate the response HTML and move any CSS/script references to the appropriate places. This isn't ideal, and I'm not sure of the performance implications, but it seems like the only way to resolve the issue without either (a) a javascript-based solution, or (b) working against MVC principles.
Another approach, which defeats the principles of MVC is to use a ViewModel and respond to the Init-event of your page to set the desired css/javascript (ie myViewModel.Css.Add(".css") and in your head render the content of the css-collection on your viewmodel.
To do this you create a base viewmodel class that all your other models inherits from, ala
public class BaseViewModel
{
public string Css { get; set; }
}
In your master-page you set it to use this viewmodel
<%# Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<BaseViewModel>" %>
and your head-section you can write out the value of the Css property
<head runat="server">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
<%= Model.Css %>
</head>
Now, in your partial view you need to have this code, which is kinda ugly in MVC
<script runat="server">
protected override void OnInit(EventArgs e)
{
Model.Css = "hej";
base.OnInit(e);
}
</script>
The following would work only if javascript were enabled. it's a little helper that i use for exactly the scenario you mention:
// standard method - renders as defined in as(cp)x file
public static MvcHtmlString Css(this HtmlHelper html, string path)
{
return html.Css(path, false);
}
// override - to allow javascript to put css in head
public static MvcHtmlString Css(this HtmlHelper html,
string path,
bool renderAsAjax)
{
var filePath = VirtualPathUtility.ToAbsolute(path);
HttpContextBase context = html.ViewContext.HttpContext;
// don't add the file if it's already there
if (context.Items.Contains(filePath))
return null;
// otherwise, add it to the context and put on page
// this of course only works for items going in via the current
// request and by this method
context.Items.Add(filePath, filePath);
// js and css function strings
const string jsHead = "<script type='text/javascript'>";
const string jsFoot = "</script>";
const string jsFunctionStt = "$(function(){";
const string jsFunctionEnd = "});";
string linkText = string.Format("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\"></link>", filePath);
string jsBody = string.Format("$('head').prepend('{0}');", linkText);
var sb = new StringBuilder();
if (renderAsAjax)
{
// join it all up now
sb.Append(jsHead);
sb.AppendFormat("\r\n\t");
sb.Append(jsFunctionStt);
sb.AppendFormat("\r\n\t\t");
sb.Append(jsBody);
sb.AppendFormat("\r\n\t");
sb.Append(jsFunctionEnd);
sb.AppendFormat("\r\n");
sb.Append(jsFoot);
}
else
{
sb.Append(linkText);
}
return MvcHtmlString.Create( sb.ToString());
}
usage:
<%=Html.Css("~/content/site.css", true) %>
works for me, tho as stated, only if javascript is enabled, thus limiting its usefulness a little.

ASP.NET MVC & JQuery Dynamic Form Content

I would like to dynamically add fields to an ASP.NET MVC form with JQuery.
Example:
<script language="javascript" type="text/javascript">
var widgets;
$(document).ready(function() {
widgets = 0;
AddWidget();
});
function AddWidget() {
$('#widgets').append("<li><input type='text' name='widget" + widgets + "'/></li>");
widgets++;
}
</script>
<ul id="widgets">
</ul>
This works, but I was going to manually iterate the form values in the controller:
[AcceptVerbs("Post")]
public ActionResult AddWidget(FormCollection form)
{
foreach (string s in form)
{
string t = form[s];
}
return RedirectToAction("ActionName");
}
But it occurred to me when I send the user back to the Get Action in the Controller I will have to set the FormData with the values entered and then iteratively add the widgets with <% scripting.
What is the est way to do this in the current release (5 I believe)?
My solution could be something like this (pseudo-code):
<script language="javascript" type="text/javascript">
var widgets;
$(document).ready(function() {
widgets = 0;
<% for each value in ViewData("WidgetValues") %>
AddWidget(<%= value %>);
<% next %>
});
function AddWidget( value ) {
$('#widgets').append("<li><input type='text' name='widget" + widgets +
"'>" + value + "</input></li>");
widgets++;
}
</script>
<ul id="widgets">
</ul>
And in the controller:
[AcceptVerbs("Post")]
public ActionResult AddWidget(FormCollection form)
{
dim collValues as new Collection;
foreach (string s in form)
{
string t = form[s];
collValues.add( t )
}
ViewData("WidgetValues") = collValues;
return RedirectToAction("ActionName");
}
You can work out the details later
(sorry for mixing VB with C#, I'm a VB guy)
i might be missing the point here, but, do you need to actually post the data back to the controller via a form action? why not make an ajax call using jquery to post the data to the controller...or better yet a web service? send the data async and no need to rebuild the view with the data values sent in.
This works fine if the values are being consumed and never used again, however, if you plan on persisting the data and surfacing it through a the view, your model should really support the data structure. maybe a Dictionary<string, string> on the model.
I'm not a ASP.net developer but I know from PHP that you can use arrays as names for input fields
Ex:
<input type="text" name="widgets[]" />
<input type="text" name="widgets[]" />
You can then iterate through the post variable widgets as if it was an array of values.
No messing around with dynamicaly named variables etc.
As far as I understand the problem is to preserve the posted values in widgets.
I thik you can just render those widgest you wont to populate on the server during the View rendering.

Categories