نیاز داریم تا با انتخاب استان نام شهرستانهای متناظر با آن نیز مشاهده شوند
در بسیاری از صفحات نیاز داریم تا با تغییر یکی از ایتمهای لیست باز شو لیست باز شو مرتبط با آن (مثلا ارتباط بین لیست باط شو استان و در مقابل لیست باز شو شهرستانهای متناظر) به روز شود. از طریق jquery و یا ajax میتوان با تغییر ایتمهای لیست اول اطلاعات مربوطه را از بانک اطلاعاتی دریافت کرد. و در لیست باز شو دوم ریخت.
برای این کار د رModel داریم
public class City
{
public int Id { get; set; }
[Display(Name = "نام شهر")]
public string Name { get; set; }
public int ProvinceId { get; set; }
public virtual Province Province { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
}
public class Province
{
public int Id { get; set; }
[Display(Name = "نام استان")]
public string Name { get; set; }
public virtual ICollection<Customer> Customers { get; set; }
public virtual ICollection<City> Citis { get; set; }
}
و در ثبت نام مشتری
public class Customer
{
public int Id { get; set; }
[Display(Name = "نام")]
public string FirstName { get; set; }
[Display(Name = "نام خانوادگی")]
public string LastName { get; set; }
[Display(Name = "شماره تلفن")]
public string Phone { get; set; }
[Display(Name = "شماره همراه")]
public string Mobile { get; set; }
[Display(Name="پست الکترونیک")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[Display(Name = "کد ملی")]
public string NationalCode { get; set; }
public int ProvinceId { get; set; }
public virtual Province Province { get; set; }
public int CityId { get; set; }
public virtual City City { get; set; }
[Display(Name = "آدرس")]
public string Address { get; set; }
public DateTime CreateDate { get; set; }
}
در ویوو خواهیم داشت
<div class="form-group col-md-6 col-sm-12">
@Html.LabelFor(model => model.ProvinceId, "استان", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model=>model.ProvinceId, (SelectList)ViewBag.ProvinceId, "انتخاب استان", htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.ProvinceId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group col-md-6 col-sm-12">
@Html.LabelFor(model => model.CityId, "شهر", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("CityId",(SelectList)ViewBag.CityId, "انتخاب شهر", new {@class = "form-control" })
@Html.ValidationMessageFor(model => model.CityId, "", new { @class = "text-danger" })
</div>
</div>
از هر دو حالت DropDownListFor و DropDownList میتوانید استفاده کنید همانطور که در آستان و شهر متفاوت استفاده شده است
در کد های java script خواهیم داشت
$(document).on("change", "#ProvinceId", function (e) {
var PID = this.value;
$.ajax({
type: 'GET',
url: '/customers/ReturnCity',
dataType:"json",
data: { ProvinceID: PID },
success: function (ci) {
$('#CityId').empty();
$.each(ci, function (index, item)
{
$('#CityId').append($('<option></option>').text(item.Name).val(item.Id));
});
},
});
})
و در کنترل
public JsonResult ReturnCity(int ProvinceID)
{
db.Configuration.ProxyCreationEnabled = false;
var ci = db.Citis.Where(x => x.ProvinceId == ProvinceID);
return Json(ci.ToList(), JsonRequestBehavior.AllowGet);
}
public ActionResult Create()
{
int i = 0;
ViewBag.CityId = new SelectList(db.Citis, "Id", "Name");
ViewBag.CustomerTypeId = new SelectList(db.CustomerTypes, "Id", "Name");
ViewBag.ProvinceId = new SelectList(db.Provinces, "Id", "Name");
return PartialView("_Create");
}
// POST: Customers/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([Bind(Include = "Id,FirstName,LastName,Phone,Mobile,Email,NationalCode,CompanyName,ProvinceId,CityId,Address,CustomerTypeId")] Customer customer)
{
if (ModelState.IsValid)
{
db.Customers.Add(customer);
await db.SaveChangesAsync();
return RedirectToAction("Index");
}
ViewBag.CityId = new SelectList(db.Citis, "Id", "Name", customer.CityId);
ViewBag.CustomerTypeId = new SelectList(db.CustomerTypes, "Id", "Name", customer.CustomerTypeId);
ViewBag.ProvinceId = new SelectList(db.Provinces, "Id", "Name", customer.ProvinceId);
return RedirectToAction("Index");
}
actionResult اول برای استفاده ajax است که میبینید هم نام با قسمت url اجکس نام گذاری شده است
و دو اکشن Create که نیاز به توضیح خاصی ندارد فقط در اکشن create دوم با توجه به اینکه ما برای ایجاد مشتری از Modal استفاده میکردم Redirect به اکشن Index زده شده است
البته در اکشن اول (returnCity) با توجه به اینکه json بر میگردانیم اگر خط کد
db.Configuration.ProxyCreationEnabled = false;
را ایجاد نکنیم خطا یی مبنی بر
A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.City_14F512F84B33053E91AF620D1BA9085FB7B5113A0
دریافت خواهیم کرد.
البته در Edit که برای تغییر جزئیات کاربر یا مشتری استفاده میکنید باید کدهای مربوط به لیست بازشو را تغییر دهید
<div class="form-group col-md-6 col-sm-12">
@Html.LabelFor(model => model.ProvinceId, "استان", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("ProvinceId", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.ProvinceId, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group col-md-6 col-sm-12">
@Html.LabelFor(model => model.CityId, "شهر", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("CityId", null, htmlAttributes: new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.CityId, "", new { @class = "text-danger" })
</div>
</div>
چرا که اگر کدها با Create یکسان باشد در هر بار نمایش صفحه Edit لیست استانها و شهر ها را مانند زمان Create از ابتدا نمایش میدهد.
لطفا در کد های خود در java حتما به بزرگ و کوچک بودن حروف دقت کنید.
آپدیت : زمانی که روی تغییر کلیک میکنیم لیست تمامی شهرستانها نمایش داده میشود ، برای تغییر در آن باید در کنترل چنین تغییری بدیم
ViewBag.CityId = new SelectList(db.Citis.Where(x=>x.ProvinceId == customer.ProvinceId), "Id", "Name", customer.CityId);
قسمت where اضافه شد.