Trigger modal popup in mvc form with a button click - javascript

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>

Related

How to launch bootstrap modal to launch on same page to save?

When I click on the button to launch my modal, it rather duplicataes the content on the same browser page and this is the "Js error" i get in my console window. Tried many suggestions but still.Please help.
Uncaught TypeError: Cannot read properties of undefined (reading 'classList')
at Pe._isAnimated (modal.js:312:26)
at Pe._initializeBackDrop (modal.js:194:24)
at new Pe (modal.js:82:27)
at Pe.getOrCreateInstance (base-component.js:55:41)
at HTMLButtonElement.<anonymous> (modal.js:414:22)
at HTMLDocument.n (event-handler.js:120:21)
My Code:
Controller:
using BOGBitwiseApp.Data;
using BOGBitwiseApp.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System.Dynamic;
namespace BOGBitwiseApp.Controllers
{
public class CustomerRequestController : Controller
{
private readonly ApplicationDbContext _context;
public CustomerRequestController(ApplicationDbContext context)
{
_context = context;
}
//Get: Customer Requests
public IActionResult Index()
{
var customerRequest = _context.CustomerRequests.ToList();
return View(customerRequest);
}
[HttpGet]
public IActionResult Create()
{
CustomerRequestModel customer = new CustomerRequestModel();
return PartialView("AddCustomerModelPartial", customer);
}
Index.cshtml:
#model IEnumerable<BOGBitwiseApp.Models.CustomerRequestModel>
#{
ViewData["Title"] = "Index";
}
<div id="PlaceHolderHere">
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-
target="#addCustomerRequest" data-bs-url="#Url.Action("Create")">New Customer
Request</button>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>
#Html.DisplayNameFor(m => m.AccountName)
</th>
<th>
#Html.DisplayNameFor(m =>m.AccountNumber)
</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#item.AccountName
</td>
<td>
#item.AccountNumber
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.BitwiseId}) ||
#Html.ActionLink("Delete", "Delete", new { id=item.BitwiseId})
</td>
</tr>
}
</tbody>
PartialView:
I created a partialview "AddCustomerModelPartial.cshtml".
#model CustomerRequestModel
<div class="modal fade" id="addCustomerRequest">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title" id="addCustomerRequestLabel">Bitwise
Information</h2>
<button type="button" class="btn-close" aria-label="Close" data-bs-
dismiss="modal">
</button>
</div>
<div class="modal-body">
<form asp-action="Create" >
<div class="form-group">
<label asp-for="AccountName"></label>
<input asp-for="AccountName" class="form-control" />
<span asp-validation-for="AccountName" class="text-danger">
</span>
</div>
<div class="form-group">
<label asp-for="AccountNumber"></label>
<input asp-for="AccountNumber" class="form-control" />
<span asp-validation-for="AccountNumber" class="text-danger">
</span>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-bs-
dismiss="modal">Cancel Request</button>
<button type="button" class="btn btn-info" data-bs-toggle="modal">Save
Request</button>
</div>
</div>
</div>
</div>
Site.js Code:
This is my js code in the wwwroor folder.
$(function () {
var PlaceHolderElement = $('#PlaceHolderHere');
$('button[data-bs-toggle="modal"]').click(function (event) {
var url = $(this).data('url');
$.get(url).done(function (data) {
PlaceHolderElement.html(data);
PlaceHolderElement.find('.modal').modal('show');
})
})
})
It should be data-url="#Url.Action("Create")" if you want to get the value by using $(this).data('url').
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-
target="#addCustomerRequest" data-url="#Url.Action("Create")">New Customer Request</button>
Another way, if you do not want to change data-bs-url, you can change the js below to receive the url value:
var url = $(this).attr("data-bs-url");

Why isn't my form passing the id to the controller?

I've got an asp.net mvc webpage set up. All of my actions, like: create, edit, etc... have their own views, except delete, because I'm trying to pop up a modal with help from Bootstrap. I pass an id to the modal, through jQuery/JavaScript, and with the asp-action as the form's attribute, it should theoretically work, but well it doesn't.
Index View:
#if (Model.Tenants.Any())
{
<h3>Tenants (#Model.Tenants.Count)</h3>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Id</th>
<th>UrlFriendlyName</th>
<th>MicrosoftGraphTenantId</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var tenant in Model.Tenants.OrderByDescending(x => x.Name))
{
<tr>
<td>
<button class="btn btn-primary" onclick="document.location.href = '#Url.Action("Index", "User", new {id = tenant.Id})'">Show Users</button>
</td>
<td>
#tenant.Name
</td>
<td>
#tenant.Id
</td>
<td>
#tenant.UrlFriendlyName
</td>
<td>
#tenant.MicrosoftGraphTenantId
</td>
<td>
<div class="btn-group-justified pull-right ">
<button class="btn btn-success" onclick="document.location.href = '#Url.Action("Edit", "Tenant", new {id = tenant.Id})'">Edit</button>
<button type="button" class="btn btn-danger" onclick="deleteTenant('#tenant.Id', '#tenant.Name')" data-toggle="modal" data-target="#deleteModal">Delete</button>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
<div class="align-items-sm-end">
<button onclick="document.location.href='#Url.Action("Create", "Tenant")'" class="btn btn-outline-success">Create new Tenant</button>
</div>
<div class="modal fade" id="deleteModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete the selected Tenant?</p>
</div>
<div class="modal-footer">
<form asp-action="Delete">
<input type="hidden" id="tenantidinput"/>
<button type="submit" class="btn btn-outline-danger">Delete Tenant</button>
</form>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
}
Delete Action in Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteAsync(Guid id)
{
if (ModelState.IsValid && id != Guid.Empty)
{
var tenant = await _context.Tenants.AsQueryable().Where(x => x.Id == id).FirstOrDefaultAsync().ConfigureAwait(false);
_context.Tenants.Remove(tenant);
await _context.SaveChangesAsync().ConfigureAwait(false);
}
return RedirectToAction("Index");
}
Javascript:
function deleteTenant(tenantid, tenantname) {
$(".modal-title").text("Delete " + tenantname);
$("#tenantidinput").attr("name", ''+tenantid+'');
}
Input getting the id as the value of the name:
When debugging, it receives no id whatsoever:
The javascript-function receives the parameters just fine. I think that the problem lies in, the way, the form passes the id to the controller. It somehow doesn't pass the value of the name-attribute.
This is happening for two reasons. Firstly, the hidden input should have the name matching the argument in the action. In your case id:
<input type="hidden" name="id" id="tenantidinput" />
Secondly, your JS should set the value of the field, not its name:
function deleteTenant(tenantid, tenantname) {
$(".modal-title").text("Delete " + tenantname);
$("#tenantidinput").val(tenantid);
}

What's the correct way to submit a single element in a list when each of them has a separate submit button

I have an event page which contains a list of participants. From there users can be invited to that event by opening a modal view containing a user list. Users are shown in the same modal with each having an 'Invite'(submit) button next to them. How can I let the controller action know which user is invited?
From what I could find, creating a form for each list element is bad and in addition displays warnings, but if I create a form element on top of the 'foreach', I then need to somehow find which user to submit.
Also thought about appending incrementing numbers to each of submit button name, but I still need to somehow map them to 'their' users.
Along with the invited user id, controller post action also needs to receive the event id.
Here's the code:
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Select user</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<form id="eventMemberForm" method="post" class="col-sm-6 custom-close" data-ajax="true" data-ajax-method="post" data-ajax-complete="completed" data-ajax-url="#Url.Action("SendInvitation", "Sports")">
<input type="hidden" asp-for="Invitation.FkEvent" value="#Model.Event.EventId" />
<input type="hidden" asp-for="Invitation.EventInvitationId" />
<div class="modal-body">
<input class="form-control p-2 mb-2" id="myInput" type="text" placeholder="Search..">
<h4 class="align-content-center">Users</h4>
<div class="form-group">
<table class="w-100">
<tbody id="myField">
#foreach (var item in Model.Users)
{
<tr>
<td class="d-flex">
<div> #Html.DisplayFor(modelItem => item.Text) </div>
<input type="hidden" asp-for="Invitation.FkUser" value="#item.Value" />
<div class="ml-auto">
<input id="btnSave" type="submit" value="Invite" class="btn btn-success" />
</div>
</td>
</tr>
++i;
}
</tbody>
</table>
</div>
</div>
</form>
</div>
</div>
</div>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
$(document).ready(function () {
$("#myInput").on("keyup", function () {
var value = $(this).val().toLowerCase();
$("#myField tr").filter(function () {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
completed = () => {
alert("User invited");
};
</script>
You can use jquery ajax to pass the parameters you need, through the click event, get the corresponding value of the control needed next to the current button.
By adding the name attribute to the submit button, and then triggered in jquery.
And add the id to the div that stores the Text value of User to facilitate finding the corresponding value in jquery.
#section Scripts{
<script>
$(document).ready(function () {
$("#myInput").on("keyup", function () {
var value = $(this).val().toLowerCase();
$("#myField tr").filter(function () {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
$("[name=submitBtn]").click(function () {
event.preventDefault();
var obj = {
myUser: {
Text: $($(this).parent().siblings()[0]).text(),
Value: $($(this).parent().siblings()[1]).val()
},
eventId: $("#Invitation_FkEvent").val()
};
$.ajax({
url: $("#eventMemberForm").attr("data-ajax-url"),
method: 'post',
data: obj,
})
});
});
completed = () => {
alert("User invited");
};
</script>
}
<h1>Index</h1>
<button data-toggle="modal" data-target="#myModal" class="btn btn-primary">Submit</button>
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Select user</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<form id="eventMemberForm" method="post" class="col-sm-6 custom-close" data-ajax="true" data-ajax-method="post" data-ajax-complete="completed" data-ajax-url="#Url.Action("SendInvitation", "Sports")">
<input type="hidden" asp-for="Invitation.FkEvent" value="#Model.Event.EventId" />
<input type="hidden" asp-for="Invitation.EventInvitationId" />
<div class="modal-body">
<input class="form-control p-2 mb-2" id="myInput" type="text" placeholder="Search..">
<h4 class="align-content-center">Users</h4>
<div class="form-group">
<table class="w-100">
<tbody id="myField">
#foreach (var item in Model.Users)
{
<tr>
<td class="d-flex">
<div id="textValue"> #Html.DisplayFor(modelItem => item.Text) </div>
<input type="hidden" asp-for="Invitation.FkUser" value="#item.Value" />
<div class="ml-auto">
<input id="btnSave" type="submit" value="Invite" class="btn btn-success" name="submitBtn"/>
</div>
</td>
</tr>
++i;
}
</tbody>
</table>
</div>
</div>
</form>
</div>
</div>
</div>
Controller:
public IActionResult SendInvitation(User myUser, string eventId)
{
//do what you want
return View();
}

Javascript function undefined, but IT IS

I'm doing some testing with AJAX form submissions and I keep getting ReferenceError: submit_ajax is not defined from the code below. However, you can see that it IS defined.
<script type="javascript">
function submit_ajax(){
data = {'email':$('#email2').val(),'password':$('#pwd2').val()}
$.ajax({
url: 'ajax_testing.php',
data: data,
success: function() {
//AJAX success
$('#success_fail').html('success!');
window.setTimeout(function() { $('#success_fail').hide(); }, 3000);
$('#myModal2').hide();
},
error: function() {
//Ajax failure
$('#success_fail').html('failed!');
window.setTimeout(function() { $('#success_fail').hide(); }, 3000);
$('#myModal2').hide();
}
});
}
</script>
<div>
<div id="success_fail"></div>
<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-info btn-lg" id="button_for_modal2" data-toggle="modal" data-target="#myModal2">Form Submitted via AJAX and No Parent Refresh</button>
<!-- Modal -->
<div class="modal fade" id="myModal2" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Title of Form</h4>
</div>
<div class="modal-body">
<h2>Vertical (basic) form</h2>
<!--<form action="<?PHP echo $_SERVER['PHP_SELF']; ?>" method="post">*******************************AJAX*********************************-->
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email2" placeholder="Enter email (ajax)" name="email2">
</div>
<div class="form-group">
<label for="pwd">Password:</label>
<input type="password" class="form-control" id="pwd2" placeholder="Enter password (ajax)" name="pwd2">
</div>
<button onclick="submit_ajax()" class="btn btn-default">Submit</button>
<!--</form>-->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
I've tried running the function directly in the console and I get the same thing.
Any idea about what's going wrong here?
Instead of using <script type="javascript"> use <script type="text/javascript"> which is valid type for JS code.
change your script tag, either dont include type or set it as type="text/javascript"
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
function submit_ajax(){
alert('submit_ajax working')
data = {'email':$('#email2').val(),'password':$('#pwd2').val()}
$.ajax({
url: 'ajax_testing.php',
data: data,
success: function() {
//AJAX success
$('#success_fail').html('success!');
window.setTimeout(function() { $('#success_fail').hide(); }, 3000);
$('#myModal2').hide();
},
error: function() {
//Ajax failure
$('#success_fail').html('failed!');
window.setTimeout(function() { $('#success_fail').hide(); }, 3000);
$('#myModal2').hide();
}
});
}
</script>
<button onclick="submit_ajax()" class="btn btn-default">Submit</button>

Submit Dynamically Created Form using Button Outside The Form

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

Categories

Resources