I have a model called Course and another model called SelectedCourse. These two models represent two different tables and have exclusive properties to their own and hence not the same type.
I would like to display List<Course> on my page in the form of multiple check-boxes. The courses that are available in the List<SelectedCourse> should be marked as checked.
How do I build my ViewModel to achieve this?
For Post, I would like to return the list of my ViewModel back to the controller and the POST action. And then be able to only delete/add the items that were modified (selected/un-selected) to the table representing List<SelectedCourse>.
How do I achieve this?
(Because I don't know how to create my ViewModel, I cannot provide cshtml or controller actions to prove effort)
Your ViewModel could contain a list of e.g. CourseViewModel objects, which contains the properties of the Course you are using in the view, but also a bool for representing whether the course is selected. See this question for an example.
Your action method (POST) could take the list of CourseViewModels as argument, which allows the form to post that list of ViewModels back to the controller. See this question for an example.
I have a couple of pages for e.g. Product that look almost the same. I have Product/Add and Product/Modify/{id} pages where one is an empty form to add new Product and the second one comes already filled with data for a current product and can be updated with additional information. Because Razor Pages separates this into Add and Modify PageModels, I have a different cshtml view for each of them.
I tried to use ViewComponents to build reusable parts of these views, but they are only good if all you want to do is display data. Because ViewComponents don't support Binding all I have left is somehow send ajax requests and append the data to submit, which even sounds wrong and probably isn't the right approach.
Is there any other way of creating these pages without duplication?
You can create one page for create and edit by sending a new object of the Product model (with no data in id attribute) and a created object (with data in id attribute) in case of editing. And in the view you can do rendering based on the sent object (whether it is new or not).
I am in need of hopefully an example for a drop down list search function. Not sure what the correct terminology would be.
Needed:
Two drop down lists then a submit button. First being of Country, then the second being of Department. So say you picked France and HR, it would display a contact person below.
Is there any examples of something of this sort? Would be nice have code in CS then have my end user be able to add and link the two together in Sitecore. So they could add Countries they would like, departments they would like, then the respected person linked to the two fields.
So if I understand you correctly, you're taking multiple inputs and producing results for that combination of them. I'll make some assumptions and try to give you enough direction to get started. This will take a bit of explaining.
Starting from scratch, we've got a Contact template that has, at least, a Country and Department field. You'll need templates and lists of items for each of those two fields. You could get these values from another source, but let's just keep it simple for now and use lists of items. This sounds hierarchical, so I'd suggest you define your departments as children of your Country items. What other fields are on these items doesn't really matter at the moment.
Next, you'll want to communicate the end-user's selections back to your Sitecore instance. I'll assume that you're using Sitecore MVC, but the same principles apply for web forms.
Set up a controller to parse your parameters, country and department, and a form in your View with <select> elements populated from the lists of countries and departments. When the country selector is changed, you can either reload the page with the value set as a request parameter or use AJAX to ask your controller directly. If you structure the model so that it doesn't rely on the rendering context, you can submit your form results to /api/sitecore/{controllername}/{actionname}?country={values}&department={values} and get the data that way. (If you want an example of the kind of JS you need to do this I can provide one.) You could disable or hide the Department <select> until this is selected so that users don't get confused, then use the same technique to also set the Department parameter/submit that value. Once those two values are in the request, you have enough information to get a list or single Contact and display that information, also using the same technique.
If you have a more specific question about a particular aspect of this process I'd be happy to explain.
So I have a Model named Parties, that contains a List of Instructors.
I want to create TextBoxFor's based on the properties of the Instructor object.
When I do #Html.TextBoxFor(x => x.Model.Instructors...) I cant get the properties of the Instructor object without using a Select with Linq. If I use linq, I need to dynamically get the specific instructor I want. The information I need to get this instructor is based on a textbox somewhere else on the form, but how could I dynamically get the value of another textbox to satisfy the linq expression?
Depends on what you are trying to achieve. It sounds (vaguely) like what you want is more of a MVVM architecture there, in which case you should be looking at angular or similar. Maybe I misunderstood what you want.
TextboxFor can't generate a textbox for a List of objects. What would you expect it to generate? A list of textboxes? If all you want is a text box that has some unique name, then just pick an instance of one, like #Html.TextBoxFor(x=>x.Model.Instructors.FirstOrDefault().something)
If by "dynamically get the specific instructor I want" means that they will pick it on the client side and you can edit a current existing record, then you probably should be sending down the list of instructors into a javascript array and then writing some client side code to pick it for you. Alternatively, you can make an AJAX call if the list of instructors would be too large. Why would you base it on a Textbox value, shouldn't it be based on a dropdown/select value?
Let's say I have a very huge model that contains lists and even those lists can have objects that contain other lists. I want to create an edit form for that in MVC4 (or 5) without AJAX.
So I figured that the first part of that is to store the entire object on the client side in hidden fields. List binding works like a charm, see http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/. Now the complete roundtrip is working, I can push out the entire object to the client in bound hidden fields, it gets back to me upon submit and the posted hidden fields are put into the complex object, nested lists and everything included.
Lists or other objects should become editable based on some action. One scenario is where a single object or list items are displayed as non-editable, and when the user clicks it, it becomes editable in-place, so for example the cells in a grid become textboxes. Another scenario is where a single object or list items are not shown at all, and when the user clicks a button, a popup window appears with the text input fields.
Is there a library or a proven way to do this?
Is there a library or a proven way to do this?
Exactly what for? Displaying a massive model in view for editing? Making a grid editable? Or popping up the records of a grid for editing?
Basically, I think you are overcomplicating this matter a bit. If you apply some separation of concerns here you will find out how easy everything becomes and in fact it's super easy to implement and most importantly much easier to maintain and scale.
Starting from the model, let's assume you've got this all-mighty massive model named Company with the following properties:
CompanyID (int)
CompanyName (string)
CompanyLegalID (string)
CompanyRegistrationNumber (string)
ContactInfo (ContactInfo class)
HeadQuaterAddress ('Address` class)
Branches (List of Branch classes)
Employees (List of Employee classes)
And the list of properties could go on and on forever.It would be easier, super easier to break down this model into smaller models. Make a CompanyModel model with the following properties...
CompanyID (int)
CompanyName (string)
CompanyLegalID (string)
CompanyRegistrationNumber (string)
Then make a CompanyContactInfo model and so on. Getting the idea? Again, separation of concerns simplifies matters a lot. Then, create action methods and views to read/edit these models.
Now for lists properties of the massive object you'd like to do the same. For example, for the list of Employee objects it'd be easier to create a CompanyEmployeesModel model with the following properties:
CompanyId (int)
Employees (List of EmployeeModel classes)
Then create a controller action method to show the list of employees...
public ActionResult EmployeeList(int companyId)
{
var employees = BusinessLogic.Get_Me_Employees_For(companyId);
CompanyEmployeesModel model = new CompanyEmployeesModel();
model.CompanyId = companyId;
model.Employees = employees;
return View(model);
}
Hope you are getting the idea so far. In the view simply create a css-formatted table to show the employee list, razor makes it super simple...
<table class="grid">
<tr>
<th></th>
<th>
Name
</th>
<th>
Phone
</th>
</tr>
#{
var alt = false;
foreach (var emp in Model.Employees)
{
<tr class="#(alt ? "alt" : string.Empty)">
<td class="cmd">
#ActionLink("edit", "Edit", "Employees", new { empId = emp.Id}, null)
</td>
<td>#emp.Name</td>
<td>#emp.Phone</td>
</tr>
alt = !alt;
}
}
</table>
Notice that the first column of the table has link "edit" that takes the user to the Edit action method of the Employee controller where obviously you will do exactly the same you've been doing with smaller models. All I'm doing is separating the logic, models, view and making them simpler, easier to maintain and easier to understand.
Hope it all makes sense to you
Jeditable http://www.appelsiini.net/projects/jeditable which does the same thing and is easier to implement
The very huge model is a business requirement, it has to be edited as one entity, preferably on one page, it makes perfect sense but I can't talk about it. I originally thought (or hoped) there was an easy to describe solution, but apparently, this isn't a common thing in MVC. It would be very different with AJAX, it has its pros and cons. For sure it's more widely used, hence more documented. Without AJAX, there is only one round-trip, which is a bit bigger, but it's a smoother user experience. Anyway, here's a rough guide how to do it the way I asked.
The client-server roundtrip is handled by MVC with (mostly) hidden fields as I said in the question. Later it can be optimized by encoding some stuff in JSON instead of hidden fields, it doesn't affect the rest of the system.
Normal fields are stored in normal editors, not hidden fields. It makes no difference from the perspective of the client-server roundtrip. So these can be edited in place.
Grid rendering is also easy. Server-side MVC grids are suboptimal in this case, because they would send redundant data to the client side. Luckily there are a lot more client-side grid solutions, they are by nature server platform independent. Just collect the required data from the hidden fields and use a JavaScript grid library to build a grid from it when the page loads. Naturally, as I said, the lists can contain lots of data and other nested lists, but in this simple grid, a few necessary columns must be selected, no problem with that.
Now comes the interesting part, how to edit a grid row with all that complex data. Let's say I have a list of Persons in my model, and they have a list of Addresses. There is a Person grid, and when you click on a row, you want the end user to be able to edit additional data for a Person and also his Addresses.
First of all, the Person editor template has to be sent to the client side in advance. We need to put that editor template inside our view, and hide it. Whenever the user wants to edit a person, we create a JS dialog with the contents of that editor template.
We need to bind the Person editor template to a Person object stored in the hidden fields. Based on which row the user clicked, we get an index, and we bind Model.Persons[index] to that template. Knockout.js is a good candidate for JS binding. It does all the field copying back and forth.
An MVC editor template can also contain validation logic. It's no problem in this case, because we rendered the editor template to the client side as a whole. The validation will happen inside the popup window without any kind of magic. When the user presses the save button, validation will run, and when it succeeds, we use the binding engine to copy the popup contents back into the hidden fields.
It is not the simplest of things, but it is very straightforward. Actually, several different JS libraries are needed, not as I hoped. So if anyone wants to edit a complex model on a single page without AJAX, it is certainly possible. It's still not completely documented because I can't share more details. But it has its advantages: only one round-trip, hence faster user experience, and there's no need to maintain state on the server, all the data is retrieved and saved as one entity in one roundtrip.