I've been struggling for a while now with the Ajax.BeginForm.
So, what I want to achieve is:
Clicking a button that will open a Modal Popup with a Partial View inside.
When I close the Modal Popup by pressing the Save button the information will be reloaded on the target control id by call an action on the controller.
What is happening is that the first time I do this, everything seems to work as intended. However as soon as I try to add something else, it does not work anymore.
Here goes the code.
Heres the code on the view that is being loaded inside the Modal Popup
#model GEMS.Models.ViewModels.AddressVM
#{
string controllerName = ViewContext.RouteData.Values["controller"].ToString();
string actionName = ViewContext.RouteData.Values["action"].ToString();
}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">#HTMLHelper.TranslateCRUDTitles(controllerName, actionName)</h4>
</div>
#using (Ajax.BeginForm(new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, OnSuccess = "ShowSuccess", OnFailure = "ShowFailure" }))
{
#Html.AntiForgeryToken()
<div class="modal-body">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#foreach (System.Reflection.PropertyInfo prop in Model.GetDisplayProps())
{
switch (prop.Name)
{
case "NewAddressTypeName":
break;
case "AddressType":
<div class="form-group">
#Html.Label(prop.Name)
#Html.DropDownList("AddressTypeID", null, htmlAttributes: new { #class = "form-control" }).DisableIf(() => actionName == "Delete")
#Html.ValidationMessage(prop.Name, new { #class = "text-danger" })
</div>
break;
case "Country":
<div class="form-group">
#Html.Label(prop.Name)
#Html.DropDownList("CountryID", null, htmlAttributes: new { #class = "form-control" }).DisableIf(() => actionName == "Delete")
#Html.ValidationMessage(prop.Name, new { #class = "text-danger" })
</div>
break;
case "IsDefault":
<div class="form-group">
<label class="checkbox-inline">
#Html.Editor(prop.Name, new { htmlAttributes = new { #class = "grey" } }).DisableIf(() => actionName == "Delete")
#Html.Label(prop.Name)
</label>
#Html.ValidationMessage(prop.Name, new { #class = "text-danger" })
</div>
break;
case "SameAsID":
if (ViewBag.SameAsID != null)
{
<div class="form-group">
#Html.Label(prop.Name)
#Html.DropDownList(prop.Name, null, htmlAttributes: new { #class = "form-control" }).DisableIf(() => actionName == "Delete")
#Html.ValidationMessage(prop.Name, new { #class = "text-danger" })
</div>
}
break;
default:
<div class="form-group">
#Html.Label(prop.Name)
#Html.Editor(prop.Name, new { htmlAttributes = new { #class = "form-control" } }).DisableIf(() => actionName == "Delete")
#Html.ValidationMessage(prop.Name, new { #class = "text-danger" })
</div>
break;
}
}
#foreach (System.Reflection.PropertyInfo prop in Model.GetHiddenProps())
{
<input id="#prop.Name" name="#prop.Name" type="hidden" value="#Model.GetPropValue(prop.Name)">
}
</div>
<div class="modal-footer">
#if (actionName == "Delete")
{
<p>
#Resources.ConfirmAddressDelete
</p>
}
<button class="btn btn-yellow" type="button" data-dismiss="modal">
#Resources.Cancel <i class="fa fa-arrow-circle-left"></i>
</button>
#switch (actionName)
{
case "Create":
case "Edit":
<button class="btn btn-success" type="submit" value="Save">
#Resources.Save <i class="fa fa-save"></i>
</button>
break;
case "Delete":
<button class="btn btn-red" type="submit" value="Delete">
#Resources.Delete <i class="fa fa-times"></i>
</button>
break;
}
</div>
}
Here's the controller relevant actions:
public ActionResult Index(List<AddressVM> addressVMList)
{
addressVMList = addressVMList ?? (List<AddressVM>)TempData["AddressVMList"];
TempData["AddressVMList"] = addressVMList;
TempData.Keep("AddressVMList");
return PartialView("_Index", addressVMList);
}
public ActionResult Create()
{
TempData.Keep("AddressVMList");
ViewBag.AddressTypeID = new SelectList(AddressType.GetList(), "ID", "Name");
ViewBag.CountryID = new SelectList(Country.GetList(), "ID", "NiceName");
List<AddressVM> addressVMList = (List<AddressVM>)TempData["AddressVMList"];
return PartialView("_CreateEditDelete", new AddressVM());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(AddressVM addressVM)
{
if (ModelState.IsValid)
{
//Create a fake ID in order to be able to edit and manipulate the address before it is actually saved
List<AddressVM> addressVMList = (List<AddressVM>)TempData["AddressVMList"];
addressVM.Id = (addressVMList.Count + 1) * -1;
addressVMList.Add(addressVM);
if (addressVM.IsDefault) ListedPropVM.SetDefault(addressVMList.Cast<ListedPropVM>().ToList(), addressVM.Id);
TempData.Keep("AddressVMList");
string url = Url.Action("Index", "Addresses", null);
return Json(new { success = true, url = url, method = "replaceTargetAddresses" });
}
// return PartialView("_CreateEditDelete", addressVM);
return RedirectToAction("Create");
}
And finally the script that is run when OnSuccess:
function ShowSuccess(data) {
if (data.success) {
$('#defaultModal').modal('hide');
$('#' + data.method).load(data.url);
}
}
function ShowFailure(data) {
alert('Problem occured');
}
Thanks in advance for your help and time.
Well I solved the problem by adding the following to the script on the partial view:
<script type="text/javascript">
**$(document).ready(function () {
$.ajaxSetup({ cache: false });
});**
function ShowSuccess(data) {
if (data.success) {
$('#defaultModal').modal('hide');
$('#' + data.method).load(data.url);
}
}
function ShowFailure(data) {
$('#defaultModalContent').html(result);
}
</script>
Hope this helps someone else.
Related
I got stucked with (it seems to be) a simple problem.
My goal is to create a modal with an Ajax form. A child action gets the modal in a partial view, and when edited, submit button posts Ajax form which returns just Json data. Built-in code in Ajax.BeginForm should trigger OnSuccess or OnFailure depending on the result of the action.
The problem is OnFailure is triggered and OnSuccess don't, although the action finishes OK, and post return a 200 code. The "data" param in OnFailure function contains the HTML of the whole page.
This is the code:
(1) Snippet to load the modal in the main view:
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
#Html.Action("GetDialogV2", "Fianzas", new { idArrendamiento = Model.Id_Arrendamiento })
</div>
(2) Button to open the modal in the main view:
<button type="button" class="btn btn-outline-primary" data-toggle="modal" data-target="#exampleModal">
<i class="far fa-hand-holding-usd"></i> Modal
</button>
(3) The partial view with the modal (and the Ajax Form), GetDialogV2.cshtml:
#model EditFianzas_vm
#{
AjaxOptions ajaxOptions = new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "Respuesta",
OnSuccess = "OnSuccess",
OnFailure = "OnFailure"
};
}
#using (Ajax.BeginForm(ajaxOptions))
{
#Html.AntiForgeryToken()
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Fianza</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.Id_Arrendamiento)
<div class="form-group">
#Html.LabelFor(model => model.Importe, new { #class = "control-label col-md-6" })
<div class="col-md-8">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far fa-euro-sign"></i></span>
</div>
#Html.EditorFor(model => model.Importe, new { htmlAttributes = new { #class = "form-control importe" } })
</div>
#Html.ValidationMessageFor(model => model.Importe, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Fecha_Abono, new { #class = "control-label col-md-6" })
<div class="col-md-8">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="far fa-calendar"></i></span>
</div>
#Html.TextBoxFor(model => model.Fecha_Abono, "{0:dd/MM/yyyy}", new { #class = "form-control datepicker" })
</div>
#Html.ValidationMessageFor(model => model.Fecha_Abono, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-8">
<input type="text" id="Respuesta" class="form-control" />
</div>
</div>
</div>
</div>
<div class="modal-footer justify-content-between">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancelar</button>
<button type="submit" class="btn btn-primary" id="botonPrueba">Guardar</button>
</div>
</div>
<!-- /.modal-content -->
</div>
}
(4) The Javascript in the main view:
#section scripts
{
<script type="text/javascript">
function OnSuccess(data) {
if (data.Success == true) {
toastr.success("Operación realizada.", "Fianzas");
$("#exampleModal").modal('hide');
}
else {
if (data.modelState) {
$.each(d.modelState, function (i, item) {
toastr.info(i + ': ' + item, "i: item");
//item.valid(); //run jQuery validation to display error
$('#' + i).valid();
});
}
else {
toastr.error(data.Error, "Fianzas");
}
}
}
function OnFailure(data) {
alert(data);
alert('HTTP Status Code: ' + data.param1 + ' Error Message: ' + data.param2);
toastr.error("Se ha producido un error no controlado al realizar la operación.", "Fianzas");
toastr.warning(data, "Fianzas");
}
</script>
}
(5) And finally, the controller:
#region Ajax Form (GetDialogV2)
public PartialViewResult GetDialogV2(int idArrendamiento)
{
//Obtengo el modelo...
Arrendamientos_Fianzas fianza = db.Arrendamientos_Fianzas.Find(idArrendamiento);
//Creo la vista-modelo...
EditFianzas_vm vm = new EditFianzas_vm {
Id_Arrendamiento = idArrendamiento,
Importe = fianza.Importe,
Fecha_Abono = fianza.Fecha_Abono
};
return PartialView(vm);
}
[HttpPost]
[ValidateAntiForgeryToken]
public JsonResult GetDialogV2(EditFianzas_vm vm)
{
try
{
if (!ModelState.IsValid)
{
var modelState = ModelState.ToDictionary
(
kvp => kvp.Key,
kvp => kvp.Value.Errors.Select(e => e.ErrorMessage).ToArray()
);
modelState.Add("hdId_Arrendamiento", modelState["vm.Id_Arrendamiento"]);
modelState.Remove("vm.Id_Arrendamiento");
modelState.Add("txtImporte", modelState["vm.Importe"]);
modelState.Remove("vm.Importe");
modelState.Add("txtFecha_Abono", modelState["vm.Fecha_Abono"]);
modelState.Remove("vm.Fecha_Abono");
return Json(new { modelState }, JsonRequestBehavior.AllowGet);
//throw (new Exception("Error en la validación del modelo."));
}
//Miro a ver si existen datos para este arrendamiento (no sé si es un edit o un new, si quiero hacerlo todo en una misma acción)
Arrendamientos_Fianzas fianza = db.Arrendamientos_Fianzas.Find(vm.Id_Arrendamiento);
//Compruebo si es nuevo o editado...
if (fianza == null)
{
//Nuevo registro...
fianza = new Arrendamientos_Fianzas
{
Id_Arrendamiento = vm.Id_Arrendamiento,
Importe = vm.Importe,
Fecha_Abono = vm.Fecha_Abono
};
//Actualizo info de control...
fianza.C_Fecha = DateTime.Now;
fianza.C_IdUsuario = Usuario.NombreUsuario;
fianza.C_Comentarios = "Alta de la fianza.";
//Guardo registro...
db.Arrendamientos_Fianzas.Add(fianza);
}
else
{
//Estoy editando, grabo valores...
fianza.Importe = vm.Importe;
fianza.Fecha_Abono = vm.Fecha_Abono;
//Actualizo info de control...
fianza.C_Fecha = DateTime.Now;
fianza.C_IdUsuario = Usuario.NombreUsuario;
fianza.C_Comentarios = "Modificación de los datos de la fianza.";
//Modifico estado del registro en el modelo...
db.Entry(fianza).State = EntityState.Modified;
}
//Guardo cambios...
db.SaveChanges();
//Return...
return new JsonResult() { Data = Json(new { Success = true }) };
}
catch (Exception ex)
{
return new JsonResult() { Data = Json(new { Success = false, Error = ex.Message }) };
}
}
#endregion
Thanks a lot in advance for your time and help.
Best regards,
Fernando.
I got it. It was a subtle solution, as I barely guessed:
If Javascript is disabled, or in certain circumstances, you need to explicitly pass action to the AjaxOptions, like that:
AjaxOptions ajaxOptions = new AjaxOptions()
{
HttpMethod = "POST",
OnSuccess = "OnSuccess(data)",
OnFailure = "OnFailure",
OnBegin = "OnBegin",
OnComplete = "OnComplete",
Url = Url.Action("GetDialogV2")
};
I have implemented a code to create Tree View and also save it into database.
Controller
public ActionResult IndexMda()
{
using (BackendEntities context = new BackendEntities())
{
var plist = context.MDA.Where(p => p.PARENT_MDA_ID == null).Select(a => new
{
a.MDA_ID,
a.MDA_NAME,
a.MDA_DESCRIPTION,
a.ORGANIZATION_TYPE
}).ToList();
ViewBag.plist = plist;
}
GetHierarchy();
return View();
}
public JsonResult GetHierarchy()
{
List<MDA2> hdList;
List<MdaViewModel> records;
using (BackendEntities context = new BackendEntities())
{
hdList = context.MDA.ToList();
records = hdList.Where(l => l.PARENT_MDA_ID == null)
.Select(l => new MdaViewModel
{
MDA_ID = l.MDA_ID,
text = l.MDA_NAME,
MDA_DESCRIPTION = l.MDA_DESCRIPTION,
ORGANIZATION_TYPE = l.ORGANIZATION_TYPE,
PARENT_MDA_ID = l.PARENT_MDA_ID,
children = GetChildren(hdList, l.MDA_ID)
}).ToList();
}
return this.Json(records, JsonRequestBehavior.AllowGet);
// return View();
}
private List<MdaViewModel> GetChildren(List<MDA2> hdList, long PARENT_MDA_ID)
{
return hdList.Where(l => l.PARENT_MDA_ID == PARENT_MDA_ID)
.Select(l => new MdaViewModel
{
MDA_ID = l.MDA_ID,
text = l.MDA_NAME,
MDA_DESCRIPTION = l.MDA_DESCRIPTION,
ORGANIZATION_TYPE = l.ORGANIZATION_TYPE,
PARENT_MDA_ID = l.PARENT_MDA_ID,
children = GetChildren(hdList, l.MDA_ID)
}).ToList();
}
[HttpPost]
public JsonResult ChangeNodePosition(long MDA_ID, long PARENT_MDA_ID)
{
using (BackendEntities context = new BackendEntities())
{
var Hd = context.MDA.First(l => l.MDA_ID == MDA_ID);
Hd.PARENT_MDA_ID = PARENT_MDA_ID;
context.SaveChanges();
}
return this.Json(true, JsonRequestBehavior.AllowGet);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddNewNode(AddNode model)
{
try
{
if (ModelState.IsValid)
{
using (BackendEntities db = new BackendEntities())
{
MDA2 hierarchyDetail = new MDA2()
{
MDA_NAME = model.NodeName,
PARENT_MDA_ID = model.ParentName,
MDA_DESCRIPTION = model.NodeDescription,
ORGANIZATION_TYPE = model.NodeOrganizationType
};
db.MDA.Add(hierarchyDetail);
db.SaveChanges();
}
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
}
catch (Exception ex)
{
throw ex;
}
return Json(new { success = false }, JsonRequestBehavior.AllowGet);
}
The partial view is where the Tree View is created
Partial View
#model BPP.CCSP.Admin.Web.ViewModels.AddNode
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button"
class="close"
data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">Add Node</h4>
</div>
<div class="modal-body">
#using (Html.BeginForm("AddNewNode", "Mda", FormMethod.Post, new { #id = "formaddNode", #class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="col-md-12">
<div class="col-md-6 row">
<div class="input-group">
<input type="text" class="form-control" value="Perent Node" readonly="readonly">
<span class="input-group-addon">
#Html.RadioButtonFor(model => model.NodeTypeRbtn, "Pn", new { #class = "btn btn-primary rbtnnodetype" })
</span>
</div>
</div>
<div class="col-md-6">
<div class="input-group ">
<input type="text" class="form-control" value="Child Node" readonly="readonly">
<span class="input-group-addon">
#Html.RadioButtonFor(model => model.NodeTypeRbtn, "Cn", new { #class = "rbtnnodetype" })
</span>
</div>
</div>
<br />
#Html.ValidationMessageFor(m => m.NodeTypeRbtn, "", new { #class = "alert-error" })
</div>
<div class="clearfix">
</div>
<div class="col-md-12">
<div class="petenddiv hidden">
#Html.Label("Select Parent")
#Html.DropDownList("ParentName", new SelectList(ViewBag.plist, "MDA_ID", "MDA_NAME"), "--select--", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.ParentName, "", new { #class = "alert-error" })
</div>
</div>
<div class="clearfix">
</div>
<div class="col-md-12">
<div>
#Html.Label("MDA Name")
#Html.TextBoxFor(model => model.NodeName, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.NodeName, "", new { #class = "alert-error" })
</div>
</div>
<div class="col-md-12">
<div>
#Html.Label("Description")
#Html.TextBoxFor(model => model.NodeDescription, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.NodeDescription, "", new { #class = "alert-error" })
</div>
</div>
<div class="col-md-12">
<div>
#Html.Label("Organization Type")
#Html.DropDownListFor(model => model.NodeOrganizationType, new List<SelectListItem>
{
new SelectListItem{Text = "Agency", Value = "Agency"},
new SelectListItem{Text = "Commission", Value = "Commission"},
new SelectListItem{Text = "Department", Value = "Department"},
new SelectListItem{Text = "Ministry", Value = "Ministry"}
}, "Select Error Type", new { #style = "border-radius:3px;", #type = "text", #class = "form-control", #placeholder = "Enter Organization Type", #autocomplete = "on" })
#Html.ValidationMessageFor(model => model.NodeDescription, "", new { #class = "alert-error" })
</div>
</div>
<div class="clearfix">
</div>
<br />
<br />
<div class="col-md-12">
<div>
<div class="pull-left">
<input type="submit" id="savenode" value="S A V E" class="btn btn-primary" />
</div>
<div class="pull-right">
<input type="button" id="closePopOver" value="C L O S E" class="btn btn-primary" />
</div>
</div>
</div>
<div class="clearfix">
</div>
}
</div>
</div>
View
<div class="col-md-12" style="margin:100px auto;">
<div class="modal fade in" id="modalAddNode" role="dialog" aria-hidden="true">
#Html.Partial("_AddNode")
</div>
<div class="col-md-12">
<div class="panel panel-primary">
<div class="panel-heading">Ministries, Departments and Agencies -: [ Add MDA and its Members ]</div>
<div class="panel-body">
<div id="tree"></div>
<div class="clearfix">
</div>
<br />
<div>
<button id="btnDeleteNode" data-toggle="modal" class='btn btn-danger'> Delete Node <span class="glyphicon glyphicon-trash"></span> </button>
<button id="btnpopoverAddNode" data-toggle="modal" class='btn btn-warning'> Add Node <span class="glyphicon glyphicon-plus"></span> </button>
</div>
</div>
</div>
</div>
Scipts
#section Scripts {
#System.Web.Optimization.Scripts.Render("~/bundles/jqueryval")
<script src="#Url.Content("~/Scripts/conditional-validation.js")" type="text/javascript"></script>
<script src="~/Scripts/Gijgo/gijgo.js"></script>
<link href="http://code.gijgo.com/1.3.0/css/gijgo.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
//'Hierarchy/GetHierarchy'
$(document).ready(function () {
var Usertree = "";
var tree = "";
$.ajax({
type: 'get',
dataType: 'json',
cache: false,
url: '/Mda/GetHierarchy',
success: function (records, textStatus, jqXHR) {
tree = $('#tree').tree({
primaryKey: 'MDA_ID',
dataSource: records,
dragAndDrop: true,
checkboxes: true,
iconsLibrary: 'glyphicons',
//uiLibrary: 'bootstrap'
});
Usertree = $('#Usertree').tree({
primaryKey: 'MDA_ID',
dataSource: records,
dragAndDrop: false,
checkboxes: true,
iconsLibrary: 'glyphicons',
//uiLibrary: 'bootstrap'
});
tree.on('nodeDrop', function (e, MDA_ID, PARENT_MDA_ID) {
currentNode = MDA_ID ? tree.getDataById(MDA_ID) : {};
console.log("current Node = " + currentNode);
parentNode = PerentId ? tree.getDataById(PARENT_MDA_ID) : {};
console.log("parent Node = " + parentNode);
if (currentNode.PARENT_MDA_ID === null && parentNode.PARENT_MDA_ID === null) {
alert("Parent node is not droppable..!!");
return false;
}
// console.log(parent.HierarchyLevel);
var params = { MDA_ID: MDA_ID, PARENT_MDA_ID: PARENT_MDA_ID };
$.ajax({
type: "POST",
url: "/Mda/ChangeNodePosition",
data: params,
dataType: "json",
success: function (data) {
$.ajax({
type: "Get",
url: "/Mda/GetHierarchy",
dataType: "json",
success: function (records) {
Usertree.destroy();
Usertree = $('#Usertree').tree({
primaryKey: 'MDA_ID',
dataSource: records,
dragAndDrop: false,
checkboxes: true,
iconsLibrary: 'glyphicons',
//uiLibrary: 'bootstrap'
});
}
});
}
});
});
$('#btnGetValue').click(function (e) {
var result = Usertree.getCheckedNodes();
if (result == "") { alert("Please Select Node..!!") }
else {
alert("Selected Node id is= " + result.join());
}
});
//delete node
$('#btnDeleteNode').click(function (e) {
e.preventDefault();
var result = tree.getCheckedNodes();
if (result != "") {
$.ajax({
type: "POST",
url: "/Mda/DeleteNode",
data: { values: result.toString() },
dataType: "json",
success: function (data) {
alert("Deleted successfully ");
window.location.reload();
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Error - ' + errorThrown);
},
});
}
else {
alert("Please select Node to delete..!!");
}
});
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Error - ' + errorThrown);
}
});
// show model popup to add new node in Tree
$('#btnpopoverAddNode').click(function (e) {
e.preventDefault();
$("#modalAddNode").modal("show");
});
//Save data from PopUp
$(document).on("click", "#savenode", function (event) {
event.preventDefault();
$.validator.unobtrusive.parse($('#formaddNode'));
$('#formaddNode').validate();
if ($('#formaddNode').valid()) {
var formdata = $('#formaddNode').serialize();
// alert(formdata);
$.ajax({
type: "POST",
url: "/Mda/AddNewNode",
dataType: "json",
data: formdata,
success: function (response) {
// $("#modalAddNode").modal("hide");
window.location.reload();
},
error: function (response) {
alert('Exception found');
// $("#modalAddNode").modal("hide");
window.location.reload();
},
complete: function () {
// $('.ajax-loader').css("visibility", "hidden");
}
});
}
});
//Close PopUp
$(document).on("click", "#closePopup", function (e) {
e.preventDefault();
$("#modalAddNode").modal("hide");
});
$('.rbtnnodetype').click(function (e) {
if ($(this).val() == "Pn") {
$('.petenddiv').attr("class", "petenddiv hidden");
$("#ParentName").val("");
}
else {
$('.petenddiv').attr("class", "petenddiv");
}
});
});
</script>
}
As shown above, what I have created can only do one level node. I want want to create multi-level.Whereby, a child will be a parent to other children.
Please how do I achieve this.
You can see some ASP.NET examples about this at https://github.com/atatanasov/gijgo-asp-net-examples/tree/master/Gijgo.Asp.NET.Examples
Please use our examples in order to achieve that.
Am using it for cascading dropdownlist for country and state. When I click on
country dropdownlist that suppose to display states, I got 500 server error. Please help me
The error occurs when I click the Country dropdownlist
[HttpPost]
[ValidateAntiForgeryToken] //this is to prevent CSRF attack
public ActionResult Create(CITIES ci)
{
List<COUNTRIES> allCountry = new List<COUNTRIES>();
List<STATES> allState = new List<STATES>();
using (AdminEntities dc = new AdminEntities())
{
allCountry = dc.COUNTRIES.OrderBy(a => a.COUNTRY_NAME).ToList();
if (ci != null && ci.COUNTRY_ID > 0)
{
allState = dc.STATES.Where(a => a.COUNTRY_ID.Equals(ci.COUNTRY_ID)).OrderBy(a => a.STATE_NAME).ToList();
}
}
ViewBag.COUNTRY_ID = new SelectList(allCountry, "COUNTRY_ID", "COUNTRY_NAME", ci.COUNTRY_ID);
ViewBag.STATE_ID = new SelectList(allState, "STATE_ID", "STATE_NAME", ci.STATE_ID);
if (ModelState.IsValid)
{
using (AdminEntities dc = new AdminEntities())
{
dc.CITIES.Add(ci);
dc.SaveChanges();
ModelState.Clear();
ci = null;
ViewBag.Message = "Successfully Saved";
}
}
else
{
ViewBag.Message = "Failed! Please try again";
}
return View(ci);
}
[HttpGet]
public JsonResult GetStates(string countryID = "")
{
// List<COUNTRIES> allCountry = new List<COUNTRIES>();
List<STATES> allState = new List<STATES>();
int ID = 0;
if (int.TryParse(countryID, out ID))
{
using (AdminEntities dc = new AdminEntities())
{
allState = dc.STATES.Where(a => a.COUNTRY_ID.Equals(ID)).OrderBy(a => a.STATE_NAME).ToList();
}
}
if (Request.IsAjaxRequest())
{
return new JsonResult
{
Data = allState,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
return new JsonResult
{
Data = "Not valid request",
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
view
#model BPP.CCSP.Admin.Web.Models.CITIES
Create
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="form-horizontal">
<h4>CITIES</h4>
<hr />
#if(ViewBag.message != true)
{
<div style="border:solid 1px black">
#ViewBag.message
</div>
}
<div class="form-group">
#Html.LabelFor(model => model.COUNTRY_ID, "COUNTRY_ID", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#* #Html.DropDownListFor(model=>model.COUNTRY_ID, new SelectList(string.Empty, "Value", "Text"), "Please select a country", new { #style = "width:250px;" }) *#
#Html.DropDownListFor(model => model.COUNTRY_ID, #ViewBag.COUNTRY_ID as SelectList,"Select Country")
#Html.ValidationMessageFor(model => model.COUNTRY_ID)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.STATE_ID, "STATE_ID", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#* #Html.DropDownListFor(model => model.STATE_ID, new SelectList(string.Empty, "Value", "Text"), "Please select a state", new { #style = "width:250px;" }) *#
#Html.DropDownListFor(model => model.STATE_ID, #ViewBag.STATE_ID as SelectList, "Select State")
#Html.ValidationMessageFor(model => model.STATE_ID)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CITY_NAME, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.CITY_NAME)
#Html.ValidationMessageFor(model => model.CITY_NAME)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script language="javascript">
$(document).ready(function () {
$("#COUNTRY_ID").change(function () {
//this will call when country dropdown select change
var countryID = parseInt($("#COUNTRY_ID").val());
if (!isNaN(countryID))
{
var ddState = $("#STATE_ID");
ddState.empty(); //this line is to clear all items from statee dropdown
ddState.append($("<option></option>").val("").html("Select State"));
//here i will call controller action via jquery to load state for selected country
$.ajax({
url: "#Url.Action("GetStates","CITIES")",
type: "GET",
data: {countryID : countryID},
dataType: "json",
success: function (data)
{
$.each(data, function (i, val) {
ddState.append(
$("<option></option>").val(val.STATE_ID).html(val.STATE_NAME)
);
});
}
,
error: function ()
{
alert("Error!");
}
});
}
});
});
</script>
}
Please what do I do
can you try
var data = {"countryID" : countryID};
$.ajax({
url: '#Url.Content("~/CITIES/GetStates")',
type: "GET",
contentType: 'application/json',
data:JSON.stringify(data),
});
and then debug GetStates action and if you get error there you will get normally 500 server error
In my view, I have an image element as follows:
<img id="ImageDisplay" class="img-thumbnail" width="280" height="280"
src="#Url.Action("GetFileFromHttpPostedFile", "Image", new { File = Model.File })"/>
When I debug my code, I can see that my Model.File is not null. But when I pass it to the action method, the action method receives the parameter as null. Here is my action method:
public FileContentResult GetFileFromHttpPostedFile(HttpPostedFileBase File)
{
byte[] imageData = new byte[File.ContentLength];
File.InputStream.Read(imageData, 0, File.ContentLength);
return GetFileFromData(imageData, File.ContentType);
}
Am I missing something? Can we not pass an HttpPostedFileBase to a method? Help please.
Edit:
I also have the following element in the view that allows the user to populate Model.File property:
<input type="file" name="File" id="File" onchange="loadFile(event)" />
loadFile(event) simply shows a preview of the picture on the view.
Edit 2: Here is the full code for the view:
#model MyProject.Models.ViewModels.ChangeProfileModel
#{
ViewBag.Title = "Change Your Profile";
}
<script>
$(document).ready(function () {
$('textarea').keyup(updateCount);
$('textarea').keydown(updateCount);
function updateCount() {
var cs = [500 - $(this).val().length];
$('#characters').text(cs);
}
});
var loadFile = function (event) {
var output = document.getElementById('ImageDisplay');
if (output != null) {
output.src = URL.createObjectURL(event.target.files[0]);
}
};
</script>
<h2>Change Your Profile Info</h2>
#using (Html.BeginForm("ChangeProfile", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
if (ViewBag.ChangesSaved == true)
{
<div class="alert alert-success">
Your changes have been saved successfully!
×
</div>
}
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.City, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.City, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.City, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Country, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Country, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Country, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2">Select an Image </label>
<div class="col-md-10">
<input type="file" name="File" id="File" onchange="loadFile(event)" />
</div>
</div>
<div class="form-group">
<label class="control-label col-md-2"></label>
<div class="col-md-10">
#if (Model.File == null)
{
<img id="ImageDisplay" class="img-thumbnail" width="280" height="280"
src="#Url.Action("GetImageByUser", "Image", new { id = Model.Id })"/>
}
else
{
<img id="ImageDisplay" class="img-thumbnail" width="280" height="280"
src="#Url.Action("GetFileFromHttpPostedFile", "Image", new { File = Model.File })"/>
}
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.About, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextAreaFor(m => m.About, new { #class = "form-control", #rows = "5", #maxlength = 500 })
<span id="characters" style="color:#999;">500</span> <span style="color:#999;">characters left</span>
#Html.ValidationMessageFor(model => model.About, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
#Html.ActionLink("Cancel", "Index", "Manage", null, new { #class = "btn btn-default" })
</div>
</div>
</div>
}
In my HomeController, I have the following methods:
public ActionResult ChangeProfile()
{
var userId = User.Identity.GetUserId();
var loggedInUser = UserManager.FindById(userId);
ChangeProfileModel viewModel = new ChangeProfileModel
{
Id = userId,
City = loggedInUser.City,
Country = loggedInUser.Country,
About = loggedInUser.About
};
return View(viewModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ChangeProfile(ChangeProfileModel viewModel)
{
if (!ModelState.IsValid)
{
return View(viewModel);
}
var userId = User.Identity.GetUserId();
var loggedInUser = UserManager.FindById(userId);
byte[] imageData = null;
if (viewModel.File != null)
{
imageData = new byte[viewModel.File.ContentLength];
viewModel.File.InputStream.Read(imageData, 0, viewModel.File.ContentLength);
}
_aspNetUserRepository.EditUserInfo(userId, viewModel.City, viewModel.Country, viewModel.About,
imageData, (viewModel.File == null) ? null: viewModel.File.ContentType);
ViewBag.ChangesSaved = true;
return View(viewModel);
}
Lastly, here is my last relevant action method inside ImageController:
public FileContentResult GetFileFromHttpPostedFile(HttpPostedFileBase File)
{
byte[] imageData = new byte[File.ContentLength];
File.InputStream.Read(imageData, 0, File.ContentLength);
return GetFileFromData(imageData, File.ContentType);
}
I have this issue, have search a lot but with now correct answer.
I have a contact form in the footer, on my _Layout page, but when I clicked the button the partial view is open in a new page.
I have remember to include the jquery.unobtrusive-ajax.js. Here is what I have.
Controller :
[HttpGet]
public ActionResult Call()
{
return PartialView("_PartialFooter");
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Call(CallMe callMe)
{
if(ModelState.IsValid)
{
}
return PartialView("_PartialFooter");
}
_Layout the scripts is above the Body tag in the bottom
#using (Ajax.BeginForm("Call", "Home", new AjaxOptions { UpdateTargetId = "result" }))
{
<div id="result" class="margin-bottom-5">
#Html.Action("Call", "Home")
</div>
<button class="btn btn-common-small margin-bottom-10 pull-right" type="submit">Send</button>
}
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#Scripts.Render("~/bundles/myscripts")
#RenderSection("scripts", required: false)
#section Scripts {
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
}
_PartialFooter (the partial view)
#model servicemadsen.Models.CallMe
#Html.AntiForgeryToken()
<div class="row">
<div id="result" class="margin-bottom-5">
<div class="col-md-6">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control", #placeholder = "Navn" } })
</div>
<div class="col-md-6">
#Html.EditorFor(model => model.Phone, new { htmlAttributes = new { #class = "form-control", #placeholder = "Telefon" } })
</div>
<div class="col-md-12">
#Html.TextAreaFor(model => model.CallMeMessage, new { #class = "form-control", #placeholder = "Besked", #cols = 80, #rows = 7 })
</div>
<div class="col-md-12">
#Html.ValidationMessageFor(model => model.Name, string.Empty, new { #class = "field-validation-error" })
#Html.ValidationMessageFor(model => model.Phone, string.Empty, new { #class = "field-validation-error" })
#Html.ValidationMessageFor(model => model.CallMeMessage, string.Empty, new { #class = "field-validation-error" })
</div>
</div>
</div>
Hope someone could help, its probaly some dummy thing that I need
have you installed the microsoft jquery unobstrusive ajax? if not try with that. i do some tests with your code and works.
EDIT : i also change some code for the tests
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Call(CallMe callMe)
{
if (ModelState.IsValid)
{
ModelState.Clear();
callMe.CallMeMessage = callMe.CallMeMessage + " i was on the server";
}
return PartialView("_PartialFooter", callMe);
}
and
#using (Ajax.BeginForm("Call", "Home", new AjaxOptions { UpdateTargetId = "result", InsertionMode = InsertionMode.Replace}))
{
<div id="result" class="margin-bottom-5">
#Html.Action("Call", "Home")
</div>
<button class="btn btn-common-small margin-bottom-10 pull-right" type="submit">Send</button>
}
so you can see the changes.