I'm currently developing a system which manages work times and analyze them. Therefore I need to add several Time-Stamps once and add/remove some input field dynamically.
The ViewModel looks like:
public class CreateWorkDayViewModel
{
public DateTime Date { get; set; }
public IEnumerable<CreateStampModel> Stamps { get; set; }
}
public class CreateStampModel
{
public string ProjectId { get; set; }
public DateTime From { get; set; }
public DateTime To { get; set; }
}
How to do this with the razer syntax including validation?
I'm developing with Visual Studio Version 15.2 and the latest stable MVC version.
EDIT (17.05.17):
What I've done so far:
I added a jQuery based mechanism to add/remove rows dynamically.
Click for the mechanism
My problem is, that in the part of where I'm adding the rows(at JS line 4) I can't use the razor syntax because this html code is inserted at runtime by jQuery.
I also tried it with the old way and used instead of asp-for name. This works for the post data, but to fill the project drop-down selection I need the data from the ViewModel and this is missing.
Related
I am new to .net core - have been using aspx web pages and .net framework 4.x for a number of years. I have a project where we want to display different controls (textbox, dropdown, checkbox) on the page based on values returned from a query. For example, user chooses "A" from a dropdown list and it shows 10 controls, if they choose object B it shows 8 controls, etc. Previously in .net framework, I would use a content placeholder with an ID and then find that ID and start adding controls (controls.Add(newControl)) in the placeholder. It doesn't seem that is an option with .net core. It seems like this would be a common need for various web applications, but I'm not finding many hits.
Another question is whether this can be done in the code behind or if it has to be done on the client-side. If one of the controls in the list is a dropdown, there will be a query that a subroutine will run to get the Key/Value pairs for the dropdown. To me this means it would be more effective on the server side.
I haven't really found any good examples when I do some searching. Can anyone point me to a good resource or provide me with a basic example - either client-side or server-side? Thanks!
There are many options, but I'll describe a simple one, using server side processing. As you explained in your comment, there will be 2 pages:
One that will display the select element that will be used to choose a set of controls.
The page that will be returned according to the previous choise, displaying the selected set of controls.
I assume that you know how to build the first page.
For the second page, you can leverage the ASP.NET Core MVC pattern to achieve the desired result.
You will need the three usual MVC elements:
An Action in a Controler.
A ViewModel for your Razor View.
A Razor View.
The Action does the following:
Receives the id of the selected set of control (via the Action's parameter).
Uses this id to retrieve the information about the corresponding set of controls from your repository.
Builds a ViewModel out of the received information.
Builds a View using the obtained ViewModel.
Return the builded View.
Here is some simplified example code:
In your controller, add the following method:
#!lang-cs
Public IActionResult GetProgramControlSet(int ProgramId)
{
// Here, use the id to get the data from your repository
// that will be used to build set of controls.
// Supposing you have defined a GetControls method,
// it could look like:
var SelectedControls = MyRepository.GetControls(ProgramId);
// If needed, you can build a ViewModel out of the received SelectedControls.
var SelectedControlsViewModel = new ControlSetViewModel(SelectedControls);
return View(SelectedControlsViewModel)
}
Of course, many things are missing here: error handling, etc...
Here is what the ViewModel could be:
#!lang-cs
public class ControlSetViewModel
{
public string Name { get; private set; }
public List<IControl> Controls { get; private set; }
public ControlSetViewModel(...)
{
// Whatever needs to be done to construct the ViewModel
}
}
public enum ControlKind
{
Button,
Select,
Textarea
//...
}
public interface IControl
{
ControlKind Kind { get; }
}
public class ControlButton : IControl
{
public ControlKind Kind => ControlKind.Button;
public string Label { get; set; }
public string Text { get; set; }
public string Color { get; set; }
// ... All other needed properties for the button
}
public class ControlTextarea : IControl
{
public ControlKind Kind => ControlKind.Textarea;
public string Label { get; set; }
public string PlaceholderText { get; set; }
public string RowCount { get; set; }
// ... All other needed properties for the textarea
}
public class ControlSelect : IControl
{
public ControlKind Kind => ControlKind.Select;
public string Label { get; set; }
public string PlaceholderText { get; set; }
public List<SelectOption> Options { get; set; }
// ... All other needed properties for the select
}
public class SelectOption
{
public string Text { get; set; }
public string Value { get; set; }
}
You could also use inheritance instead of interface for the control classes.
Now the view.
It is a Razor page containing something akin to
#model ControlSetViewModel
#*... some HTML ...*#
<div>
<h1>#Model.Name</h1>
#foreach(var control in Model.Controls)
{
<div>
switch(control.GetControlKind())
{
case ControlKind.TextArea:
var Textarea = (ControlTextarea)control;
<label>#Textarea.Label</label>
<textarea rows="#Textarea.RowCount"/>
break;
case ControlKind.Select:
var Select = (ControlSelect)control;
<label>#Select.Label</label>
<select>
#foreach(var option in Select.Options)
{
<option value="#option.Value">#option.Text</option>
}
</select>
break;
#*... etc ...*#
default:
#*... etc ...*#
}
</div>
}
</div>
#*... More HTML ...*#
Of course this is far to be finished. All the infrastructure and code that will actually react to the displayed controls is missing.
Is it a form you that will be posted?
Is it Javascript code that will react to the control manipulation?
Or another mecanism?
This questions will need to be addressed.
I have a view which has different sections displaying different type of orders from DB (SQL Server). Now I need to refresh view with updated information each time a new order is submitted through Android Application. Below are code snippets:
ViewModel:
public class KitchenViewModel
{
public List<Orders> DisplayOrders { get; set; }
public List<Orders> PreparedOrders { get; set; }
public List<OrderItem> ProgressItems { get; set; }
public List<OrderItem> QueuedItems { get; set; }
public int DisplayOrdCount { get; set; }
public int PreparedOrdCount { get; set; }
public int QueuedOrdCount { get; set; }
}
Controller:
public ActionResult KitchenOrder()
{
KitchenModel kitchenInstance = new KitchenModel();
List<Orders> orders = kitchenInstance.GetProgOrdersList();
List<OrderItem> progressItems = kitchenInstance.GetItemProgress();
List<OrderItem> queuedItems = kitchenInstance.GetItemQueued();
List<Orders> prepOrders = kitchenInstance.GetPrepOrdersList();
List<Orders> queuedOrders = kitchenInstance.GetQueuedOrdersList();
KitchenViewModel viewModel = new KitchenViewModel();
viewModel.PreparedOrders = prepOrders;
viewModel.ProgressItems = progressItems;
viewModel.DisplayOrders = orders;
viewModel.QueuedItems = queuedItems;
viewModel.DisplayOrdCount = orders.Count;
viewModel.PreparedOrdCount = prepOrders.Count;
viewModel.QueuedOrdCount = queuedOrders.Count;
return View(viewModel);
}
As of now I am auto refreshing view after every 15 seconds which is working perfectly.
But I need to refresh view only when a new order is submitted through Android application and order is inserted in DB. Once a new order is submitted the values for PreparedOrders, Progressitems, DisplayOrders gets changed and need to be fetched again. I have read many posts/tutorials relating to Observer pattern and publisher/subscriber method but unable to get crisp solution which would fit best. Could someone please provide relevant pointer/tutorial to use in such a scenario that could help. Being this my very first project and a total beginner, I m quite confused as in how to proceed.
So if you have to update site on event that fires when something changes in base, as other clients have changed it, you need PUSH based architecture, and not PULL based like you do it now (requests on timer elapsed).
For this purpose you can use SignalR, that implements various modern communication mechanisms. The basic idea is: one time client accessed your site, there is a persistent
connection created pointing to it's browser, and in the moment of notification you just roll over all available clients and notify them. On client side, naturally, event is handled in your case with javascript.
Worth mentioning that this technology has limitations across browser versioning, so refer to documentation to see if supported browser versions set satisfies your requirements.
Here is the link to supported platforms list for SignalR2: Supported platforms
I have two Model classes like so:
Program:
public class Program
{
public int ProgramId { get; set; }
public string Name { get; set; }
public virtual Playlist chosenPlaylist { get; set; }
public virtual IList<Playlist> Playlists { get; set; }
}
public class Playlist
{
public int PlaylistId { get; set; }
public string Name { get; set; }
public int NumberVotes { get; set; }
public virtual IList<Song> Songs { get; set; }
}
In my Edit Program View, I want to update the chosenPlaylist so I can allow the user to select none or one of the Program's Playlists.
For example:
Program 1:
Playlist 1
Playlist 2
Chosen Playlist: Playlist 1
So the user can then edit and select None (so no playlist), 1 (won't change anything) or 2 and that gets saved to the database.
I've tried to create a dropdownlist in my Controller but it won't update.
Here's what I have in both my GET and POST Edit ActionResults:
ViewBag.chosenId = new SelectList(program.Playlists, "PlaylistId",
"Name", program.chosenPlaylist.PlaylistId);
And in my View:
#Html.DropDownList("PlaylistId", (SelectList)ViewBag.chosenId)
This displays the list fine and pre-selects the chosen Playlist, if there is one (if not, I'll write code for it to default to the first). If there aren't playlists in a Program, that's easy to control.
However, problems:
Doesn't update my model. If Playlist 2 is the chosen one, for example, and I choose P1, it continues to display P2 after the POST event.
I want to include an option in the dropdownlist for it not to pick any value (so, place a NULL in that field). Is that possible?
There are no errors thrown, everything seems to work except for the most important part - updating the database.
Make sure there are no #Html.HiddenFor or similar rendering the same item.
There's 2 things you can do:
Change #Html.DropDownList("PlaylistId", (SelectList)ViewBag.chosenId) into #Html.DropDownList("chosenPlaylist.PlaylistId", (SelectList)ViewBag.chosenId)
Or use the Html.DropDownListFor(m => m.chosenPlaylist.PlaylistId, (SelectList)ViewBag.chosenId)).
When using:
#Html.DropDownList("PlaylistId", (SelectList)ViewBag.chosenId)
you have to rename the PlaylistId select list to something that is not the same as the propertyname that stores the selected Id, else it wont be marked as selected.
(which makes sense now that im typing it, you cant store the selected value into something that has the same as the select list)
Basically saying:
#Html.DropDownList("MySelectListId", (SelectList)ViewBag.chosenId)
will work.
You can look at the comments on this issue at codeplex for more information: http://aspnet.codeplex.com/workitem/4932
I'm struggling with the design aspect of building this web site, its my first website and I'm not sure of the correct direction i need to take this project in. I've posted on this previously but not done a good job of explaining it. So I'll attempt to do so now.
The Site will be used for submitting "Innovation Ideas" from employees. It will have to connect up to an already existing MS Access Database. There will be two tables in this database that it has to communicate with.
The first one Is the InnovationSubmission Table which which looks similar to this :-
ID(Auto Generated),
Short Description,
Long Description,
Name,
Email Address,
Date(From Date.Time.Now()) - on Submission.
Team Name
Area (Area of Business)
The User will use a Web Form(View) to enter the details above, it will be validated, then saved to the back end database. I have this working in a fashion. The issue has started when I have tried to introduce two DropDownlistsFor contorls based on another table which is below :-
AREA A - Team1, Team3, Team5, Team7
AREA B - Team2, Team4, Team6, Team8
This is just sample Data, there are only two different areas in the table, but there will be over 50 teams split across them. I will be looking to have the Teams dropdownList filter on the value in the Area DropDownlist.
In my Models folder I have created a InnovationSubmission Class, that replicates the table in the database, this class is used as a strongly typed data type in the View representing the Submission Form. Its how i Validate the User input and I pass this class to a c# method that sends the data back using ADO.NET.
I'm struggling with how I should be trying to implement the dropdownlists.
Will I need to create a class similar to the InnovationSubmission Class, to represent the Teams/ Area Table?
Is the table at present structured in the best way for this project?
Can I populate both dropdownlists from the 1 table?
How do I relate the Teams & Area Columns?
Any Help would be greatly appreciated!?!
Would this be the correct way to design my View Model :-
public class MyViewModel
{
public int ID { get; set; }
public string shortDesc { get; set; }
public string longDesc { get; set; }
public string Status { get; set; }
public string originator { get; set; }
public string originatorEmail { get; set; }
public IEnumerable<Area> area { get; set; }
public IEnumerable<Team> team { get; set; }
}
public class Team
{
public string teamName { get; set; }
}
public class Area
{
public string area { get; set; }
}
You seem to be talking about cascading dropdown lists where the values of the second one update based on the selection made in the first one. I have illustrated an example of how this could be achieved in this post. The idea is that you subscribe to the .change event of the first dropdownlist and then trigger an AJAX request to a controller action passing the selected value in which you wold query the database and return a list of possible options.
I've been working with javascript Highcharts and I made a basic 'Chart Builder' app. One of my goals is to have the user create and modify as many options as they like and save those to the db. The main problem I'm having is trying to convert the Highcharts object to a c# class. I've been building it slowly(ie manually) with the parts I need, as I need them, but to eventually get the whole thing converted will take a long time.
Ideally, I'd like to create and setup the whole highcharts options object server side and just send it 100% complete to highcharts
Is there any easy way to do this? Has anyone already done this?
Here is the Highcharts reference page: http://www.highcharts.com/ref/
and this is what I've done so far.
public class Highchart
{
public title title { get; set; }
public plotOptions plotOptions { get; set; }
}
public class title
{
public string text { get; set; }
}
public class plotOptions
{
public series series { get; set; }
}
public class series
{
public string stacking { get; set; }
public string borderColor { get; set; }
public bool shadow { get; set; }
public int borderWidth { get; set; }
}
As you can see, I just started ^_^
Update : The Highcharts .Net library has been updated in December, and is nearly feature complete as per V2.1.9 of the Javascript library.
The .Net library currently has support for multiple axes, point objects, viewstate management after postbacks, click events for points, series etc, and a built in implementation of an AJAX datasource ;) You don't need to write a single line of JS code unless you want to handle click events; you simply code in C#, and the appropriate JS is rendered automatically for you..
Click here to view the Live Demo