I'm creating a page that can add more than one invoice in a page. There is a link, to display invoice fields in modal form. This form is dynamically created using ajax.
After filling out the invoice fields, I want to submit the form by button in the modal footer. This button is not generated dynamically, only form in the modal body.
How to submit the invoice fields in modal form using button that is outside the modal form?
Here is the code
Create Invoice View
#using (Html.BeginForm("Create", "Invoice", FormMethod.Post, new { #enctype = "multipart/form-data" }))
{
<div class="form-horizontal">
<div id="invoiceList">
#{ Html.RenderPartial("_InvoiceList", Model.Invoices); }
</div>
Add Row..
<br />
<div class="form-group">
<div class="col-md-12">
<input type="submit" value="Submit" class="btn btn-primary" />
</div>
</div>
</div>
}
<div class="modal fade" id="addInvoiceModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">Add Invoice</h4>
</div>
<div class="modal-body" id="add-invoice-container">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" id="btnSaveInvoice">Save changes</button>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$("#lnkAddInvoice").click(function (e) {
$.ajax({
type: "GET",
url: "#Url.Content("~/Invoice/AddInvoice")",
cache: false
}).done(function (data) {
if (!data.message) {
$("#add-invoice-container").html(data);
$("#addInvoiceModal").modal({ show: true, backdrop: true });
} else {
$("#addInvoiceModal").modal("hide");
}
});
});
$("#btnSaveInvoice").click(function (e) {
// Submit frmInvoice in modal form ???
});
});
</script>
AddInvoice (Modal)
#using (Html.BeginForm("AddInvoice", "Invoice", FormMethod.Post, new { #id = "frmInvoice" }))
{
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.InvoiceNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.InvoiceNo, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.InvoiceNo, "", new { #class = "text-danger" })
</div>
</div>
</div>
}
Not sure i got understood the question correct, but if you only have the button outside the form you could do something like this.
$("#btnSaveInvoice").click(function (e) {
var $frm = $("#frmInvoice");
if($frm.length > 0){
$frm.submit()
}
});
Form submit jquery
In HTML5 you can use the form attribute to specify a button that is outside the <form> tags is associated with the form
<form id="myForm" .....> // give the form an ID
....
</form>
<button type="submit" form="myForm" value="Submit">Submit</button>
Note: It seems that this may not yet be supported in IE
Related
I am following this guide (https://softdevpractice.com/blog/asp-net-core-mvc-ajax-modals/) for my Modals, and got everything working except for the last part which closes the Modal when it saves without errors. Essentially what the article shows is to add an IsValid input tag that's hidden and stores the ModelState which would be used to determine whether or not it is a successful save and should close the modal.
// find IsValid input field and check it's value
// if it's valid then hide modal window
var isValid = newBody.find('[name="IsValid"]').val() == 'True';
if (isValid) {
placeholderElement.find('.modal').modal('hide');
}
Would love any input on this. My code is as follows:
View
<div id="AddStudyModal"></div>
// unrelated code here
<button type="button" class="btn btn-secondary" data-toggle="ajax-modal" data-bs-target="#add-study" data-url="#Url.Action("AddStudy", "App", new {id = Model.GUID})">Add</button>
Partial View
#model AddStudyViewModel
<div class="modal fade" id="add-study" tabindex="-1" role="dialog" aria-labelledby="addStudyLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addStudyLabel">Add Study</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form asp-controller="App" asp-action="AddStudy" method="post">
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()"/>
#Html.HiddenFor(m => m.ParticipantGuid)
<div asp-validation-summary="ModelOnly"></div>
<div class="mb-3 form-group">
#* <label asp-for="Studies" class="form-label"></label> *#
<select asp-for="SelectedStudyGuid" asp-items="#ViewBag.Studies" class="form-control" autocomplete="off">
#* <select asp-for="SelectedStudyGuid" asp-items="#Model.Studies" class="form-control" autocomplete="off"> *#
<option value="">Select Study</option>
</select>
<span asp-validation-for="SelectedStudyGuid" class="text-danger"></span>
</div>
<div class="mb-3 form-group">
<label asp-for="StartDate" class="form-label"></label>
<input asp-for="StartDate" class="form-control" autocomplete="off"/>
<span asp-validation-for="StartDate" class="text-danger"></span>
</div>
<div class="mb-3 form-group">
<label asp-for="EndDate" class="form-label"></label>
<input asp-for="EndDate" class="form-control" autocomplete="off"/>
<span asp-validation-for="EndDate" class="text-danger"></span>
</div>
<div class="text-center">
</div>
<div class="text-center">#ViewBag.Message</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" data-save="modal">Save</button>
</div>
</div>
</div>
</div>
Site.Js
$(function (){
var AddStudyElement = $('#AddStudyModal');
$('button[data-toggle="ajax-modal"]').click(function(event){
var url = $(this).data('url');
$.get(url).done(function(data){
AddStudyElement.html(data);
AddStudyElement.find('.modal').modal('show');
})
})
AddStudyElement.on('click', '[data-save="modal"]', function(event){
event.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
var sendData = form.serialize();
// $.post(actionUrl, sendData).done(function(data){
// AddStudyElement.find('.modal').modal('hide');
// })
$.post(actionUrl, sendData).done(function (data) {
var newBody = $('.modal-body', data);
AddStudyElement.find('.modal-body').replaceWith(newBody);
// find IsValid input field and check it's value
// if it's valid then hide modal window
var isValid = newBody.find('[name="IsValid"]').val() == 'True';
if (isValid) {
AddStudyElement.find('.modal').modal('hide');
}
});
});
});
Edit: After more examination it seems like my issue may be related to my RedirectToAction. I have posted my controller action below
[HttpPost]
public IActionResult Study(StudyViewModel model)
{
if (ModelState.IsValid)
{
var response= _repo.AddEditStudy(model.StudyGuid,model.SelectedStudyCatalogGuid, model.ParticipantGuid, model.StartDate, model.EndDate);
if (response.Success)
{
TempData["Message"] = response.Message;
return RedirectToAction("EditParticipant", new {id = model.ParticipantGuid});
}
}
model.Studies = GetStudyCatalog();
return PartialView("_StudyModal", model);
}
I got problem.
Every time when I click on button Close I get error in console : Appointment:103 Uncaught ReferenceError: onCloseModal is not defined
at HTMLButtonElement.onclick
What I doing wrong? I tried to add Id="Closebtn" and add script like this :
<script>
$(document).ready(function(){
// Open modal on page load
$("#appointmentInput").modal('show');
// Close modal on button click
$("#Closebtn").click(function(){
$("#appointmentInput").modal('hide');
});
});
</script>
Tried to add ";" after onclick methods.
Modal code :
<div class="modal fade" role="dialog" id="appointmentInput" data-backdrop="static" data-keyboard="false">
<div class="modal-dialog">
<div class="modal-content">
<form id="appointmentForm" autocomplete="off" novalidate="novalidate">
<div class="modal-header">
<h4 class="modal-title">Add/Edit Appointment</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="title">Title</label>
<input type="text" maxlength="100" class="form-control" id="title" />
</div>
<div class="form-group">
<label for="description">Descriptions</label>
<textarea type="text" class="form-control" id="title"></textarea>
</div>
<div class="form-group">
<label for="title">Select Patient</label>
<select id="patientId" asp-items="#(new SelectList(ViewBag.PatientList, "Id","Name"))" class="form-control"></select>
</div>
<div class="form-group">
<label for="title">Duration</label>
<select id="duration" asp-items="ViewBag.Duration" class="form-control"></select>
</div>
<input type="hidden" id="id" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" onclick="onCloseModal()">Close</button>
<button type="button" id="btnSubmit" class="btn btn-success" onclick="onSubmitForm();">Submit</button>
</div>
</form>
</div>
</div>
</div>`
And JS code :
$(document).ready(function () {
InitializeCalendar();
});
function InitializeCalendar() {
try {
$('#calendar').fullCalendar({
timezone: false,
header: {
left: 'prev,next,today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
selectable: true,
editable: false,
select: function (event) {
onShowModal(event, null);
}
});
}
catch (e) {
alert(e);
}
}
function onShowModal(obj, isEventDetail) {
$("#appointmentInuput").modal("show");
}
function onCloseModal() {
$("#appointmentInuput").modal("hide");
}
Your functions for onShowModal and onCloseModal both reference an element with the ID of #appointmentInuput but your modal uses an ID of #appointmentInput
Correcting this typo allows the modal to open (and close) as expected. I would also note that Bootstrap's built-in close action for the Modal component is also fully functional:
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
The data-dismiss="modal" being the attribute that would trigger the modal closing. In Bootstrap 5.x this would be data-bs-dismiss="modal"
Here's the code of an Angular 4 component used to collect contact information from visitors:
.html:
<form (submit)="onCreateContact()">
<div class="form-group">
<input type="text" [(ngModel)]="contactname" name="contactname" class="form-control form-control-lg" placeholder="Name">
</div>
<div class="form-group">
<input type="email" [(ngModel)]="contactemail" name="contactemail" class="form-control form-control-lg" placeholder="Email">
</div>
<div class="form-group">
<input type="text" [(ngModel)]="contactphone" name="contactphone" class="form-control form-control-lg" placeholder="Phone">
</div>
<input type="submit" class="btn btn-outline-light btn-block" data-toggle="modal" data-target='#addContactModal'>
</form>
<!-- Modal -->
<div class="modal fade" id="addContactModal" tabindex="-1" role="dialog" aria-labelledby="addContactModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addContactModalLabel">Contact</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Thanks for contacting us! We will get in touch with you shortly.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
.ts:
onCreateContact() {
let contact = {
contactname: this.contactname,
contactemail: this.contactemail,
contactphone: this.contactphone
}
return this.http.post('api/contacts/add', contact).map(res => res.json()).subscribe(data => {
if(data.success) {
console.log(data);
} else {
console.log('Failed to add contact');
}
}
);
}
All contact fields are required; the data is not passed to the backend if not all fields are filled.
Currently, the Bootstrap modal popups every time I press the submit button, even when the data is not passed. How can I show it only when the data is actually passed to the server?
You are toggling the modal when the user clicks on the submit button.
What you need to do is, toggle the modal from component class(.ts) after getting the response from the backend.
So in your ".ts" file add below line under the imports section
declare var $: any;
Then toggle modal after receiving response from backend as below
onCreateContact() {
return this.http.post('api/contacts/add', contact).map(res => res.json()).subscribe(data => {
if(data.success) {
console.log(data);
$('#addContactModal').modal('show'); // Add this line
} else {
console.log('Failed to add contact');
$('#errorModalId').modal('show'); // If you are planning to show error modal when something goes wrong.
}
});
}
Don't forget to remove data-toggle and data-target attribute from submit button.
Hope this helps.
I've a Bootstrap modal for changing a user's password. The problem, however, is that no matter what I try I cannot get the event to fire, be it via onclick or by attaching the button to an event using .on. It simply will not recognise it.
I've tried putting the <script> tags above the modal, below the modal, and even inside the modal, only to always have onclick return Uncaught ReferenceError: updatePassword is not defined. I then removed the onclick, assigned an ID to the submit button, and tried $('#update-password').on('click', function() { ... }); but this wasn't recognised at all.
The culprit in all of this is almost definitely the Bootstrap modal, and I'm guessing it's got something to do with how the browser handles it upon page load.
--
Modal
<!-- Modal -->
<div class="modal fade" id="changePasswordModal" tabindex="-1" role="dialog" aria-labelledby="changePassModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="changePassModalLabel">Change Password</h4>
</div>
<div class="modal-body">
<div class="col-md-12">
<div class="alert alert-password" style="display: none;">
<p></p>
</div>
</div>
<form role="form" action="#" method="post">
<div class="form-group">
<label for="password-current">Current Password<span>*</span></label>
<input type="password" class="form-control" id="password-current" name="pass-curr" placeholder="Current password...">
</div>
<hr>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="password-new">New Password<span>*</span></label>
<input type="password" class="form-control" id="password-new" name="pass-new" placeholder="New password...">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="password-new-conf">Confirm New Password<span>*</span></label>
<input type="password" class="form-control" id="password-new-conf" name="pass-new-c" placeholder="Confirm new password...">
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary" onclick="updatePassword()">Update Password</button>
</div>
</div>
</div>
</div>
Script
<script>
function updatePassword(){
console.log('foo');
/*$.ajax({
url: url+"ajax/update_password",
data: {pass-curr : pass-curr, pass-new : pass-new, pass-new-c : pass-new-c},
async: false,
success: function(data) {
},
error: function(data) {
$('#alert-password').removeClass('alert-success').addClass('alert-danger').html('<p><strong>Sorry, an error occurred!</strong></p><p>'+data.additional+'</p>').slideDown(200, function() {
$('#alert-password').delay(4000).slideUp(200);
});
}
})*/
};
</script>
My apologies if this has been asked before. The only questions I could seem to find were those asking how to launch a modal through onclick.
The problem is that your event is not getting binded with button
Please find the JSFIDDLE here
In your HTML - do the following in the script tag
<head>
<script>
function updatePassword(){
console.log('updatePassword');
}
$(document).ready(function(){
// $('.btn-primary').on('click',function(){ - This too works
// console.log('foo');
//});
$('.btn-primary').on('click',updatePassword);
});
</script>
</head>
I have this view in mvc in which I display details for a model. The modal popup was working fine until I didn't put it in form block. Now its only posting back instead of displaying the popup.
This is the view I have:
#using App.Portal.WebUI.Controllers
#using MvcPaging
#model IPagedList<App.Models.Device>
#{
ViewBag.Title = "Manage Devices";
}
<h2>Manage Devices</h2>
#Html.ActionLink("Add New Device", "Manage", "Handhelds", new { #class = "editUser btn btn-info" })
<button id="showInactive" class="btn btn-primary">Show Inactive Devices</button>
<br /><br />
#using (Ajax.BeginForm("Home", "Handhelds",
new AjaxOptions {UpdateTargetId = "grid-list", HttpMethod = "get", LoadingElementId = "loading", OnBegin = "beginPaging", OnSuccess = "successPaging", OnFailure = "failurePaging"},
new {id = "frm-search"}))
{
<div class="input-append">
<input class="span2" id="appendedInputButton" type="text" name="handheld" placeholder="Enter Text" />
<button class="btn" type="submit">
<i class="icon-search"></i> Search</button>
</div>
<br />
<div id="grid-list">
<div class="table-responsive">
<table id="dataTable" class="table table-striped">
<tr>
<td>No</td>
<td>Device ID</td>
<td>Serial Number</td>
<td>Options</td>
</tr>
#foreach (var device in Model)
{
<tr>
<td>#device.DeviceID</td>
<td>#device.DeviceIDView</td>
<td>#device.DeviceSerialNumber</td>
<td>
#Html.ActionLink("Edit", "Manage", new {id = #device.DeviceID}, new {#class = "editUser btn btn-info"})
<button id="btnDeleteHandheld" class="deleteHandheld btn btn-danger" data-id="#device.DeviceID">Delete</button>
</td>
</tr>
}
</table>
</div>
</div>
}
<script type="text/javascript">
$(document).ready(function () {
$('button.btnAddDevice').click(function () {
$('#addNewDevice').modal('show');
});
$('button.deleteHandheld').click(function () {
$("#hfDeviceId").val($(this).data('id'));
$('#deleteConfirm').modal('show');
});
$('button.deleteDeviceConfirm').click(function () {
$.ajax({
url: '#Url.Action("Delete", "Handhelds")',
data: { deviceid: $("#hfDeviceId").val() },
dataType: "json",
type: 'POST',
success: function (data) {
if (data === "OK") {
$('#deleteConfirm').modal('hide');
$('#deleteConfirmation').modal('show');
setTimeout(function () {
location.reload();
}, 3000);
}
},
error: function (textStatus, errorThrown) {
Success = false;//doesn't goes here
}
});
});
});
</script>
<div id="deleteConfirm" class="modal fade" data-backdrop="static" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h4>Are you sure you want to remove the device?</h4>
<button class="btn btn-success deleteDeviceConfirm">Yes</button>
<button class="btn btn-danger" data-dismiss="modal">No</button>
<input type="hidden" id="hfDeviceId" />
</div>
</div>
</div>
</div>
<div id="deleteConfirmation" class="modal fade" data-backdrop="static" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h4>Device removed</h4>
<button class="btn btn-danger btn-block" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>
I need the button with id of btnDeleteHandheld to trigger the associated modal popup. What do I need to change?
I think the button make an input submit by default. To prevent the post use the preventDefault like so :
$('button.deleteHandheld').click(function (e) {
e.preventDefault();
$("#hfDeviceId").val($(this).data('id'));
$('#deleteConfirm').modal('show');
});
You can also replace you button with this :
<input type="button" "id="btnDeleteHandheld" class="deleteHandheld btn btn-danger" data-id="#device.DeviceID">Delete</input>