On a web page who have many tab, i have a input box who do a search via a ajax call.
If there is no result, i would like to display a modal dialog box.
<div role="tabpanel">
<div class="row">
<div class="span12">
<nav role="navigation" class="navbar navbar-default navbar-right">
<form class="navbar-form" role="search">
<div class="checkbox">
<label>
<input type="checkbox" id="inactiveLodger"> Locataire inactif
</label>
</div>
<div class="input-group">
<input type="text" class="form-control" placeholder="Rechercher" name="srch-term" id="srch-term">
<div class="input-group-btn">
<button id="lodgerSearch" type="button" class="btn btn-default"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
</form>
</nav>
<div class="modal fade" id="modalEmptyResult">
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>Résultat de recherche</h3>
</div>
<div class="modal-body">
<p>Aucun résultat ne correspondant à votre requête</p>
</div>
<div class="modal-footer">
Fermer
</div>
</div>
</div>
</div>
...
$('#lodgerSearch').on('click', function (e) {
var inactiveLodger = $('#inactiveLodger').is(':checked');
debugger;
var searchParam = $('#srch-term').val();
var url = "http://localhost:8080/lodgers/search";
if (searchParam != "") {
url = url + "?searchTerm=" + searchParam;
}
if (inactiveLodger == true) {
url = url + "?inactiveLodger=true";
}
jQuery.ajax({
type: "GET",
url: url,
success: function (data, status, jqXHR) {
debugger;
if (data.length == 0) {
$("#lodgerSearchResult").empty();
$('#modalEmptyResult').modal('show');
} else {
$("#lodgerSearchResult").empty().append(template(data));
}
},
error: function (jqXHR, status) {
// error handler
alert("error " + jqXHR + " - " + status);
}
});
// e.preventDefault();
});
Like we can see on the picture, we can see the dialog box, but it's seem transparent.
I created a basic example with similar problem.
https://jsfiddle.net/m7eop6k1/
Strange with jquery 1.9.1 that work... but not with latest release of jquery.
Related
I use the Modal display field in the Partial View to input data for the User, and use data-url=#url.action("Create") in the main screen to call Modal.
And wrote Autocomplete JavaScript in Partial View.
It works perfectly before using Ajax Post.
But after going through Ajax, the JavaScript cannot be used when it returns because of an error.
How can I make corrections?
Main View
<div id="PlaceHolderHere" data-url="#Url.Action("Create")"></div>
Ajax Code
$(function () {
var PlaceHolderElement = $('#PlaceHolderHere');
$('button[data-toggle="ajax-modal"]').click(function (event) {
event.preventDefault();
var url = $(this).data('url');
$.get(url).done(function (data) {
PlaceHolderElement.html(data);
PlaceHolderElement.find('.modal').modal('show');
});
});
PlaceHolderElement.on('click', '[data-save="modal"]', function (event) {
event.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var sendData = new FormData(form.get(0));
console.log(sendData);
$.ajax({
url: actionUrl,
method: 'post',
data: sendData,
processData: false,
contentType: false,
cache: false,
success: function (redata) {
console.log(redata);
if (redata.status === "success") {
PlaceHolderElement.find('.modal').modal('hide');
}
else {
var newBody = $('.modal-body', redata);
var newFoot = $('.modal-footer', redata);
PlaceHolderElement.find('.modal-body').replaceWith(newBody);
PlaceHolderElement.find('.modal-footer').replaceWith(newFoot);
}
},
error: function (message) {
alert(message);
}
})
})
})
Partial View of JavaScript part
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/bootstrap-autocomplete/dist/latest/bootstrap-autocomplete.min.js"></script>
$('#BossName').autoComplete({
resolver: 'custom',
minLength: 2,
formatResult: function (item) {
return {
value: item.value,
text: "[" + item.value + "] " + item.text,
}
},
noResultsText:'There is no matching data, please confirm whether there is data in the company field',
events: {
search: function (qry, callback) {
// let's do a custom ajax call
$.ajax(
'#Url.Action("GetRolesByAutoComplete","Roles")',
{
data: {
'q': qry,
'key': document.getElementById('CompanyCode').value
}
}
).done(function (res) {
callback(res)
});
}
}
});
$('#BossName').on('autocomplete.select', function (evt, item) {
console.log(item);
$('#BossID').val(item.value);
$('#BossName').val(item.text);
});
Partial View of Modal
<div class="modal fade" id="AddEditRoles" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="AddEditRolesLabel">Add New Roles</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form asp-action="Create" id="Edit">
<div class="input-group">
<span class="input-group-text">#Html.DisplayNameFor(m => m.RolesCode)</span>
#if (Model != null && Model.RolesCode != null)
{
<input asp-for="RolesCode" class="form-control" readonly />
}
else
{
<input asp-for="RolesCode" class="form-control" autocomplete="off" />
}
<span asp-validation-for="RolesCode" class="text-danger"></span>
</div>
<div class="input-group">
<span class="input-group-text">#Html.DisplayNameFor(m => m.Title)</span>
<input asp-for="Title" class="form-control" autocomplete="off" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="input-group">
<span class="input-group-text">#Html.DisplayNameFor(m => m.CompanyCode)</span>
<input type="text" asp-for="CompanyCode" class="form-control col-md-3" readonly />
<input type="text" id="CompanyName" class="form-control" autocomplete="off"
placeholder="Please type Key word" />
<span asp-validation-for="CompanyCode" class="text-danger"></span>
</div>
<div class="input-group">
<span class="input-group-text">#Html.DisplayNameFor(m => m.BossID)</span>
<input asp-for="BossID" type="text" class="form-control col-md-3" readonly />
<input id="BossName" type="text" class="form-control" autocomplete="off"
placeholder="Please type Key word" />
<span asp-validation-for="BossID" class="text-danger"></span>
</div>
</form>
</div>
<div class="modal-footer">
<div class="text-danger">#Html.ValidationMessage("error")</div>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button id="Save" type="button" class="btn btn-primary" data-save="modal">Save changes</button>
</div>
</div>
</div>
</div>
You send data to the server, but when it fails you replace modal contents.
Replacing HTML destroys everything that was already there, so you wipe everything that was done by your autocomplete plugin.
All you need to do is to initialize autocomplete again:
success: function (redata) {
if (redata.status === "success") {
} else {
var newBody = $('.modal-body', redata);
var newFoot = $('.modal-footer', redata);
PlaceHolderElement.find('.modal-body').replaceWith(newBody);
PlaceHolderElement.find('.modal-footer').replaceWith(newFoot);
// INITIALIZE AUTOCOMPLETE HERE
}
},
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 have an issue in generating anti-forgery token manually inside ajax methods. So my question If I used ajax.beginform(), does it generate a token like the #html.beginform? If so, how can I use it with my ajax methods?
Kindly ignore the long code in the view. My main concern is with the ajax methods. I posted it to show you the view in case of the suggestion of using the beginForm().
#*#Html.AntiForgeryToken()*#
<hr />
<div class="row">
<div class="col-lg-6">
<label><strong>Month:</strong></label>
</div>
<div class="col-lg-6">
<label>#manning_HQ.Issue_Date</label>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label><strong>Count:</strong></label>
</div>
<div class="col-lg-6">
<label>#manning_HQ.Count</label>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<label><strong>Location:</strong></label>
</div>
<div class="col-lg-6">
<label>#manning_HQ.Location_Name</label>
</div>
</div>
<hr />
<div class="col-lg-4">
<label>Recruitment Status :</label>
</div>
<div class="col-lg-3">
<select id="recruitment_Status">
<option value="0">
Choose Status
</option>
#foreach (TBL_Recruitment_Status rec in recruitment_Status)
{
<option value="#rec.Rec_Status_ID">
#rec.Status_Name
</option>
}
</select>
</div>
<div class="row">
<div class="col-lg-12">
<label><strong>Issue staff requisition:</strong></label>
</div>
</div>
<div class="row">
<div class="col-lg-6">
<input type="radio" name="Decision" id="_123" value="Accepted" />
Accepted
</div>
<div class="col-lg-6">
<input type="radio" name="Decision" id="_456" value="Rejected" />
Rejected
</div>
</div>
<hr />
<div class="row" id="RejComment" hidden>
<div class="col-lg-6">
<label>Rejected Comment :</label>
</div>
<div class="col-lg-3">
<textarea id="RetainedComment"></textarea>
</div>
</div>
<br />
<div class="modal-footer" id="Save_Dicision" hidden>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="saveDecision(#manning_HQ.Issue_Staff_ID)">Save</button>
</div>
<script>
var DecesionCheck = false;
var rejected = false;
var reason = false;
$(document).ready(function () {
$('input[type=radio][name=Decision]').change(function () {
if ($("input[name='Decision']:checked").val() == 'Accepted') {
$('#RejComment').hide();
$('#Save_Dicision').show();
rejected = true;
}
if ($("input[name='Decision']:checked").val() == 'Rejected') {
$('#RejComment').show();
$('#Save_Dicision').show();
rejected = true;
}
});
});
function saveDecision(ID) {
var Decsion = $('input[name=Decision]:checked').val();
var Reason = $('#recruitment_Status').val();
//var token = $("[name='__RequestVerificationToken']").val();
if (Decsion == "#_123") {
if (DecesionCheck == true) {
var Decsion = $('input[name=Decision]:checked').val();
var optionalComment = $('#OptionalComment').val();
$.ajax({
type: 'POST',
url: '/Staff_Requisition_HQ/Recruitment_Actions',
data: {
// __RequestVerificationToken: token,
Issue_Staff_ID: ID,
Rec_Status_ID: Reason,
OpComment: RetainedComment,
RecDecison: Decsion,
},
success: function (result) {
$('#DescionDetailsPOPUP').modal('hide');
location.reload();
},
fail: function (xhr, textStatus, errorThrown) {
alert('request failed');
}
});
}
}
else {
var Decsion = $('input[name=Decision]:checked').val();
var RetainedComment = $('#RetainedComment').val();
$.ajax({
type: 'POST',
url: '/Staff_Requisition_HQ/Recruitment_Actions',
data: {
//__RequestVerificationToken: token,
Issue_Staff_ID: ID,
Rec_Status_ID: Reason,
Comment: RetainedComment,
RecDecison: Decsion,
},
success: function (result) {
$('#DescionDetailsPOPUP').modal('hide');
location.reload();
},
fail: function (xhr, textStatus, errorThrown) {
alert('request failed');
}
});
}
}
</script>
Here's an example of Ajax.BeginForm from one of my views:
<!-- FORM Atributo -->
#using (Ajax.BeginForm(accionFormulario, "Atributos", new AjaxOptions() { OnSuccess = "onSuccessCreate" }, new { #id = "frmCreate" }))
{
#Html.AntiForgeryToken()
#Html.HiddenFor(model => model.AtributoId)
#Html.HiddenFor(model => model.EmpresaId)
<div class="modal-body">
<div class="row">
// the form inputs ....
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary mx-1" type="button" data-dismiss="modal" aria-label="Close">#Global.Cancelar</button>
<button class="btn btn-primary" type="submit"><strong>#Global.Guardar</strong></button>
</div>
}
This generates the AntiForgeryToken as expected:
You can capture it with javascript as you were doing in your view.
So this is my brand.php file
And it portrays the edit part of the brand
so in this part we can probably see how the thing will look like
<!-- edit brand -->
<div class="modal fade" id="editBrandModel" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<form class="form-horizontal" id="editBrandForm" action="php_action/editBrand.php" method="POST">
<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"><i class="fa fa-edit"></i> Edit Brand</h4>
</div>
<div class="modal-body">
<div id="edit-brand-messages"></div>
<div class="modal-loading div-hide" style="width:50px; margin:auto;padding-top:50px; padding-bottom:50px;">
<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>
<span class="sr-only">Loading...</span>
</div>
<div class="edit-brand-result">
<div class="form-group">
<label for="editBrandName" class="col-sm-3 control-label">Brand Name: </label>
<label class="col-sm-1 control-label">: </label>
<div class="col-sm-8">
<input type="text" class="form-control" id="editBrandName" placeholder="Brand Name" name="editBrandName" autocomplete="off">
</div>
</div> <!-- /form-group-->
<div class="form-group">
<label for="editBrandStatus" class="col-sm-3 control-label">Status: </label>
<label class="col-sm-1 control-label">: </label>
<div class="col-sm-8">
<select class="form-control" id="editBrandStatus" name="editBrandStatus">
<option value="">~~SELECT~~</option>
<option value="1">Available</option>
<option value="2">Not Available</option>
</select>
</div>
</div> <!-- /form-group-->
</div>
<!-- /edit brand result -->
</div> <!-- /modal-body -->
<div class="modal-footer editBrandFooter">
<button type="button" class="btn btn-default" data-dismiss="modal"> <i class="glyphicon glyphicon-remove-sign"></i> Close</button>
<button type="submit" class="btn btn-success" id="editBrandBtn" data-loading-text="Loading..." autocomplete="off"> <i class="glyphicon glyphicon-ok-sign"></i> Save Changes</button>
</div>
<!-- /modal-footer -->
</form>
<!-- /.form -->
</div>
<!-- /modal-content -->
</div>
<!-- /modal-dailog -->
</div>
<!-- / add modal -->
<!-- /edit brand -->
> --this one is the end part
And this is the fetching part, wherein once you click the button from the row(example row 1), a modal(Edit Modal will likely appear), but the thing is, once the modal appear, the data that is supposed to be fetched from the row is not on that modal ;-;
<?php
require_once '../../includes/connection.php';
$brandId = $_POST['brandId'];
$sql = "SELECT brand_id, brand_name, brand_active, brand_status FROM brands WHERE brand_id = $brandId";
$result = $connect->query($sql);
if($result->num_rows > 0) {
$row = $result->fetch_array();
} // if num_rows
$connect->close();
echo json_encode($row);
?>
Now the JScript part
This part is the filler part(like getting the data and now portraying the data and filling the input boxes etc..)
function editBrands(brandId = null) {
if(brandId) {
// remove hidden brand id text
$('#brandId').remove();
// remove the error
$('.text-danger').remove();
// remove the form-error
$('.form-group').removeClass('has-error').removeClass('has-success');
// modal loading
$('.modal-loading').removeClass('div-hide');
// modal result
$('.edit-brand-result').addClass('div-hide');
// modal footer
$('.editBrandFooter').addClass('div-hide');
$.ajax({
url: 'fetchSelectedBrand.php',
type: 'post',
data: {brandId : brandId},
dataType: 'json',
success:function(response) {
// modal loading
$('.modal-loading').addClass('div-hide');
// modal result
$('.edit-brand-result').removeClass('div-hide');
// modal footer
$('.editBrandFooter').removeClass('div-hide');
// setting the brand name value
$('#editBrandName').val(response.brand_name);
// setting the brand status value
$('#editBrandStatus').val(response.brand_active);
// brand id
$(".editBrandFooter").after('<input type="hidden" name="brandId" id="brandId" value="'+response.brand_id+'" />');
// update brand form
$('#editBrandForm').unbind('submit').bind('submit', function() {
// remove the error text
$(".text-danger").remove();
// remove the form error
$('.form-group').removeClass('has-error').removeClass('has-success');
var brandName = $('#editBrandName').val();
var brandStatus = $('#editBrandStatus').val();
if(brandName == "") {
$("#editBrandName").after('<p class="text-danger">Brand Name field is required</p>');
$('#editBrandName').closest('.form-group').addClass('has-error');
} else {
// remov error text field
$("#editBrandName").find('.text-danger').remove();
// success out for form
$("#editBrandName").closest('.form-group').addClass('has-success');
}
if(brandStatus == "") {
$("#editBrandStatus").after('<p class="text-danger">Brand Name field is required</p>');
$('#editBrandStatus').closest('.form-group').addClass('has-error');
} else {
// remove error text field
$("#editBrandStatus").find('.text-danger').remove();
// success out for form
$("#editBrandStatus").closest('.form-group').addClass('has-success');
}
if(brandName && brandStatus) {
var form = $(this);
// submit btn
$('#editBrandBtn').button('loading');
$.ajax({
url: form.attr('action'),
type: form.attr('method'),
data: form.serialize(),
dataType: 'json',
success:function(response) {
if(response.success == true) {
console.log(response);
// submit btn
$('#editBrandBtn').button('reset');
// reload the manage member table
manageBrandTable.ajax.reload(null, false);
// remove the error text
$(".text-danger").remove();
// remove the form error
$('.form-group').removeClass('has-error').removeClass('has-success');
$('#edit-brand-messages').html('<div class="alert alert-success">'+
'<button type="button" class="close" data-dismiss="alert">×</button>'+
'<strong><i class="glyphicon glyphicon-ok-sign"></i></strong> '+ response.messages +
'</div>');
$(".alert-success").delay(500).show(10, function() {
$(this).delay(3000).hide(10, function() {
$(this).remove();
});
}); // /.alert
} // /if
}// /success
}); // /ajax
} // /if
return false;
}); // /update brand form
} // /success
}); // ajax function
} else {
alert('error!! Refresh the page again');
}
} // /edit brands function
Can you check the Network tab to see the result from server? You can debug your app by seeing that result.
By the way, there're two things that you may need to edit:
1/ If brandId is interger, you need to get it from $_GET by intval($_POST['brandId']) to prevent SQL Injection.
2/
if($result->num_rows > 0) {
$row = $result->fetch_array();
}
else {
$row = array();
}
your code need to return empty array if sql result is empty to avoid Undefined variable error.
i wrote this to get form data and post it to a php page and do some proccess and get back a result to me,i start with getting post data from my bootstrap modal form and i found that the script can't take values from modal form,because the php part i can't upload it to fiddle or somewhere else.
i upload it on my server for rapid review
click on compose;
complete the fields
and when Send button clicked it expect to modal form sent some value to jquery ajax(on submit) but nothing sent from modal inputs to ajax and the whole $_POST array remain null,and whats going on?
hours and hours i searched for doc's and example's,but i couldn't found any answer,some examples works with bootstrap 2,and nothing for the bootstrap 3.
bootstrap 3.3.1,jquery 2.1.1
here is the modal code:
<div class="modal fade" id="largeModal" tabindex="-1" role="dialog" aria-labelledby="largeModal" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Compose</h4>
</div>
<div class="modal-body">
<form id="sendmail" data-async method="post" role="form" class="form-horizontal">
<div class="form-group">
<label class="col-sm-2" for="inputTo">To</label>
<div class="col-sm-10">
<input type="email" class="form-control" id="inputTo" placeholder="comma separated list of recipients">
</div>
</div>
<div class="form-group">
<label class="col-sm-2" for="inputSubject">Subject</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="inputSubject" placeholder="subject">
</div>
</div>
<div class="form-group">
<label class="col-sm-12" for="inputBody">Message</label>
<div class="col-sm-12">
<textarea class="form-control" id="inputBody" rows="18"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary" value="Submit">Send</button>
<div id='response'></div>
</div>
</form>
</div>
</div>
</div>
jQuery:
$(document).ready(function () {
$('#sendmail').submit(function () {
$('#response').html("<b>Loading response...</b>");
$.ajax({
type: 'POST',
url: 'proccess.php',
data: $(this).serialize()
})
.done(function (data) {
$('#response').html(data);
})
.fail(function () {
alert("Posting failed.");
});
return false;
});
});
Simple PHP Code:
print_r($_POST);
In your code, this which is provided inside the $.ajax method's object refers ajax object. And it seems that you need to refer to the form from which you have to get the data and serialise it and send it into AJAX request.
Try following code,
$(document).ready(function () {
$('#sendmail').submit(function () {
var that = this;
$('#response').html("<b>Loading response...</b>");
$.ajax({
type: 'POST',
url: 'proccess.php',
data: $(that).serialize()
})
.done(function (data) {
$('#response').html(data);
})
.fail(function () {
alert("Posting failed.");
});
return false;
});
});
here I have referred the form object this by assigning it to that