How to display the Lookup icon automatically to select Opportunity on a custom visualforce page? - visualforce

My expectation is to display lookup icon next to Opportunity field. The results received from custom class in controller.
I am trying to display the opportunity name, but am expecting to display with lookup icon next to it which allows user to select another opportunity. My intention is update the record with another opportunity if user decides to do.
<apex:inputField value="{!result.oppty.Name}"/>
public class SearchResultController {
public List<SearchResult> resultList {get; set;}
public SearchResult searchResult {get; set;}
public SearchResultController() {
searchResult = new SearchResult();
getSearchResults();
}
public class SearchResult {
public Id acctId {get; set;}
public Opportunity oppty {get; set;}
}
public void getSearchResults() {
// populate resultList.
}
}
Expected: SearchResults displayed using pageBlockTable. Display lookup icon next to opportunity name.

One way we found the solution is below:
Create an object (kind of dummy object) with all the lookup fields that we wanted. Add it to the Controller as instance variable.
In UI, display this dummy object with opportunity which automatically displays the standard look up icon and functionality.
Once user selects the opportunity values and saves / submits, map the dummy object ID into SearchResult object's oppty in the Controller.

Related

Using a viewmodel which ignores the properties from the model

I'm using entity framework and MVC (both CORE if that matters) to make a site. Using the model and tying it directly to the view is fine all the CRUD actions work, everything is lovely.
I wanted to use a couple of pages to access the model so the site looked better, so split the controls out onto separate views and added a corresponding viewmodel for each, so my project looks like this
-Model
--CustomerModel
-ViewModel
--CustomerNameVM
--CustomerAddressVM
-View
--CustomerNameView
--CustomerAddressView
The CustomerModel has a number of properties
Forename
Surname
Address
Postcode
with Forename and Surname in the CustomerNameVM and Address and Postcode in CustomerAddressVM. Surname is defined as [Required] in the model but not in CustomerNameVM which I believe is the correct way to do it.
I'm struggling to get the model loaded into the viewmodel and then trying to save it when I'm editing the address details in CustomerAddressView because it errors when I try and save as the viewmodel doesn't contain Surname (from the model), so it's null and therefore the [Required] criteria isn't being met.
I've tried a few methods of trying to get past this like :-
Jeffrey Palermo's Onion Architecture
Repositories
domain models
amongst others which all end up with the same problem, I can't save the Address as the Surname is null.
How do I ignore validation criteria for the properties of the model that aren't being referenced in the viewmodel?
Or how do I load and reference only those properties of the model that are present in viewmodel?
Edit
For those who keep asking for code, which codeset? I've tried 30 of them now, none of which do the job. Which one of these do you want? I'm trying to get a general idea of how this is supposed to work as none of the methods, documentation and associated examples function.
Here's a starter for 10, it's unlike the other 29 codesets but it's code and probably the shortest.
The controller
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Step2Address(int? id, [Bind("CustomerID,txtAddress,txtPostcode")] VMAddress VMAddress) {
if (ModelState.IsValid) {
//the saving code
}
return View(VMAddress);
}
the model
public class clsCustomer {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CustomerID { get; set; }
public string Forename { get; set; }
[Required]
public string Surname { get; set; }
public string Address { get; set; }
public string Postcode { get; set; }
the viewmodel
public class VMAddress {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CustomerID { get; set; }
public string Address { get; set; }
public string Postcode { get; set; }
}
the view
#model theProject.Models.VMStep2Contact
<form asp-action="Step2Address">
<input type="hidden" asp-for="ComplaintID" />
<input asp-for="txtAddress"/>
<input asp-for="txtPostcode"/>
<input type="submit" value="Save" />
the context
public class ContextCustomer : DbContext {
public ContextCustomer(DbContextOptions<ContextCustomer> options) : base(options) {
}
public DbSet<clsCustomer> Customer{ get; set; }
}
Clicking "Save" on the webpage calls the controller straight away, which hits the first line if (ModelState.IsValid) and as the Surname isn't set and is [Required] the ModelState is not valid so no save is attempted.
I don't actually understand what the problem is, and without code, it's impossible to say what you might be doing wrong. Generally speaking, you shouldn't have any issues since you're using view models.
A view model is, of course, not saved directly to the database, so it has to be mapped over to an actual entity class that you will be saving. In the case of an edit, you should retrieve all relevant entities from the database, map any posted values onto the appropriate properties on those entities, and then save those entities back to the database. If you're doing this, presumably, the customer model should already contain the Surname and other required properties, and you'd only be modifying/setting the address properties.
If you're doing a create, then, simply you can't just take address information. You need the name as well, so for this, you'd need to pass a view model that contains at least all required fields, such that you have all the information you need to actually save the entity.
If you're trying to do a multi-step form, where you collect all the information over multiple posts, then you simply must persist the posted data somewhere other than the database until you have enough of it to actually save an entity to the database. This is usually accomplished via Session/TempData.

serialize null navigation property

I have simple class:
public class Person
{
public string Name {get; set;}
public Address Address {get; set;} // can be null
}
When I query Person I want webapi return me empty Address property. I tryed the following:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings()
{
NullValueHandling = Newtonsoft.Json.NullValueHandling.Include,
};
but, nothing chaged, it's just not exist in result.
You don't need to configure the formatter, just add $expand query option:
GET ~/Person?$expand=Address
I tried, it works. and I'm using WebApi OData for OData v4.
{
"#odata.context":"http://jinfutan13:9123/$metadata#Albums/$entity",
"ID":5,"Name":"Name 5",
"Singer":null
}
Where Singer is also a navigation property.

MVC3: Pass ICollection from View to controller

I have a model with an property of type icollection.
public class myClass{
public string param1{get; set;}
public string param2{get; set;}
public virtual ICollection<myClass2> param3{get; set;}
public myClass()
{
param3 = new hashSet<myClass2>();
}
}
public class myClass2{
public string param4{get; set;}
public string param5{get; set;}
public virtual myClass param6{get; set;}
}
I pass the model containing these two class to my view and am able to see the items in my icollection by using foreach(var item in Model.myClass.param3)
And I store the items in a hidden field to retrieve it in my controller
foreach(var item in Model.myClass.param3){
#Html.HiddenFor(model => item.parm4);
#Html.HiddenFor(model => item.parm5);
}
But when I submit the form and pass the model to the controller, I get a count = 0 when calling model.myClass.param3.
How can I pass an ICollection to my view?
I tried this link but do not know why it is not working.
EDIT
The link uses the class Book as a list in order to index (suggesting I should cast the ICollection to a list). How do I do that? Also, if I cast it to a list how do i pass that to the controller as the controller expects to receive an ICollectiion?
You can't use a foreach loop for that, you have to use a for loop.
for (int i=0; i<Model.MyClass.param3.Count; i++)
{
#Html.HiddenFor( model => model.MyClass.param3[i])
}
The reason for this is the HiddenFor helper needs some way of assigning unique names to each field for the model binding to work. The i variable accomplishes this.
In your case you;ll need to do some refactoring to implement this. I don't think ICollection or HashSet supports indexing, so you'll need to cast it to a List or some collection that does support indexing.
See this excellent blog post on the subject.

How to make single controller for two database classes - MVC3

I have two database classes as defined below:
public class TopDate
{
[Key]
public int DateId { get; set; }
public DateTime Date { get; set; }
}
public class TopSong
{
[Key]
public int SongId { get; set; }
public string Title { get; set; }
public int DateId { get; set; }
}
where DateId is foreign key to TopSong
I am creating a controller through which i can create, delete or edit these database values.
When i right click on controller class and add controller i can only select one of the two classes defined above. Is there a way to make 1 controller to handle database updates to both these tables on one page?
Error Image:
Your controller should not be dealing directly with domain objects (meaning those things that are directly associated with your database). Create a ViewModel that contains the properties that you need, use your service layer to populate the ViewModel and your controller will use that as the Model for its base. An example of your ViewModel could be something like the following given your description above:
public class MusicViewModel
{
public int SongId {get;set;}
public string Title {get;set;}
public IEnumerable<DateTime> TopDates {get;set;}
}
This view model would contain a list of all dates that a specific song was a Top Song.
The objects you showing (code) are database classes (so called domain objects).
What you need to do is to define a view model, a standard ASP MVC practice:
you define a class, that is tailored for specific view and only containing data relevant to that particular view. So you will have a view model for a view that will create a song, another that will update it etc.
Actually situation you describing is classical situation to use view models. Using domain objects in the views, however, is really really bad practice and prone to more problems than you want to deal with.
Hope this helps.

MVC - Multiple Model One Data

For example, in an IDE application, say for C#, there are 2 views ClassView and TextView.
In ClassView we need to display the Class information in a hierarchical manner, where as in TextView the code for that Class is shown.
The ClassView needs to query for classes, methods, properties, fields, etc. whereas the Text View queries lines in the code.
Both the views are editable. Change in one view should be reflected in the other view too.
So Class View requires one model and Text View requires another but the underlying data is the same.
Is there a design pattern to solve such a problem?
Thanks in advance.
Certainly an MVC model can be hierarchical. If your data is all contained in a single file, maybe you don't really need multiple models for your application? How about:
namespace MyNamespace
{
public class CodeFile
{
/// <summary>
/// A list of contained classes for the Class view
/// </summary>
public List<CodeClass> Classes { get; set; }
public CodeFile()
{
Classes = new List<CodeClass>();
}
public string ToString()
{
// send output to Text view
}
}
public class CodeClass
{
public string ClassName {get; set;}
public List<CodeProperty> Properties {get; set;}
public List<CodeMethod> Methods {get;set;}
public CodeClass(string className)
{
ClassName = className;
Properties = new List<CodeProperty>();
Methods = new List<CodeMethod>();
}
}
public class CodeMethod
{
public string MethodName { get; set; }
}
public class CodeProperty
{
public string PropertyName
}
}
Model View Controller :)
The mistake in your question is that your data is actually mapped on your model.
You can have 2 views (classview and textview) and they both works with one single common model. Controller can update one view when another one changes the model.
You tagged it yourself with MVC... The underlying data is the model, the Class View and Text View act as views/controllers. The model sends out events to its views, to make sure that changes in one view are reflected in the other.
There's nothing in MVC architecture to prevent writing multiple model hierarchies which interact with the same underlying data store.
You would just have Controllers/Views which interact with Model A, and different Controllers/Views which interact with Model B.

Resources