How to fill a dropdown list dynamically in MVC3? - asp.net-mvc

I'm creating a search application in mvc3 where I have 2 tables :
1.State:Id(pk) and state_name
2.District:Id(pk),s_id(f.k.), District_name
I am using code first and EF and have database created for it called Search
I want my index to show all states in drop down list
following is my State.cs code
public partial class State
{
public State()
{
this.Districts = new HashSet<District>();
this.Search_master = new HashSet<Search_master>();
}
public int Id { get; set; }
public string State_name { get; set; }
public virtual ICollection<District> Districts { get; set; }}
this is my District class:
public partial class District
{
public District()
{
this.Search_master = new HashSet<Search_master>();
}
public int Id { get; set; }
public string District_name { get; set; }
public int StateId { get; set; }
public virtual State State { get; set; } }
How can I call the data stored in my tables in my index page
thank you in advance!!

You can use JQuery to bind to the onChange event of the State dropdown. And do an ajax call passing the stateId to the server that will return a json list with the correct districts.
Look here for a sample
Update
on how to populate a dropdownlist look here

Pass the contents of the first dropdown in the model and use a
#Html.DropDownListFor(m => m.MyList)
Bind to the change event and send a jQuery ajax call to a server method you create in a controller. Pass the dynamic list back using JSON and parse the results. Manually add them to your dropdown.
Alternatively just do a full post back and send the second list back in the model, hiding the other dropdown while it has an empty result set.

Related

how to perform pagination in List inside a model in mvc razor

I have a model like:
public class Customer
{
public string Name { get; set; }
public string Address { get; set; }
public List<Contacts> ContactList { get; set; }
}
public class Contacts
{
public string Name { get; set; }
public string Phone { get; set; }
}
Now in razor view, if we call the model like
#model MvcApp.Models.Customer
how to perform paging operation on ContactList that is inside the Customer model using PagedList or something.
Any help ?
Thanks in advance
If you want easy client side pagination then https://datatables.net/ would be your best option. Put Contacts into PartialView, make list displayed as table, apply datatables module, and it should look good. If you want to use IPagedList then you would have to reload view every time when user clicks new page, because IPageList return one page at the time, and use of it on client side is not very good practice. However if you are ready to server calls:
public class Customer
{
public string Name { get; set; }
public string Address { get; set; }
public IPageList<Contacts> ContactList { get; set; }
}
Just load ContactList with page data on Server side every time when user clicks page.

MVC Entity relationship - how to add child to entity as it's being created

I have a BasinPeak entity with a default controller created in an MVC project. When I open http://XX.XX.XX.XX:51573/BasinPeak/Create and add a new BasinPeak, how can I attach a new Note to the BasinPeak at this time?
I want to call the Create action from the NoteController but when the new Note was created how could I then pass the NoteId back to the BasinPeak?
Or is there a much easier way to add the Note and have it linked to the BasinPeak
public class BasinPeak
{
public int Id { get; set; }
public DateTime DateTime { get; set; }
public int Edus { get; set; }
public int Rating { get; set; }
public int? NoteId { get; set; }
public virtual Note Note { get; set; }
}
public class Note
{
public int Id { get; set; }
public String Notes { get; set; }
public DateTime When { get; set; }
public String PersonId { get; set; }
public String History { get; set; }
}
you should ideally create a Basin Peak First and then create a note attached to that BasinPeak
if you want the user should not leave the page where the BasinPeak was created then try using ajax which ideally should be like this.
you hit url BasinPeak/Create<br>
form loaded to create basin peak
you fill in the values and hit submit
send request using ajax (try using juery form ajax)
if the creation of the BasinPeak is successfull return true with id of the recently created BasinPeak.
show him the markup to create a form. because now you have id of the created BasinPeak you can send another request to add the note to the created BasinPeak.
Still if you want to create then in one go then. you can try creating a seperate view model. containing values of the BasinPeak to be created and the values of the note to be created. Make the View strongly type to this View Model and create the Peak and the Note accordingly

MVC MultiSelect modelbinding

i want to be able to display and update my User's Organisations preferably using the htmlhelper Html.TextBoxFor(
I have an entityframework 5 database first database with relationships defined as expected on the 3 tables
User
Organisation
UserOrganisation
which yield the classes below
public partial class User
{
public System.Guid UserId { get; set; }
public string Fullname { get; set; }
...
}
public partial class Organisation
{
public int OrganisationID { get; set; }
public string Title { get; set; }
...
}
public partial class UserOrganisation
{
public System.Guid UserId { get; set; }
public int OrganisationID { get; set; }
}
I pass in the user as the model and also populate a list of potential organisations in the viewbag i.e.
ViewBag.PossibleOrganisations = OrganisationFactories.GetOrganisations()
and the razor markup is.
#Html.ListBoxFor(model => model.UserOrganisations,
new MultiSelectList(ViewBag.PossibleOrganisations,"OrganisationID","Title"))
Now this displays the list of Organisations correctly and i can multiselect them. But it doesn't show the selected Organisations, and it also wont write this back to the database when posting back (incidentally all other fields did write back prior to this change).
Does anyone have any suggestions or examples of a multiselect list working in this fashion?
Cheers
Tim

MVC 4, Upshot entities cyclic references

I have a DbDataController which delivers a List of Equipment.
public IQueryable<BettrFit.Models.Equipment> GetEquipment() {
var q= DbContext.EquipmentSet.OrderBy(e => e.Name);
return q;
}
In my scaffolded view everything looks ok.
But the Equipment contains a HashSet member of EquipmentType. I want to show this type in my view and also be able to add data to the EquipmentType collection of Equipment (via a multiselect list).
But if I try to include the "EquipmentType" in my linq query it fails during serialisation.
public IQueryable<BettrFit.Models.Equipment> GetEquipment() {
var q= DbContext.EquipmentSet.Include("EquipmentType").OrderBy(e => e.Name);
return q;
}
"Object Graph for Type EquipmentType Contains Cycles and Cannot be Serialized if Reference Tracking is Disabled"
How can I switch on the "backtracking of references"?
Maybe the problem is that the EquipmentType is back-linking through a HashSet? But I do not .include("EquipmentType.Equipment") in my query. So that should be ok.
How is Upshot generating the model? I only find the EquipmentViewModel.js file but this does not contain any model members.
Here are my model classes:
public class Equipment
{
public Equipment()
{
this.Exercise = new HashSet<Exercise>();
this.EquipmentType = new HashSet<EquipmentType>();
this.UserDetails = new HashSet<UserDetails>();
}
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Picture { get; set; }
public string Link { get; set; }
public string Producer { get; set; }
public string Video { get; set; }
public virtual ICollection<EquipmentType> EquipmentType { get; set; }
public virtual ICollection<UserDetails> UserDetails { get; set; }
}
public class EquipmentType
{
public EquipmentType()
{
this.Equipment = new HashSet<Equipment>();
this.UserDetails = new HashSet<UserDetails>();
}
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public virtual ICollection<Equipment> Equipment { get; set; }
public virtual ICollection<UserDetails> UserDetails { get; set; }
}
try decorating one of the navigation properties with [IgnoreDataMember]
[IgnoreDataMember]
public virtual ICollection<Equipment> Equipment { get; set; }
The model generated by upshot can be found on the page itself. In your Index view you will see the UpshotContext HTML helper being used (given that you are using the latest SPA version), in which the dataSource and model type are specified.
When the page is then rendered in the browser, this helper code is replaced with the actual model definition. To see that, view the source code of your page in the browser and search for a <script> tag that starts with upshot.dataSources = upshot.dataSources || {};
Check here for more info about how upshot generates the client side model.
As for the "backtracking of references", I don't know :)
I figured out - partially how to solve the circular reference problem.
I just iterated over my queried collection (with Include() ) and set the backreferences to the parent to NULL. That worked for the serialisation issue which otherwise already breaks on the server.
The only problem now is the update of a data entity - its failing because the arrays of the referenced entitycollection are static...
To solve the cyclic backreference, you can use the IgnoreDataMember attribute. Or you can set the back reference to NULL before returning the data from the DbDataController
I posted a working solution to your problem in a different question, but using Entity Framework Code First.
https://stackoverflow.com/a/10010695/1226140
Here I show how to generate your client-side model manually, allowing to you to map the data however you please

Passing complex object from view to controller/view in ASP.NET MVC

In my MVC application I have a problem with passing data from view to controller. I have fairly complex domain classes:
public class TaskBase : PersistableObject
{
public virtual TaskCategory Category { get; set; }
public virtual IList<TaskNote> Notes { get; set; }
public virtual string TaskTitle { get; set; }
public virtual string TaskBody { get; set; }
public virtual DateTime? CreationTime { get; set; }
public virtual User CreatedBy { get; set; }
public virtual int CompletionRatio { get; set; }
}
public class MainTask : TaskBase
{
public virtual IList<TaskBase> ChildTasks { get; set; }
public virtual User AssignedTo { get; set; }
public virtual IList<TaskHistory> History { get; set; }
}
public class TaskFormModel : ViewDomainBase
{
public MainTask Task { get; set; }
public LoginForm LoginInfo { get; set; }
}
And in my view I want to pass an instance of TaskFormModel to the controller.
<%= Html.ActionLink<TaskController>("Edit Task", (x) => x.Edit(new TaskFormModel() { Task = item, LoginInfo = Model.LoginInfo }))%>
And here is the controller action:
public ActionResult Edit (TaskFormModel taskInfo)
{
return View(ViewPageName.TaskDetailsForm, task.Task);
}
In this action method taskInfo comes null even if I pass non-null instance from view. I think I have a binding problem here. I think, writing custom model binder requires every property to be converted and also when new fields added then binder class should also be changed, so I don't want custom model binder to do this. Is there any other way to pass data to controller in this scenario? Or could custom model binder can be coded so that less code written and also when new properies are added binder class will not need to be changed?
Edit After Comments: What I am trying to achieve is basically to pass an instance from one view to another view, without querying repository/db in my controller's action.
First version of answer:
Your GET edit method should be like:
public ActionResult Edit (int id)
{
var model = taskRepository.GetTaskEditModel(id);
return View(ViewPageName.TaskDetailsForm, model);
}
and ActionLink:
<%= Html.ActionLink("Edit Task", "Edit", "Task", new { model.Task.id })%>
If you want to pass complex objects to controller, you should wrap them up in html form and pass to POST action.
In my opinion you are doing something wrong.
As I understand: you are trying to instantiate a new object, pass it to browser and get it back.
well you cant.
If object you want to edit exists already in your storage, then you should alter your ActionLink to reference it by id, and instantiate it inside your Edit action.
Take a look at default strongly typed index views created by tooling.

Resources