I am working on creating Modal pop-ups for CRUD operations. I have created working modals for Create and Edit. My issue is now I have no way to use the validations from the server side which I need to have. When Edit fails the validation test it rightfully so rejects the request but redirects back to the Edit view in a non modal form. Please see below.
Modal:
After Invalid input:
I believe its going into the controller post edit and rendering from the URL. Which its good as it gives the validation for the pin being empty correctly, However this would need to be rendered on the Modal Edit 1234 pop up. Will include Model, controller , index view, Edit view, and js to help with the issue. Thank you for your help.
Model:
public class Airmen
{
[Key]
[Required]
public string MobileID { get; set; }
[Required]
public string Pin { get; set; }
}
public class SuperModel
{
public Airmen airmen { get; set; }
public IEnumerable<Airmen> airmens { get; set; }
}
Controller:
public async Task<IActionResult> Index(SuperModel arm)
{
arm.airmens = await _context.Airmen.ToListAsync();
return View(arm);
}
[HttpGet]
public async Task<IActionResult> Edit(string id)
{
SuperModel airmen = new SuperModel();
airmen.airmen = await _context.Airmen.FindAsync(id);
return PartialView(airmen);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, [Bind("MobileID,Pin")] Airmen airmen)
{
SuperModel amn = new SuperModel();
if (id != airmen.MobileID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(airmen);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!AirmenExists(airmen.MobileID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
amn.airmen = airmen;
return PartialView(amn);
}
Index View:
#model ALRSweb4.Models.SuperModel
#{ViewData["Title"] = "Index";}
<h1>Index</h1>
<table class="table">
<thead>
<tr>
<th>
Mobile ID
</th>
<th>
Pin
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.airmens)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.MobileID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Pin)
</td>
<td>
<button type="button" class="btn btn-primary" data-toggle="ajax-modal" data-target="#Edit" data-url="#Url.Action(item.MobileID,"Airmen/Edit")">
Edit
</button>
<a asp-action="Details" asp-route-id="#item.MobileID">Details</a> |
<a asp-action="Delete" asp-route-id="#item.MobileID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#CreateModal">
Create
</button>
<div class="modal fade" id="CreateModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Create</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
#Html.Partial("Create")
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
<div id="EditPlaceHolder">
</div>
Edit View:
#model ALRSweb4.Models.SuperModel
#{
ViewData["Title"] = "Edit";
}
<div class="modal fade" id="Edit" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Edit 12343</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-4">
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input asp-for="airmen.MobileID" />
<div class="form-group">
<label asp-for="airmen.Pin" class="control-label"></label>
<input asp-for="airmen.Pin" class="form-control" />
<span asp-validation-for="airmen.Pin" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
JS:
// t2
$(function () {
var CreatePlaceHolderElement = $('#EditPlaceHolder');
$('button[data-toggle="ajax-modal"]').click(function (event) {
var url = $(this).data('url');
var decodedUrl = decodeURIComponent(url);
$.get(decodedUrl).done(function (data) {
CreatePlaceHolderElement.html(data);
CreatePlaceHolderElement.find('.modal').modal('show');
})
})
CreatePlaceHolderElement.on('click', '[data-save="modal"]', function (event) {
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var sendData = form.serialize();
$.post(actionUrl, sendData).done(function (data) {
CreatePlaceHolderElement.find('.modal').modal('hide');
location.reload(true);
})
})
})
// end of t2
// start of function for create modal
$(function () {
var CreatePlaceHolderElement = $('#CreatePlaceHolder');
$('button[data-toggle="ajax-modal"]').click(function(event){
var url = $(this).data('url');
$.get(url).done(function (data) {
CreatePlaceHolderElement.html(data);
CreatePlaceHolderElement.find('.modal').modal('show');
})
})
CreatePlaceHolderElement.on('click', '[data-save="modal"]', function (event) {
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var sendData = form.serialize();
$.post(actionUrl, sendData).done(function (data) {
CreatePlaceHolderElement.find('.modal').modal('hide');
location.reload(true);
})
})
})
// end of function for create modal
Html.RenderPartialAsync cannot render the js successfully by ajax call back. So the fastest way is to add the js in Edit view like below and it will prevent form submit:
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
The ajax function below is useless, just remove the following code to use default form submit. The reason for why removing it is because firstly your code does not have any element with data-save="modal". Then you have <input type="submit" /> which will submit your form data by default without using ajax.
CreatePlaceHolderElement.on('click', '[data-save="modal"]', function (event) {
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var sendData = form.serialize();
$.post(actionUrl, sendData).done(function (data) {
CreatePlaceHolderElement.find('.modal').modal('hide');
location.reload(true);
})
})
Related
I want to change the delete button from an ajax button to an html button. I am currently using ajax/javascript for the delete button. When I click the Delete button, a modal window to confirm that I want to delete comes up and once I click confirm it will delete the vote. The Delete Action redirect I changed to RedirectToAction but the page errors out (InvalidOperationException: No route matches the supplied values.). The redirect isn't right I believe or maybe I need another return for the method?
<div class="modal fade" id="delete-vote-modal" tabindex="-1"
role="dialog"
data-backdrop="static">
<form method="post" asp-controller="Discussion" asp-action="DeleteVote"
enctype="multipart/form-data">
<input id="packet-item-id" asp-for="#Model.PacketItemId" type="hidden"
/>
<input id="voting-type" asp-for="#Model.VotingType" type="hidden"
/>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Delete Vote</h5>
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<input type="hidden" name="voteId" id="voteId" value="" />
Do you want to delete this vote ?
<div style="text-align: center; display: none"
id="loaderDiv">
<img src="~/images/loading.gif" width="150" />
</div>
</div>
<div class="modal-footer">
<a href="#" class="btn btn-default" data-
dismiss="modal">Cancel</a>
<input type="submit"
value="Confirm"
class="btn btn-success col-sm-12 col-md-2 col-lg-2"
data-action="submit" />
</div>
</div>
</div>
</form>
[HttpPost]
public async Task<IActionResult> DeleteVote(long voteId, int
packetItemId, string votingType, CancellationToken cancellationToken)
{
try
{
await _discussionService.DeleteVoteAsync(
voteId,
cancellationToken)
.ConfigureAwait(true);
TempData.Put(key: TempDataKey.Vote.DeleteMessage,
StatusMessageModel.Create(UserStringsService.VoteDeletedSuccessfully,
false));
return RedirectToAction("/Vote?packetItemId=" + packetItemId +
"&votingType=" + votingType);
//return Json(new { isSuccess = true, statusMessage =
UserStringsService.VoteDeletedSuccessfully });
}
catch
{
Logger.LogError($"Error in deleting the Vote Id: {voteId}");
TempData.Put(key: TempDataKey.Vote.DeleteMessage,
StatusMessageModel.Create(UserStringsService.VoteDeleteFailed, false));
return RedirectToAction("/Discussion/Vote?packetItemId=" +
packetItemId + "&votingType=" + votingType);
//return Json(new { isSuccess = false, statusMessage =
UserStringsService.VoteDeleteFailed });
}
}
From the code, the bakend need to receive the data with an object.
Note: the route parameter in Redirect is an absolute path.
[HttpPost]
public async Task<IActionResult> DeleteVote(ViewModel viewModel, CancellationToken cancellationToken)
{
return Redirect("/Discussion/Vote?packetItemId="+viewModel.PacketItemId+ "&votingType="+viewModel.VotingType);
}
public IActionResult Vote(int packetItemId, string votingType)
{
return Ok(new { packetItemId = packetItemId, votingType = votingType });
}
Model
public class ViewModel
{
public int PacketItemId { get; set; }
public string VotingType { get; set; }
//...
}
This is in ASP.NET Core MVC 2.1.
What I have is a main Index page on witch I load all my partial views.
<button type="button" id="CreateButton" class="btn btn-success" style="margin-top: 20px;">Nova osoba</button>
<button type="button" id="LoadDataButton" class="btn btn-info" style="margin-top: 20px;">Ucitati podatke</button>
<div id="CreateEditView">
</div>
<div id="TablePeopleView">
</div>
The way I load data into "TablePeopleView" is like this.
function AjaxCall(url) {
$("#TablePeople").replaceWith(
$.ajax({
url: url,
method: "POST",
success: function (html) {
$("#TablePeopleView").html(html);
}
}));
}
$(document).ready(function () {
AjaxCall("#Url.Action("IndexAjax")");
});
This calls the IndexAjax method from the controller and creates this partial view inside "TablePeopleView"
#model List<Person>
<table style="margin-top: 20px;" class="table table-condensed" id="TablePeople">
<thead>
<tr>
<th>ID</th>
<th>Ime</th>
<th>Prezime</th>
<th>Grad</th>
<th>Postanski broj</th>
<th>Broj mobitela</th>
<th> </th>
<th> </th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#item.ID</td>
<td>#item.FirstName</td>
<td>#item.LastName</td>
<td>#item.CityName</td>
<td>#item.PostalCode</td>
<td>#item.MobileNumber</td>
<td>
<button type="button" class="btn btn-toolbar EditButton" data-url="#Url.Action("Edit","Zadatak")/#item.ID">
Uredi osobu
</button>
</td>
<td>
<button type="submit" class="btn btn-danger DeleteButton" data-url="#Url.Action("Delete","Zadatak")/#item.ID">
Obriši osobu
</button>
</td>
</tr>
}
</tbody>
</table>
And it works fine, gets the data and shows it on table.
When I want to create a new person I click on the "CreateButton" and get a new partial view inside "CreateEditView". The partial view looks like this.
#model Person
<div class="modal fade" id="CreateOrEditModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
#if (Model == null)
{
<h4 class="modal-title">Nova osoba</h4>
}
else
{
<h4 class="modal-title">Uredi osobu</h4>
}
</div>
<div class="modal-body">
<form asp-controller="Zadatak" id="CreateOrEditModalForm">
<div class="form-group">
<label class="control-label">Ime osobe</label>
<input asp-for="FirstName" class="form-control" id="FirstName" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Prezime osobe</label>
<input asp-for="LastName" class="form-control" id="LastName" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Naziv grada</label>
<input asp-for="CityName" class="form-control" id="CityName" />
<span asp-validation-for="CityName" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Poštanski broj</label>
<input asp-for="PostalCode" class="form-control" id="PostalCode" onkeypress="return isNumberKey(event)" />
<span asp-validation-for="PostalCode" class="text-danger"></span>
</div>
<div class="form-group">
<label class="control-label">Mobilni broj</label>
<input asp-for="MobileNumber" class="form-control" id="MobileNumber" onkeypress="return isNumberKey(event)" />
<span asp-validation-for="MobileNumber" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Pospremi osobu" class="btn btn-default" id="SavePerson" />
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" id="ClosePerson" class="btn btn-default" data-dismiss="modal">Zatvori</button>
</div>
</div>
</div>
</div>
The way I get the partial view to show up in "CreateEditView" is like this.
$('#CreateButton').click(function () {
var url = "#Url.Action("Create","Zadatak")";
$("#CreateEditView").load(url, function () {
$("#CreateOrEditModal").modal("show");
});
});
The way I save date from the form "CreateOrEditModalForm" is with this.
$("#CreateEditView").on("click", "#SavePerson", function (event) {
$("#CreateOrEditModalForm").removeData('validator');
$("#CreateOrEditModalForm").removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse("#CreateOrEditModalForm");
$("#CreateOrEditModalForm").validate();
if ($("#CreateOrEditModalForm").valid()) {
$("#CreateOrEditModal").modal("hide");
}
});
I had to do it like this because it is loaded through a partial view witch is not loaded on page load.
After the form is validated it calls the "Create" method from the controller witch looks like this.
[HttpPost]
public IActionResult Create(Person model)
{
if (ModelState.IsValid)
{
this._dbContext.People.Add(model);
this._dbContext.SaveChanges();
return NoContent();
}
return NoContent();
}
Now this is where my problem comes I think. If the "ModelState.IsValid" is valid the new person will be saved to the DB and it will return NoContent. I put no content so the page does not refresh but if I put return RedirectToAction(nameof(IndexAjax)); like I did in the begginig it just loads the partila view in a new page like this.
I do not want that to happen, I just want the table to be refreshed with the new person while staying on the page.
Ajax allows websites to load content onto the screen without refreshing the page.
Here is a working demo you could check:
Model:
public class Person
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string CityName { get; set; }
public string PostalCode { get; set; }
public string MobileNumber { get; set; }
}
View(Views/Zadatak/Index.cshtml):
<button type="button" id="CreateButton" class="btn btn-success" style="margin-top: 20px;">Nova osoba</button>
<button type="button" id="LoadDataButton" class="btn btn-info" style="margin-top: 20px;">Ucitati podatke</button>
<div id="CreateEditView">
</div>
<div id="TablePeopleView">
</div>
#section Scripts
{ //be sure add _ValidationScriptsPartial....
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
function AjaxCall(url) {
//the same as yours..
}
$(document).ready(function () {
AjaxCall("#Url.Action("IndexAjax")");
});
$('#CreateButton').click(function () {
//the same as yours..
});
$("#CreateEditView").on("click", "#SavePerson", function (event) {
$("#CreateOrEditModalForm").removeData('validator');
$("#CreateOrEditModalForm").removeData('unobtrusiveValidation');
$.validator.unobtrusive.parse("#CreateOrEditModalForm");
$("#CreateOrEditModalForm").validate();
if ($("#CreateOrEditModalForm").valid()) {
$("#CreateOrEditModal").modal("hide");
//add the following code....
$("#TablePeople").replaceWith(
$.ajax({
url:"#Url.Action("Create", "Zadatak")",
method: "POST",
data: $("#CreateOrEditModalForm").serialize(),
success: function (html) {
$("#TablePeopleView").html(html);
}
}));
}
});
</script>
}
Be sure modify your CreateEditView.cshtml:
#model Person
<div class="modal fade" id="CreateOrEditModal" role="dialog">
//...
<div class="form-group">
#*change type="submit" to type="button"*#
<input type="button" value="Pospremi osobu" class="btn btn-default" id="SavePerson" />
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" id="ClosePerson" class="btn btn-default" data-dismiss="modal">Zatvori</button>
</div>
</div>
</div>
</div>
Controller:
public class ZadatakController : Controller
{
private readonly YourContext _context;
public ZadatakController(YourContext context)
{
_context = context;
}
[HttpGet]
public async Task<IActionResult> Index()
{
return View();
}
[HttpPost]
public async Task<IActionResult> IndexAjax()
{
//change here....
return PartialView("_IndexTable", await _context.Person.ToListAsync());
}
public IActionResult Create()
{
return PartialView("CreateEditView");
}
[HttpPost]
public async Task<IActionResult> Create(Person person)
{
if (ModelState.IsValid)
{
_context.Add(person);
await _context.SaveChangesAsync();
//change here....
return PartialView("_IndexTable", await _context.Person.ToListAsync());
}
return View(person);
}
}
Result:
This is sort of an add-on to my previous question:
Modal Pop-Up Not Closing Properly After Form Submission
I'm trying to reuse the modal pop-up functionality for another pop-up on the same page. This time I am using it to upload a file. This is the javascript in question:
$('body').on('click', '.relative', function (e) {
e.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var dataToSend = form.serialize();
$.post(actionUrl, dataToSend).done(function (data) {
$('body').find('.modal-content').html(data);
var isValid = $('body').find('[name="IsValid"]').val() == 'True';
if (isValid) {
$('body').find('#modal-container').modal('hide');
window.location.href = "/Issue/Edit";
}
});
})
I inadvertently misspelled "relative" on the submit button of this form:
#model Models.AttachmentModel
<!--Modal Body Start-->
<div class="modal-content">
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()" />
<!--Modal Header Start-->
<div class="modal-header">
<h4 class="modal-title">Upload File</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<!--Modal Header End-->
<form asp-action="FileUpload" method="post" enctype="multipart/form-data" asp-controller="Attachment">
#Html.AntiForgeryToken()
<div class="modal-body form-horizontal">
<div>
<p>Upload a file using this form:</p>
<input type="file" name="file" />
<span asp-validation-for="#Model.aFileData" class="text-danger"></span>
</div>
<div>
<p>Enter a file description</p>
<input id="attachment" asp-for="#Model.aIssueAttachmentDescription" class="form-control" />
<span asp-validation-for="#Model.aIssueAttachmentDescription" class="text-danger"></span>
<input id="issueid" type="hidden" asp-for="#Model.issueId" class="form-control" value="#ViewBag.id" />
</div>
<!--Modal Footer Start-->
<div class="modal-footer">
#*<button type="submit" class="btn btn-success fileuploadmodal" data-save="modal">Upload</button>*#
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Cancel</button>
<input type="submit" class="btn btn-success realative" id="btnSubmit" data-save="modal" value="Upload">
</div>
<div class="row">
</div>
</div> <!--Modal Footer End-->
</form>
</div>
<script type="text/javascript">
$(function () {
});
</script>
With the word "relative" misspelled, the file information is being sent to the action in the controller(see below). My guess is the Javscript isn't catching the click action ($('body').on('click', '.relative', function (e)). When I spell "relative" correctly the file information is NULL:
public async Task<IActionResult> FileUpload(IFormFile file, IFormCollection collection)
{ //do something
}
What needs to change with the Javascript (or my form/controller) to get the file information? In both cases the collection information is being passed. Is there a way to get the file information added to the collection?
--------- More Info based on #Rena answer
Let me expand some more on the original code and how this works. I have a page that has a modal section that will be populated with different partial views depending upon what I want displayed in the modal. On the Main page it has the following Javascript section:
<script>
$('body').on('click', '.modal-link', function () {
var actionUrl = $(this).attr('href');
$.get(actionUrl).done(function (data) {
$('body').find('.modal-content').html(data);
});
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
});
$('body').on('click', '.relative', function (e) {
e.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var dataToSend = form.serialize();
$.post(actionUrl, dataToSend).done(function (data) {
$('body').find('.modal-content').html(data);
var isValid = $('body').find('[name="IsValid"]').val() == 'True';
if (isValid) {
$('body').find('#modal-container').modal('hide');
window.location.href = "/Issue/Edit";
}
});
})
$('body').on('click', '.close', function () {
$('body').find('#modal-container').modal('hide');
});
$('#CancelModal').on('click', function () {
return false;
});
$("form").submit(function () {
if ($('form').valid()) {
$("input").removeAttr("disabled");
}
});
</script>
I took what was provided by #Rena and inserted it into this section, but found that the Modal wouldn't close (although the data from the form in the partial view was now getting passed). I tried changing the .realative to another value on both the partial view and the javascript, but it made no difference. I then tried what #mj313 suggested in the preceding posts by changing the provided script like this to redirect to /Issue/Edit but that didn't work either.:
}).done((response, textStatus, xhr) => {
$('body').find('.modal-content').html(data);
var isValid = $('body').find('[name="IsValid"]').val() == 'True';
if (isValid) {
$('body').find('#modal-container').modal('hide');
window.location.href = "/Issue/Edit";
}
});
So while I can now pass data I can't close the Modal.
UPDATE
Here is a slimmed down version of the Edit page where all of this starts
#model MYAPP.ViewModels.IssueViewModel
#{
ViewData["Title"] = "Issue Detail Page";
}
<script type="text/javascript">
$(document).ready(function () {
$("#UploadSection").load("/Attachment/GetAttachments/" + #Model.IssueData.issueId);
});
$(function () {
//Some code
});
function onSelectChange(element) {
//Some code
}
</script>
<div asp-validation-summary="All" class="text-danger"></div>
<hr />
<div class="row">
<div>
<form asp-action="Edit">
<input type="hidden" asp-for="IssueData.issueId" />
#*Some Code*#
#*Placeholder for Modal Pop-up*#
<div id="modal-container" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
</div>
</div>
</div>
#*This table contains the first control that generates a modal which contains the _CreateEdit.cshtml*#
<table width="100%">
<tr>
<td width="90%" style="padding:5px 5px 0px 5px;background-color:midnightblue;color:white">
<div class="form-group">
<label asp-for="IssueData.issueStatus" class="control-label">Current Issue Status</label>
-
#if (#Model.IssueData.StatusList[0].UpdatedByName != "")
{
<text>Updated by: </text> #Model.IssueData.StatusList[0].UpdatedByName <text> - </text>#Model.IssueData.StatusList[0].StatusDate.Value.ToShortDateString()
}
else
{
<text>Created by: </text> #Model.IssueData.StatusList[0].EnteredByName <text> - </text>#Model.IssueData.StatusList[0].StatusDate.Value.ToShortDateString()
}
</div>
</td>
<td style="background-color: midnightblue; padding-right:5px">
#if (#Model.IssueData.StatusList[0].StatusDate != DateTime.Today)
{
Add New Status
}
else
{
<a href="#Url.Action("CreateEdit", new { controller = "Issue", issueid = Model.IssueData.issueId, addedit = "edit" })"
class="modal-link btn btn-success">Edit Current Status</a>
}
</td>
</tr>
</table>
<br />
#*This table contains the second control that generates a modal which contains the _UploadFile.cshtml*#
<table id="upload" width="100%">
<tr>
<td width="90%" style="padding:5px 5px 0px 5px;background-color:midnightblue;color:white">
<label class="control-label">Upload Attachments</label>
</td>
<td style="background-color: midnightblue; padding-right:5px">
<a href="#Url.Action("FileUpload", new { controller = "Attachment", issueid = Model.IssueData.issueId })"
class="modal-link btn btn-success">Upload Files</a>
</td>
</tr>
</table>
#*This section contains a partial view _DisplayFiles.cshtml. The _DisplayFiles.cshtml has controls that generate 2 more modals. The modals contain either the
_DeleteFile.cshtml or _EditFile.cshtml partial views*#
<div id="UploadSection"></div>
#{
await Html.RenderPartialAsync("_DisplayFiles");
}
<div class="form-group">
<input type="submit" value="Save Changes" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
//Using this to scroll the page on the close of the modal/page refresh
$(document).ready(function () {
var JumpTo = '#ViewBag.JumpToDivId';
if (JumpTo != "") {
$(this).scrollTop($('#' + JumpTo).position().top);
}
});
//Using this to Capture the click that opens the modals
$('body').on('click', '.modal-link', function () {
var actionUrl = $(this).attr('href');
$.get(actionUrl).done(function (data) {
$('body').find('.modal-content').html(data);
});
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
});
//Using this to Capture the click that Submits the _EditFile,_DeleteFile,_CreateEdit forms on the modal
$('body').on('click', '.relative', function (e) {
e.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var dataToSend = form.serialize();
$.post(actionUrl, dataToSend).done(function (data) {
$('body').find('.modal-content').html(data);
var isValid = $('body').find('[name="IsValid"]').val() == 'True';
var issueid = "";
issueid = $('body').find('[name="issueidSaved"]').val();
var jumpto = $('body').find('[name="jumpto"]').val();
if (isValid) {
$('body').find('#modal-container').modal('hide');
if (issueid == "")
{
window.location.href = "/Issue/Edit/?id=" + issueid + "&jumpto=" + jumpto;
}
}
});
})
//Using this to Capture the click that Submits the _UploadFile form on the modal
$(function () {
$('body').on('click', '.fileupload', function (e) {
e.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var fdata = new FormData();
$('input[name="file"]').each(function (a, b) {
var fileInput = $('input[name="file"]')[a];
if (fileInput.files.length > 0) {
var file = fileInput.files[0];
fdata.append("file", file);
}
});
$("form input[type='text']").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
$("form input[type='hidden']").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
$.ajax({
url: actionUrl,
method: "POST",
contentType: false,
processData: false,
data: fdata
}).done((response, textStatus, xhr) => {
var isValid = $(response).find('[name="IsValid"]').val() == 'True';
var issueid = $(response).find('[name="issueidSaved"]').val();
var jumpto = $(response).find('[name="jumpto"]').val();
if (isValid) {
$('body').find('#modal-container').modal('hide');
window.location.href = "/Issue/Edit/?id=" + issueid + "&jumpto="+jumpto;
}
});
})
});
$('body').on('click', '.close', function () {
$('body').find('#modal-container').modal('hide');
});
$('#CancelModal').on('click', function () {
return false;
});
$("form").submit(function () {
if ($('form').valid()) {
$("input").removeAttr("disabled");
}
});
</script>
}
Here is the code for _UpdateFile.cshtml
#model MYAPP.Models.AttachmentModel
<!--Modal Body Start-->
<div class="modal-content">
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()" />
<input name="issueidSaved" type="hidden" value="#ViewBag.ID" />
<input name="jumpto" type="hidden" value="#ViewBag.JumpToDivId" />
<!--Modal Header Start-->
<div class="modal-header">
<h4 class="modal-title">Upload File</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<!--Modal Header End-->
<form asp-action="FileUpload" method="post" enctype="multipart/form-data" asp-controller="Attachment">
#Html.AntiForgeryToken()
<div class="modal-body form-horizontal">
<div>
<p>Upload a file using this form:</p>
<input type="file" name="file" />
<span asp-validation-for="#Model.aFileData" class="text-danger"></span>
</div>
<div>
<p>Enter a file description</p>
<input id="attachment" asp-for="#Model.aIssueAttachmentDescription" class="form-control" />
<span asp-validation-for="#Model.aIssueAttachmentDescription" class="text-danger"></span>
<input id="issueid" type="hidden" asp-for="#Model.issueId" class="form-control" value="#ViewBag.id" />
</div>
<!--Modal Footer Start-->
<div class="modal-footer">
#*<button type="submit" class="btn btn-success fileuploadmodal" data-save="modal">Upload</button>*#
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Cancel</button>
<input type="submit" class="btn btn-success fileupload" id="btnSubmit" data-save="modal" value="Upload">
</div>
<div class="row">
</div>
</div> <!--Modal Footer End-->
</form>
</div>
<script type="text/javascript">
$(function () {
});
</script>
<!--Modal Body End-->
Here is the code for the file Upload
[HttpPost]
public async Task<IActionResult> FileUpload(IFormFile file, IFormCollection collection)
{
if (file == null)
{
ModelState.AddModelError("aFileData", "Please select a file.");
}
if (collection["aIssueAttachmentDescription"] == "")
{
ModelState.AddModelError("aIssueAttachmentDescription", "Please provide a description for the file.");
}
if (!ModelState.IsValid)
{
return PartialView("_UploadFile");
}
var formFileContent =
await FileHelpers.ProcessFormFile<BufferedSingleFileUploadDb>(
file, ModelState, _permittedExtensions,
_fileSizeLimit);
var thefile = new AttachmentModel
{
aFileData = formFileContent,
aFileName = file.FileName,
aIssueAttachmentDescription = collection["aIssueAttachmentDescription"],
aFileSize = file.Length,
aFileType=file.ContentType,
issueId = collection["issueId"]
};
string result = _adoSqlService.InsertFile(thefile);
ViewBag.ID = collection["issueId"];
ViewBag.JumpToDivId = "upload";
return PartialView("_UploadFile");
}
You can see in the code above that I add in model errors if the file is not selected or the description is not filled in. These are not being shown.
I can live with the collection returning the entire Edit forms data, but ideally it should only return the fields on the _UploadFile.cshtml form (aIssueAttachmentDescription, issueId)
Anything you can provide that fixes the display of the model errors as well as a way to simplify my code would be greatly appreciated.
With the word "relative" misspelled, the file information is being sent to the action in the controller(see below). My guess is the Javscript isn't catching the click action ($('body').on('click', '.relative', function (e)). When I spell "relative" correctly the file information is NULL
The <input type="submit"> defines a submit button which submits all form values to a form-handler.So although you misspelled the word,it also could submit to the action successfully by default.
For how to use ajax to pass form data with file,you could follow:
#model Mvc3_0.Controllers.HomeController.AttachmentModel
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal">
Launch demo modal
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<!--Modal Body Start-->
<div class="modal-content">
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()" />
<!--Modal Header Start-->
<div class="modal-header">
<h4 class="modal-title">Upload File</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<!--Modal Header End-->
<form asp-action="FileUpload" method="post" enctype="multipart/form-data" asp-controller="Attachment">
#Html.AntiForgeryToken()
<div class="modal-body form-horizontal">
<div>
<p>Upload a file using this form:</p>
<input type="file" name="file" />
<span asp-validation-for="#Model.aFileData" class="text-danger"></span>
</div>
<div>
<p>Enter a file description</p>
<input id="attachment" asp-for="#Model.aIssueAttachmentDescription" class="form-control" />
<span asp-validation-for="#Model.aIssueAttachmentDescription" class="text-danger"></span>
<input id="issueid" type="hidden" asp-for="#Model.issueId" class="form-control" value="#ViewBag.id" />
</div>
<!--Modal Footer Start-->
<div class="modal-footer">
#*<button type="submit" class="btn btn-success fileuploadmodal" data-save="modal">Upload</button>*#
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Cancel</button>
<input type="submit" class="btn btn-success realative" id="btnSubmit" data-save="modal" value="Upload">
</div>
<div class="row">
</div>
</div> <!--Modal Footer End-->
</form>
</div>
</div>
</div>
#section Scripts
{
<script type="text/javascript">
$(function () {
$('body').on('click', '.realative', function (e) {
e.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var fdata = new FormData();
$('input[name="file"]').each(function (a, b) {
var fileInput = $('input[name="file"]')[a];
if (fileInput.files.length > 0) {
var file = fileInput.files[0];
fdata.append("file", file);
}
});
$("form input[type='text']").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
$("form input[type='hidden']").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
$.ajax({
url: actionUrl,
method: "POST",
contentType: false,
processData: false,
data: fdata
}).done((response, textStatus, xhr) => {
$("#exampleModal").modal('hide'); //update here...
});
})
});
</script>
}
Update1:
.done((response, textStatus, xhr) => {
$("#exampleModal").modal('hide'); //update here...
});
Update2:
By using your code,I find that you add the modal html in a form which is in the main page.This will cause the form in modal which is in _UploadFile.cshtml could not generate well in my project.Here is the whole working demo:
Main Page:
#model AttachmentModel
<div class="row">
<div>
//change here.....
<div id="modal-container" class="modal fade" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
</div>
</div>
</div>
<form asp-action="Edit">
<br />
#*This table contains the second control that generates a modal which contains the _UploadFile.cshtml*#
<table id="upload" width="100%">
<tr>
<td width="90%" style="padding:5px 5px 0px 5px;background-color:midnightblue;color:white">
<label class="control-label">Upload Attachments</label>
</td>
<td style="background-color: midnightblue; padding-right:5px">
<a href="#Url.Action("FileUpload", new { controller = "Attachment", issueid = "1" })"
class="modal-link btn btn-success">Upload Files</a>
</td>
</tr>
</table>
<div class="form-group">
<input type="submit" value="Save Changes" class="btn btn-primary" />
</div>
</form>
</div>
</div>
Js in Main Page:
#section Scripts
{
<script type="text/javascript">
$(function () {
$('body').on('click', '.modal-link', function () {
var actionUrl = $(this).attr('href');
$.get(actionUrl).done(function (data) {
$('body').find('.modal-content').html(data);
});
$(this).attr('data-target', '#modal-container');
$(this).attr('data-toggle', 'modal');
});
$('body').on('click', '.fileupload', function (e) {
e.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
console.log(actionUrl);
var fdata = new FormData();
$('input[name="file"]').each(function (a, b) {
var fileInput = $('input[name="file"]')[a];
if (fileInput.files.length > 0) {
var file = fileInput.files[0];
fdata.append("file", file);
}
});
$("form input[type='text']").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
$("form input[type='hidden']").each(function (x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
$.ajax({
url: actionUrl,
method: "POST",
contentType: false,
processData: false,
data: fdata
})
.done((response, textStatus, xhr) => {
var isValid = $(response).find('[name="IsValid"]').val() == 'True';
var issueid = $(response).find('[name="issueidSaved"]').val();
var jumpto = $(response).find('[name="jumpto"]').val();
if (isValid) {
$('body').find('#modal-container').modal('hide');
}
});
})
})
</script>
}
_UploadFile.cshtml:
#model AttachmentModel
<div class="modal-content">
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()" />
<input name="issueidSaved" type="hidden" value="#ViewBag.ID" />
<input name="jumpto" type="hidden" value="#ViewBag.JumpToDivId" />
<!--Modal Header Start-->
<div class="modal-header">
<h4 class="modal-title">Upload File</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<!--Modal Header End-->
<form asp-action="FileUpload" method="post" enctype="multipart/form-data" asp-controller="Home">
#Html.AntiForgeryToken()
<div class="modal-body form-horizontal">
<div>
<p>Upload a file using this form:</p>
<input type="file" name="file" />
<span asp-validation-for="#Model.aFileData" class="text-danger"></span>
</div>
<div>
<p>Enter a file description</p>
<input id="attachment" asp-for="#Model.aIssueAttachmentDescription" class="form-control" />
<span asp-validation-for="#Model.aIssueAttachmentDescription" class="text-danger"></span>
<input id="issueid" type="hidden" asp-for="#Model.issueId" class="form-control" value="#ViewBag.id" />
</div>
<!--Modal Footer Start-->
<div class="modal-footer">
#*<button type="submit" class="btn btn-success fileuploadmodal" data-save="modal">Upload</button>*#
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Cancel</button>
<input type="submit" class="btn btn-success fileupload" id="btnSubmit" data-save="modal" value="Upload">
</div>
<div class="row">
</div>
</div> <!--Modal Footer End-->
</form>
</div>
Controller:
[HttpPost]
public async Task<IActionResult> FileUpload(IFormFile file, IFormCollection collection)
{
var thefile = new AttachmentModel
{
aFileData = "asdad",
aIssueAttachmentDescription = collection["aIssueAttachmentDescription"],
issueId = collection["issueId"]
};
ViewBag.ID = collection["issueId"];
ViewBag.JumpToDivId = "upload";
return PartialView("_UploadFile");
}
Result:
I am trying to create an edit function for my data table. The data table is created using Yajra Data tables. Everything working fine unless when I try to load existing data into the edit modal it fails. No error is showing but the modal does not launch. I have only included a little portion of my code here for easy reference.
Modal:
<!-- Update Status Model Box -->
<div id="updateStatusModal" class="modal fade" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content bg-default">
<div class="modal-body">
<form class="form-horizontal" id="updateStatus">
#csrf
#method('PUT')
<div class="row">
<div class="col">
<div class="form-group text-center">
<h6 class="font-weight-bold">Stage 1</h6>
<label for="stage_1" class="switch">
<input type="checkbox" class="form-control" id="stage_1">
<div class="slider round"></div>
</label>
</div>
</div>
</div>
<div class="row">
<div class="col">
<div class="form-group">
<div class="col-md">
<label for="firstname">Coding</label>
<input type="text" class="form-control" id="first_name" value="" placeholder="Enter Completed Page Count">
</div>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer justify-content-between">
<button type="button" name="update_btn" id="update_btn" class="btn btn-outline-warning">Update</button>
</div>
</div>
</div>
</div>
jquery funtion:
// Edit action
$(document).on('click', '.updateStatus', function(){
$tr = $(this).closest('tr');
var data = $tr.clidren("td").map(function(){
return $(this).text();
}).get();
console.log(data);
$('#id').val(data[0]);
$('#job_id').val(data[2]);
$('#stage_1').val(data[3]);
$('#conversion').val(data[4]);
$('#updateStatusModal').modal('show');
});
I tried this method I found but this is not working. Can anyone provide me any pointers here?
I've just didn't seen your front scripts (also back-end codes), but instead I can share my implementation for that you need. It works perfectly like showed in this (screenshot).
Here I'll put front and back codes. There is functionality for editing existsing Datatable record, also record deletion.
FRONT
<!--HERE ATTACH NECESSARY STYLES-->
<!--VIEW end-->
<link rel="stylesheet" type="text/css" href="{{ asset('css/admin/datatables.min.css') }}"/>
<table id="yajra_datatable" class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Options</th>
</tr>
</thead>
</table>
<div class="modal modal-danger fade" id="modal_delete">
<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">Delete Language</h4>
</div>
<div class="modal-body">
<p>Are You sure You want to delete this Language?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline pull-left" data-dismiss="modal">Cancel</button>
<button id="delete_action" type="button" class="btn btn-outline">Submit</button>
</div>
</div>
</div>
</div>
<div class="modal modal-warning fade" id="modal_edit">
<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">Edit Language</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="language_name">Language Name</label>
<input name="language_name" id="language_name" type="text" value="" class="form-control" placeholder="Language Name">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline pull-left" data-dismiss="modal">Cancel</button>
<button id="edit_action" type="button" class="btn btn-outline">Submit</button>
</div>
</div>
</div>
</div>
<input type="hidden" id="item_id" value="0" />
<!--VIEW end-->
<!--HERE ATTACH NECESSARY SCRIPTS-->
<!--SCRIPTS start-->
<script src="{{ asset('js/admin/jquery.dataTables.min.js') }}"></script>
<script type="text/javascript">
var YajraDataTable;
function delete_action(item_id){
$('#item_id').val(item_id);
}
function edit_action(this_el, item_id){
$('#item_id').val(item_id);
var tr_el = this_el.closest('tr');
var row = YajraDataTable.row(tr_el);
var row_data = row.data();
$('#language_name').val(row_data.name);
}
function initDataTable() {
YajraDataTable = $('#yajra_datatable').DataTable({
"processing": true,
"serverSide": true,
"ajax": "{{ route('admin.book_languages.ajax') }}",
"columns":[
{
"data": "name",
"name": "name",
},
{
"data": "",
"name": ""
},
],
"autoWidth": false,
'columnDefs': [
{
'targets': -1,
'defaultContent': '-',
'searchable': false,
'orderable': false,
'width': '10%',
'className': 'dt-body-center',
'render': function (data, type, full_row, meta){
return '<div style="display:block">' +
'<button onclick="delete_action(' + full_row.id + ')" type="button" class="delete_action btn btn-danger btn-xs" data-toggle="modal" data-target="#modal_delete" style="margin:3px"><i class="fa fa-remove"></i> Delete</button>' +
'<button onclick="edit_action(this, ' + full_row.id + ')" type="button" class="edit_action btn btn-warning btn-xs" data-toggle="modal" data-target="#modal_edit" style="margin:3px"><i class="fa fa-edit"></i> Edit</button>' +
'</div>';
}
}
],
});
return YajraDataTable;
}
$(document).ready(function() {
var YajraDataTable = initDataTable();
$('#delete_action').on('click', function (e) {
e.preventDefault();
$.ajax({
url: "{{ route('admin.book_languages.delete') }}",
data: {
'item_id': $('#item_id').val(),
'_token': "{{ csrf_token() }}"
},
type: "POST",
success: function (data) {
$('#modal_delete').modal('hide');
YajraDataTable.ajax.reload(null, false);
console.log(data.message);
}
})
});
$('#edit_action').on('click', function (e) {
e.preventDefault();
$.ajax({
url: "{{ route('admin.book_languages.edit') }}",
data: {
'item_id': $('#item_id').val(),
'language_name': $('#language_name').val(),
'_token': "{{ csrf_token() }}"
},
type: "POST",
success: function (response) {
$('#modal_edit').modal('hide');
YajraDataTable.ajax.reload(null, false);
console.log(data.message);
}
})
});
$('#modal_delete').on('hidden.bs.modal', function () {
$('#item_id').val(0);
});
$('#modal_edit').on('hidden.bs.modal', function () {
$('#item_id').val(0);
$('#language_name').val("");
});
});
</script>
<!--SCRIPTS end-->
BACK
public function index() {
return view('admin.book-languages.index');
}
public function ajax() {
$items = BookLanguage::latest('id');
return DataTables::of($items)->make(true);
}
public function delete(Request $request) {
$item_id = $request->get('item_id');
$item = BookLanguage::find($item_id);
if(empty($item)) {
return response()->json([
'success' => false,
'message' => 'Item not found!',
], 200); // 404
} else {
$item->delete();
return response()->json([
'success' => true,
'message' => 'Item successfully deleted.',
], 200);
}
}
public function update(Request $request) {
$item_id = $request->get('item_id');
$item = BookLanguage::find($item_id);
if(empty($item)) {
return response()->json([
'success' => false,
'message' => 'Item not found!',
], 404);
} else {
$item->name = $request->get('language_name');
$item->save();
return response()->json([
'success' => true,
'message' => 'Item successfully updated.',
], 200);
}
}
ROUTES
// ...
// book_languages
Route::group(['prefix' => 'book-languages', 'as' => 'admin.book_languages.',], function () {
Route::get('all', 'BookLanguageController#index')->name('index');
Route::get('ajax', 'BookLanguageController#ajax')->name('ajax');
Route::post('update', 'BookLanguageController#update')->name('edit');
Route::post('delete', 'BookLanguageController#delete')->name('delete');
});
// ...
I think this can help you and others to build wanted functionality. Here this could be also with more hint-comments, but as it not small, I can answer later via post comments.
i am building a Laravel ERP-like web application and am implementing a CRUD function modal like you. I have made mine a server-side processing application with resource APIs in Laravel. Well, please be reminded that i have cut the #extends(layout.app) & #section('stylesheet') parts to go right into the answer. You should extend them in your own application to make everything work.
View.blade script
<script>
$(document).ready(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
var table = $('#customertable').DataTable({
processing: true,
serverSide: true,
dom: 'B<"top"frli>tp',
ajax: {
url: "{{ route('customer.index') }}", //Accessing server for data
columns: [
{data: 'id'}, //data refers to DB column name
{data: 'name'},
{data: 'chiname'},
{data: 'type'},
{data: 'action'}, //this is an addColumn item from Controller
]
});
$('#createNewcustomer').click(function () {
$('#saveBtn').val("create customer");
$('#customerid').val('');
$('#customerForm').trigger("reset");
$('#modelHeading').html("Create New Customer");
$('#customermodal').modal('show');
});
//Control the modal behavior when clicking the edit button.
$('body').on('click', '.editcustomer', function () {
var customerid = $(this).data('id');
$.get("{{ route('customer.index') }}" +'/' + customerid +'/edit', function (data) {
$('#modelHeading').html("Edit Customer");
$('#saveBtn').val("edit-user");
$('#customermodal').modal('show');
$('#customerid').val(data.id);
$('#name').val(data.name);
$('#chiname').val(data.chiname);
$('#type').val(data.type);
})
});
//Create a brand-new record
$('#createNewcustomer').click(function () {
$('#saveBtn').val("create customer");
$('#customerid').val('');
$('#customerForm').trigger("reset");
$('#modelHeading').html("Create New Customer");
$('#customermodal').modal('show');
});
//Update
$('body').on('click', '.editcustomer', function () {
var customerid = $(this).data('id');
$.get("{{ route('customer.index') }}" +'/' + customerid +'/edit', function (data) {
$('#modelHeading').html("Edit Customer");
$('#saveBtn').val("edit-user");
$('#customermodal').modal('show');
$('#customerid').val(data.id);
$('#name').val(data.name);
$('#chiname').val(data.chiname);
$('#type').val(data.type);
})
});
//Save
$('#saveBtn').click(function (e) {
e.preventDefault();
$(this).html('Sending..');
$.ajax({
data: $('#customerForm').serialize(),
url: "{{ route('customer.store') }}",
type: "POST",
dataType: 'json',
success: function (data) {
$('#customerForm').trigger("reset");
$('#customermodal').modal('hide');
table.draw();
},
error: function (data) {
console.log('Error:', data);
$('#saveBtn').html('Error');}
});
});
//Delete
$('body').on('click', '.deletecustomer', function () {
var id = $(this).data("id");
confirm("Are You sure?");
$.ajax({
type: "DELETE",
url: "{{ route('customer.store') }}"+'/'+id,
success: function (data) {
table.draw();
},
error: function (data) {
console.log('Error:', data);
}
});
});
</script>
View.blade html-table & modal part
#section('content')
<div class="container">
<div class="card-header border-left"><h3><strong> Customer overview</strong></h3></div>
<br>
<div class="row">
<div class="col-md text-right">
<button type="button" class="btn btn-success" data-toggle="modal" href="javascript:void(0)" id="createNewcustomer">Create Record</button>
</div>
</div>
{{-- Modal --}}
<div id="customermodal" class="modal fade" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="modelHeading"></h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button></div>
<div class="modal-body">
<form id="customerForm" name="customerForm" class="form-horizontal">
<input type="hidden" name="customerid" id="customerid">
<div class="form-group">
<label for="name" class="col-sm-6 control-label">Customer Name</label>
<div class="col-sm-12">
<input type="text" class="form-control" id="name" name="name" placeholder="Name" value="" maxlength="50" required="">
</div>
</div>
<div class="form-group">
<label class="col-sm-6 control-label">Customer Name</label>
<div class="col-sm-12">
<input type="text" class="form-control" id="chiname" name="chiname" placeholder="Customer Name" value="" maxlength="50" required="">
</div>
</div>
<div class="form-group">
<label class="col-sm-6 control-label">Contract type</label>
<div class="col-sm-12">
<select name="type" id="type" class="form-control">
<option value="" disabled>Type</option>
<option value="Government">Government Contract</option>
<option value="Private">Private Contract</option>
</select>
</div></div>
<br>
<div class="col-sm text-right">
<button type="submit" class="btn btn-outline-secondary" id="saveBtn" value="create">Save changes</button>
</div>
</form>
</div>
</div>
</div>
</div>
{{-- Table --}}
<br>
<div class="row">
<br/>
<br/>
<div class="form-group col-md-12 align-content-center">
<table class="table-fluid center-block" id="customertable">
<thead>
<tr>
<th>id</th>
<th>ChiName</th>
<th>Name</th>
<th>Type</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
#endsection
CustomerController
public function index(Request $request)
{
$customers = Customer::all();
}
return Datatables::of($customers)
->addColumn('action', function($customer){
$btn = 'Edit';
$btn = $btn.' Delete';
return $btn;})
->rawColumns(['action'])
->make(true);
}
return view('customer.Customer'); //my view blade is named Customer under customer dir. put your blade destination here.
}
public function store(Request $request)
{
Customer::updateOrCreate(['id' => $request->customerid],
['name' => $request->name, 'chiname' => $request->chiname,'type' =>$request->type]);
return response()->json(['success'=>'Product saved successfully.']);
}
public function edit($id)
{
$customer = Customer::findorfail($id);
return response()->json($customer);
}
public function destroy($id)
{
Customer::findorfail($id)->delete();
return response()->json(['success'=>'Product deleted successfully.']);
}
Model (pick either A.) $guarded = [] OR B.) $fillable = ['fields','fields'] as you like)
class Customer extends Model
{
protected $fillable = ['name','chiname','type'];
}
web.api (route setting)
Route::resource('customer', 'CustomerController')->middleware('auth');
Migration / DB schema structure
class CreateCustomersTable extends Migration
{
public function up()
{
Schema::create('customers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('chiname');
$table->string('type');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('customers');
}
I have not included any protection in it like gate, auth or so. But basically this is the skeleton of doing CRUD with dataTable in Laravel framework with both JS, Ajax, Jquery, PHP all in one. Kindly be reminded that the queries for such CRUD actions are directly linked to the Database server. If you want to show data processed by the DataTable, use your own jquery function to fetch and show them on the modal. My answer is not the best but i hope it helps you >:)
(I could not post a picture to show you here as i dont have enough reputation lol. gg)
I have a view. I want to load it to get all information then click Edit or Delete button to do something. When click Edit button then I hope it goes to another view.
#model Models.CountryLanguagesModel
#{
ViewBag.Title = "Language";
}
<div class="span4 proj-div text-center" data-toggle="modal" data-target="#addLanguageModal">
<u>Add Language</u>
<div><br /> </div>
<table class="table table-bordered table-dark-header table-responsive">
<tr>
<th class="text-center">Language Name</th>
<th class="text-center">Welcome Message</th>
<th></th>
</tr>
#foreach (var item in Model.CountryLanguages)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.LanguageName)</td>
<td>#Html.DisplayFor(modelItem => item.WelcomeMessage)</td>
</tr>
}
</table>
</div>
<div class="container">
<div class="col-md-8 col-md-offset-2">
<button class="btn btn-success" id="editLanguage">Edit</button>
<button class="btn btn-danger" id="deleteLanguage">Delete</button>
</div>
</div>
<div class="modal fade" id="addLanguageModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3>Add Language</h3>
</div>
<div class="modal-body">
<div class="form-group">
</div>
<div class="form-group">
<div class="left">
<label>Language Name:</label>
</div>
<div class="right">
<input type="text" class="form-control" name="languageName" id="languageName" />
</div>
</div>
<div class="form-group">
<div class="left">
<label>Welcome Messagee:</label>
</div>
<div class="right">
<input type="text" class="form-control" name="welcomeMessage" id="welcomeMessage" />
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-gray" data-dismiss="modal" aria-hidden="true">Close</button>
<button class="btn btn-primary" id="addLanguageBtn">Save</button>
</div>
</div>
</div>
</div>
#section scripts
{
<script type="text/javascript">
$(document).ready(function () {
$("#addLanguageBtn").on("click", function (evt) {
var CountryId = #Model.CountryId;
var languageName = $("#languageName").val();
var welcomeMessage = $("#welcomeMessage").val();
$.post("/Country/AddLanguage", { id: CountryId, languageName: languageName, welcomeMessage: welcomeMessage }, function (data) {
$("#languageName").val("");
$("#welcomeMessage").val("");
$("#addLanguageModal").modal('hide');
});
});
$("#editLanguage").on("click", function (evt) {
var CountryId = #Model.CountryId;
$.post("/Country/LanguageEdit", { id: CountryId }, function () {
});
});
$("deleteLanguage").on("click", function (evt) {
var CountryId = #Model.CountryId;
$.post("/Country/LanguageDelete", { id: CountryId }, function () {
});
});
});
</script>
}
Now the question is when the page loaded, I found the the code reached click event script. It is strange. When I click the button, it doesn't reach the script. But it goes to the controller action method,
[HttpPost]
public ActionResult LanguageEdit(MyModel model)
{
I guess some stupid error to cause the onclick event not fired correctly, but I can't figure it out.
EDIT
public ActionResult LanguageEdit(int id)
{
var model = new CountryLanguageModel();
model.CountryId = id;
model.CountryLanguageQuestion = MyService.GetQuestion(x => x.CountryId == id);
return View(model);
}
Add type='button' attribute to your buttons, if not it will behave as a submit button.
can you change button to a ?
<button class="btn btn-success" id="editLanguage">Edit</button>
to
<a href="/Country/LanguageEdit?id=#Model.CountryId" class="btn btn-success" />
Some more information
if you want to GET somekind of HTML use HTTPGET instead of HTTPPOST.
Use HTTPPOST if you want to send some kind of information, that server should for example save. Use HTTPGET if you want to render some kind of view ( for example get a new view),
Your Action required 'MyModel model' not a id.
As per your comment you may get this behaviour:
why it was fired when page loaded, I didn't click the button at all.
When your javascript code not inside the button click event and instead it is inside any of the other event such document ready or page load ..etc.
So kindly check the event of javascript and surely you will get the direction to solution .
After checked ,If you ,still had the same problem. kindly show us your javascript so that it will be useful to help you further
Thanks
Karthik