Adding Dynamic buttons to display pop-up window to link entries - javascript

I am creating a list of entries each with a Link button in a foreach loop on my Razor Page. The Link button is clicked to open a modal with another list of entries and all of these entries have a checkbox. This view allows me to Link an entry to multiple other entries. Code below for HTML:
#foreach (var entry in Model.EntryList.Where(w => w.IsLinked == false))
{
<tr>
<td class="pt-3-half" contenteditable="true">#entry.Description</td>
<td class="pt-3-half" contenteditable="true">
<button id="btnShowModal" type="button" class="btn btn-sm btn-default pull-left col-lg-11 button button4">
Link
</button>
<div class="modal fade" tabindex="-1" id="loginModal"
data-keyboard="false" data-backdrop="static">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Link Entries</h4>
<button type="button" class="close" data-dismiss="modal">
×
</button>
</div>
<form enctype="multipart/form-data" asp-controller="Home" asp-action="Index" asp-route-id="#entry.Description" method="post" class="mt-3">
<div class="modal-body">
<table style="text-align: center; width: 100%">
<thead>
<tr>
<th class="text-center">Description</th>
<th class="text-center"></th>
</tr>
</thead>
<tbody>
#foreach (var LinkEntry in Model.EntryList.Where(w => w.IsLinked == true))
{
<tr>
<td class="pt-3-half" contenteditable="true">#LinkEntry.Description</td>
<td class="pt-1-half" contenteditable="true">
<input name="AreChecked" type="checkbox" value="#LinkEntry.Id" />
</td>
</tr>
}
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary button button4">Link Entries</button>
<button type="button" id="btnHideModal" class="btn btn-primary button button4">
Hide
</button>
</div>
</form>
</div>
</div>
</div>
</tbody>
</table>
</div>
</td>
</td>
</tr>
}
When the Link button is clicked the below jQuery runs:
<script type="text/javascript">
$(document).ready(function () {
$("#btnShowModal").click(function () {
$("#loginModal").modal('show');
});
$("#btnHideModal").click(function () {
$("#loginModal").modal('hide');
});
});
</script>
The current problem I have is that only the first Link button shows the Modal div. The rest of the Link buttons do not do anything when clicked. So I then moved the entire Modal Div outside of the foreach but does not fix the problem and this then also doesn't allow me to parse the asp-route-Id due to now being outside the foreach.

The issue here is that you are using hard-coded ids for your buttons, but they are created in a loop so more than one element with the same id is created, which you definitely do not want.
Remove the ids and replace them with a unique class, like btn-show-modal, then change your jquery selector from $("#btnShowModal") to $(".btn-show-modal").
Do the same thing with your hide buttons, but use a different unique class name like btn-hide-modal. Be sure to do this with all hard-coded ids (looks like there is at least one more instance).
One other point I should make is you will need to query the modal relative to the button that is clicked. Inside the click events, you should do $(this).next().modal('show') / $(this).next().modal('hide') , since as stated, you need to remove the id="loginModal" and will need an alternative method to get the correct modal to show.
I believe jquery is smart enough to not search the entire DOM when using the id selector (#), so that is why only your first button is firing your click event.
My suggestion to future proof these kinds of errors is to create a <script> that will search the DOM for duplicate ids and show an alert(), or something, to let you know that your DOM is invalid. I'd also make sure that this script is only added when debugging, as with this <script> you will catch the errors during development and do not want to the extra overhead in production.

Yes as William says, you have that error because you are using an id and that button is being created so many times as items you have in your collection. And if I was you I'll put the modal outside the first loop because otherwise you can create a lot of modal too. I leave you an example of something that I hope can help you.
This is the model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace HelloWorldMvcApp
{
public class SampleViewModel
{
[Required]
[MinLength(10)]
[MaxLength(100)]
[Display(Name = "Ask Magic 8 Ball any question:")]
public string Question { get; set; }
//See here for list of answers
public string Answer { get; set; }
public List<Test> EntryList { get; set; }
}
public class Test {
public int Id { get; set; }
public string Description { get; set; }
public bool IsLinked { get; set; }
}
}
Here you are the controller:
using System;
using System.Web.Mvc;
using System.Collections.Generic;
namespace HelloWorldMvcApp
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
var list = new SampleViewModel();
list.EntryList = new List<Test>();
var test1 = new Test();
test1.Id = 1;
test1.Description = "test1";
test1.IsLinked = false;
list.EntryList.Add(test1);
var test2 = new Test();
test2.Id = 2;
test2.Description = "test2";
test2.IsLinked = false;
list.EntryList.Add(test2);
var test3 = new Test();
test3.Id = 3;
test3.Description = "test3";
test3.IsLinked = false;
list.EntryList.Add(test3);
var test11 = new Test();
test11.Id = 11;
test11.Description = "test11";
test11.IsLinked = true;
list.EntryList.Add(test11);
var test12 = new Test();
test12.Id = 12;
test12.Description = "test12";
test12.IsLinked = true;
list.EntryList.Add(test12);
var test21 = new Test();
test21.Id = 21;
test21.Description = "test21";
test21.IsLinked = true;
list.EntryList.Add(test21);
var test22 = new Test();
test22.Id = 22;
test22.Description = "test22";
test22.IsLinked = true;
list.EntryList.Add(test22);
return View(list);
}
}
}
And this is the view.
#model HelloWorldMvcApp.SampleViewModel
#{
Layout = null;
}
<!DOCTYPE html>
<!-- template from http://getbootstrap.com/getting-started -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap 101 Template</title>
<!-- CSS Includes -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<style type="text/css">
.field-validation-error {
color: #ff0000;
}
</style>
</head>
<body>
<div class="container">
<div class="col-md-6 col-md-offset-3">
<table>
<tbody>
#foreach (var entry in Model.EntryList.Where(w => w.IsLinked == false))
{
<tr>
<td class="pt-3-half" contenteditable="true">#entry.Description</td>
<td class="pt-3-half" contenteditable="true">
<button type="button" onClick="showModal('#entry.Description')" class="btn btn-sm btn-default pull-left col-lg-11 button button4">
Link
</button>
</td>
</tr>
}
</tbody>
</table>
<div class="alert alert-warning fade">
<img src="http://entechprod.blob.core.windows.net/dotnetfiddle/morpheus.jpg"
style="max-width:100%;" /><br /><br />
<strong><span class="alert-content"></span></strong>
</div>
</div>
</div>
<div class="modal fade" tabindex="-1" id="loginModal" data-keyboard="false" data-backdrop="static">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Link Entries</h4>
<button type="button" class="close" data-dismiss="modal">
×
</button>
</div>
<form enctype="multipart/form-data" id="modalForm" asp-controller="Home" asp-action="Index"
asp-route-id="" method="post" class="mt-3">
<div class="modal-body">
<table style="text-align: center; width: 100%">
<thead>
<tr>
<th class="text-center">Description</th>
<th class="text-center"></th>
</tr>
</thead>
<tbody>
#foreach (var LinkEntry in Model.EntryList.Where(w => w.IsLinked == true))
{
<tr>
<td class="pt-3-half" contenteditable="true">#LinkEntry.Description</td>
<td class="pt-1-half" contenteditable="true">
<input name="AreChecked" type="checkbox" value="#LinkEntry.Id" />
</td>
</tr>
}
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary button button4">Link Entries</button>
<button type="button" onClick="hideModal()" class="btn btn-primary button button4">
Hide
</button>
</div>
</form>
</div>
</div>
</div>
<!-- JS includes -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
<script src="//ajax.aspnetcdn.com/ajax/mvc/4.0/jquery.validate.unobtrusive.min.js"></script>
<script type="text/javascript">
function showModal(desc) {
$('#modalForm').attr('asp-route-id', desc);
$("#loginModal").modal('show');
}
function hideModal(desc) {
$("#loginModal").modal('hide');
}
</script>
</body>
</html>

Creating a modal for each entry in the loop seems unnecessary to me,
Create a single modal outside your loop and update all its data according with the Link button you clicked
Use data- attributes to pass the info you require to the click event and to build/update your modal, you can JSON your info and use a javascript function to create the table and checkboxes bit
#foreach (var entry in Model.EntryList.Where(w => w.IsLinked == false))
{
<tr>
<td class="pt-3-half" contenteditable="true">#entry.Description</td>
<td class="pt-3-half" contenteditable="true">
<button data-entry-id="#entry.Id" data-entries="<?= htmlentities(json_encode(Model.EntryList.Where(w => w.IsLinked == true)))?>" id="btnShowModal" type="button" class="btn btn-sm btn-default pull-left col-lg-11 button button4 ">
Link
</button> ...
then you add a listener with JS to all those Link buttons
function onClickLinkButtonUpdateModal($e){
let entries = JSON.parse($e.target.dataset.entries);
let entry_id = $e.target.dataset.entryId;
//pass the info you need, you can create the tr elements or the whole tbody with document.create or with template literals
let tr_entries = generateHTMLEntries(entry_id, entries);
//assuming you put an id to the table or the table body
document.querySelector('#modal-table').appendChild(tr_entries);
//or
//document.querySelector('#modal-tbody').innerHTML = tr_entries;
}

Related

Asp Validations inside a modal

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);
})
})

Passing "Id" selected checkbox to Modal bootstrap and send to controller

I have a list of Articles and I want to have a possibility to delete selected articles or all articles in a modal popup window. Also, I have checkboxes in my View. My idea - get an "Id" of each selected article, passing these articles to modal bootstrap popup. After, using form-action Post will send these "Id" to action controller method for further actions. (public ActionResult DeleteArticle (FormCollection fc){}).
I want to understand how I can pass "Id" of selected with checkboxes Articles to modal Bootstrap popup. Thanks!
My ListOfArticls.cshtml:
<table class="table table-striped table-hover">
<thead>
<tr>
<th>
<span class="custom-checkbox">
<input type="checkbox" id="checkBoxAll">
<label for="selectAll"></label>
</span>
</th>
<th>#Html.DisplayNameFor(model => model.Title)</th>
<th>#Html.DisplayNameFor(model => model.PublishDate)</th>
<th>#Html.DisplayNameFor(model => model.Tag)</th>
<th>#Html.DisplayNameFor(model => model.Note)</th>
<th>#Html.DisplayName("Category name")</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
<span class="custom-checkbox">
<input type="checkbox" class="chkCheckBoxId" value="#item.Id">
<label for="chkCheckBoxId"></label>
</span>
</td>
<td>
#Html.ActionLink(Html.DisplayFor(modelItem => item.Title).ToHtmlString(), "ArticleDetails", new { id = item.Id })
</td>
<td>
#Html.DisplayFor(modelItem => item.PublishDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Tag)
</td>
<td>
#Html.DisplayFor(modelItem => item.Note)
</td>
<td>
#Html.DisplayFor(modelItem => item.Category.Name)
</td>
<td>
<i class="material-icons" data-toggle="tooltip" title="Edit"></i>
<i class="material-icons" data-toggle="tooltip" title="Delete"></i>
</td>
</tr>
}
</tbody>
</table>
<script type="text/javascript">
$(document).ready(function () {
$('#checkBoxAll').click(function () {
if ($(this).is(":checked")) {
$(".chkCheckBoxId").prop("checked", true)
}
else {
$(".chkCheckBoxId").prop("checked", false)
}
});
});
</script>
Popup:
<!-- Delete Modal HTML -->
<div id="deleteArticleModal" class="modal fade">
<div class="modal-dialog">
<input type="hidden" id="linkId" />
<div class="modal-content">
<form action="#Url.Action("DeleteArticle", "Post")" method="post">
<div class="modal-header">
<h4 class="modal-title">Delete Employee</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<p>Are you sure you want to delete these Records?</p>
<p class="text-warning"><small>This action cannot be undone.</small></p>
</div>
<div class="modal-footer">
<input type="button" class="btn btn-default" data-dismiss="modal" value="Cancel" onclick="deleteConfirm()">
<input type="submit" class="btn btn-danger" value="Delete">
</div>
</form>
</div>
</div>
</div>
Controller:
[HttpPost]
public ActionResult DeleteArticle(FormCollection fc)
{
// Some code
return RedirectToAction("ListOfArticles");
}
UPDATE:
Little bit corrected:
js
// loop through all the check boxes
$("input[type=checkbox]:checked").each(function () {
and my controller:
[HttpPost]
public ActionResult DeleteArticle(FormCollection fc)
{
var values = fc["articlesArray"];
string[] str = values.Split(',');
for(int i=0; i < str.Length; i++)
{
postService.DeleteArticleDTO(Int32.Parse(str[i]));
}
return RedirectToAction("ListOfArticles");
}
If I understand this correctly, you want to multi-select through check boxes and clicking "Delete" on any of the row's delete buttons will open the popup with the ID's of the selected articles.
You got this part correct; the checkbox input field with ID as its value.
<input type="checkbox" class="chkCheckBoxId checkbox" value="#item.Id">
Next what we want to do is loop through all the check boxes whenever the delete button is clicked.
During the loop, we will identify which ones are checked and add them to the form tag of your modal.
Add the new script below to your code, read the comments as well.
<script type="text/javascript">
$(document).ready(function () {
$('#checkBoxAll').click(function () {
if ($(this).is(":checked")) {
$(".chkCheckBoxId").prop("checked", true)
}else{
$(".chkCheckBoxId").prop("checked", false)
}
});
// bind this event to all delete buttons
$(".delete").click(function(){
// find the modal body
var modal = $("#deleteArticleModal").find(".modal-body");
// loop through all the check boxes (class checkbox)
$(".checkbox").each(function(index){
// if they are checked, add them to the modal
var articleId = $(this).val();
if($(this).is(":checked")){
// add a hidden input element to modal with article ID as value
$(modal).append("<input name='articlesArray' value='"+articleId+"' type='hidden' />")
}
});
});
});
</script>
In your form collection, the values will be passed with the property name articlesArray. It will be an array so be sure to loop through it with foreach.

Razor: button click not fired correctly

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

How do i pass the ID of row to Modal?

I have Edit button on each row. If I press Edit button on selected row I need pass ID of this row to Modal and use it in sql query to call rest of data. P.S. I tried many ways, no one of them helped and based on bootstrap.
Here is my code with Modal
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<div class="table-responsive">
<table class="table" id="myTable">
<thead>
<tr class="header">
<th>#</th>
<th>Müştərinin Nömrəsi</th>
<th>Götürülən Ünvan</th>
<th>Gədilən Ünvan</th>
<th>Zəng Vaxtı</th>
<th>Sürücünün Tabel Kod</th>
<th>Təhfil aldı</th>
<th>Təhfil verdi</th>
<th>Maşın Nömrəsi</th>
<th>Qiymət</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
while($data=mysql_fetch_array($result)) // цикл вывода
{
$id = $data['id'];
echo "<tr>
<td></td>
<td>".$data['MUSHTERINOMRE']."</td>
<td>".$data['MUSHTERIHARDAN']."</td>
<td>".$data['MUSHTERIHARA']."</td>
<td>".$data['ZENGVAXTI']."</td>
<td>".$data['TABELKOD']."</td>
<td>".$data['TEHFILALDI']."</td>
<td>".$data['TEHFILVERDI']."</td>
<td>".$data['MASHINNOMRE']."</td>
<td>".$data['QIYMET']."</td>
<td><button class=\"btn btn-success\" onclick='getValue(".$id.");' data-toggle=\"modal\" data-target=\"#myModal\" contenteditable=\false\" value=".$id.">EDIT </button></td>
"; ?>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
</div>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content"></div>
</div>
<div class="modal-dialog">
<div class="modal-content"></div>
</div>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"> <span aria-hidden="true" class="">? </span><span class="sr-only">Close</span>
</button>
<!--Here I am trying to echo ID
<h4 class="modal-title" id="myModalLabel"><?php //echo $id."ID OFaa"; ?></h4>-->
</div>
<div class="modal-body">
<?php echo $id."I NEED TO GET ID HERE "; ?>
<?php
$link = mysql_connect('localhost', 'user', 'psw');
$db_selected = mysql_select_db('my_db', $link);
$query = mysql_query("Select * from my_table where id = $id");
//var_dump($pt);
$row = mysql_fetch_array($query);
$number = $row['num'];
?>
<div class="form-group">
<label for="name" class="control-label">Müştəri Nömrə:</label>
<input type="text" class="form-control" id="num" name="num" value="<?php echo $number; ?>" />
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
The most important thing to remember is that PHP won't execute client-side, so populating the dialog with id and editable values must be performed by the client-side language - javascript. Your only option for further server-side involvement during the editing process is to make AJAX call(s).
You will find the process a lot simpler with a "promisified" modal dialog. Rather than write something yourself, you can install install, bootStrapModal, giving you a modal that is much like the standard Bootstrap modal but behaves as an asynchronous resource.
HTML:
<script src="js/bsBetterModal.js"></script>
Build the table rows as follows :
while($data=mysql_fetch_array($result)) { // цикл вывода
$id = $data['id'];
echo "<tr data-id=\".$id.\">
<td></td>
<td class=\"mushterinomre\">".$data['MUSHTERINOMRE']."</td>
<td class=\"mushterihardan\">".$data['MUSHTERIHARDAN']."</td>
<td class=\"mushterihara\">".$data['MUSHTERIHARA']."</td>
<td class=\"zengvaxti\">".$data['ZENGVAXTI']."</td>
<td class=\"tabelkod\">".$data['TABELKOD']."</td>
<td class=\"tehfilaldi\">".$data['TEHFILALDI']."</td>
<td class=\"tehfilverdi\">".$data['TEHFILVERDI']."</td>
<td class=\"mashinnomre\">".$data['MASHINNOMRE']."</td>
<td class=\"qiymet\">".$data['QIYMET']."</td>
<td><button class=\"btn btn-success edit\">EDIT</button></td>
</tr>";
} ?>
...
Write the dialog's header as follows :
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"> <span aria-hidden="true" class="">? </span><span class="sr-only">Close</span></button>
<h4 class="modal-title dlg-element" data-element="id"></h4>
</div>
Write each of the dialog's inputs (x8) as follows :
<label class="control-label">Müştəri Nömrə:</label>
<input type="text" class="dlg-element" data-element="mushterinomre" value="" />
Write the dialog footer as follows :
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary ok">Save changes</button>
</div>
The EDIT buttons' click handler is a little complicated. It comprises some preamble followed by a promise chain. I've made it as simple as I can by unloading the fiddly bits into a bunch of helper utilities.
jQuery(function($) {
// *** start: click handler ***
$('#myTable').on('click', '.edit', function(e) {
e.preventDefault(); // in case button attempts form submission
var $button = $(this).prop('disabled', true);
var $row = $(this).closest('tr');
var idHash = { 'id': $row.data('id') }; // <<<<<< HERE'S THE ID - expressed as a js plain object.
// From here on, everything is asynchronous, therefore performed within a promise chain.
fetchValues(idHash) // Fetch current values (onscreen values may be stale)
.then(function(valuesHash) {
return betterModal.run($('#myModal'), $.extend(valuesHash, idHash))// Open modal window, populated with current field values.
.then(function($dialog) {
// The dialog was accepted.
// `$dialog` holds a jQuery object of the dialog.
return saveValues($.extend(dialogToHash($dialog), idHash)); // Pass hash of editable field values, plus idHash, to saveValues()
})
.then(function() {
// New values were successfully saved.
// valuesHash is still in scope
updateHtmlTableRow($row, valuesHash); // Update the HTML table row with the edited values.
}, function(err) {
// Save failed
// Provide warning to user ...
return err;
})
})
.then(null, function(err) {
console.log(err);
$button.prop('disabled', false);
})
.always(function() {
$button.prop('disabled', false);
});
});
// *** end: click handler ***
var fields = ['mushterinomre', 'mushterihardan', 'mushterihara', 'tabelkod', 'tehfilaldi', 'tehfilverdi', 'mashinnomre', 'qiymet']; // 'zengvaxti' omitted
// *** start: helper utility functions ***
function fetchValues(idHash) {
return $.getJSON({
'url': 'api.php', // replace with actual url
'method': 'get',
'data': idHash
});
}
function saveValues(values) {
return $.ajax({
'url': 'api.php', // replace with actual url
'method': 'put',
'data': values
});
}
function dialogToHash($dialog) {
var hash = {};
fields.forEach(function(f) {
hash[f] = $('.'+f, $dialog).val();
});
return hash;
}
function updateHtmlTableRow($row, valuesHash) {
fields.forEach(function(f) {
$('.'+f, $row).text(valuesHash[f]),
});
}
// *** end: utility functions ***
});
Untested and sketchy in places so will need debugging. Some server-side stuff also needs to be addressed.
Hope this gives you some direction
function getValue(id)
{
$.ajax({
url:'filename.php',
method:'get',
data:'id='+id,
success: function(ret)
{
// add the returned value into the modal body
$('#modalBody').html(ret);
// show the modal
$('#myModal').show();
}
});
}

Update database from bootstrap modal using AJAX

I am creating a page which displays some records from the database (please refer to the screen shots). Each row has an edit button which opens up a bootstrap modal for inputing comments and changing the user's status. On clicking the done button, I have to update the changes in the database preferably using AJAX. However it's not properly working. I can't seem to understand what's going wrong.
This is my jsp page...
<%#page import="java.sql.ResultSet"%>
<%#page import="java.sql.Statement"%>
<%#page import="java.sql.Connection"%>
<%#page import="java.util.ArrayList"%>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet"
href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script
src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<%
String loginIdEdit = "";
%>
**<script>
$(function() {
//twitter bootstrap script
$("button#save").click(function(e) {
$.ajax({
type : "POST",
url : "defaulterUpdater.jsp",
data : $('form.contact').serialize(),
success : function(msg) {
},
error : function() {
alert("Failed");
}
});
});
});
</script>**
<script type="text/javascript">
function myFun() {
alert("welcome");
var demo = document.createElement('div');
demo.innerHTML = demo.innerHTML
+ "<tr><input type='text' name='mytext'><tr>";
}
</script>
</head>
<body>
<div class="container">
<form method="post" action="RegistrationServlet">
<%
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Cache-Control", "no-store");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
Connection con = null;
con = DBManager.getConnection();
Statement st = con.createStatement();
String userName = "";
ArrayList<AutoDefaulterVO> defaulterList = null;
HttpSession session2 = request.getSession();
if (session2.getAttribute("first_name") == null) {
out.println("Your session expired.....");
%>
Please Login Again to continue
<%
} else {
defaulterList = (ArrayList<AutoDefaulterVO>) session2
.getAttribute("autoDefaulterList");
userName = session2.getAttribute("first_name").toString();
%>
<form action='LogoutServlet' method=POST>
<table align="right" style="width: 100%">
<tr>
<td align="left"><input type="submit" name="logout"
value="Home" onclick="form.action='AdminHome';">
</td>
<td align="right"><input type="submit" name="logout"
value="Logout" onclick="form.action='LogoutServlet'">
</td>
</tr>
</table>
</form>
<h3 align="center">Auto Defaults</h3>
<table border="1" style="width: 100%">
<br>
<br>
<h3 align="center">
Welcome
<%=userName%></h3>
<table border="1" style="width: 100%" class="table table-hover">
<tr>
<th>Default Status</th>
<th>Borrower Name</th>
<th>Borrower Rating</th>
<th>Accural Status</th>
<th>Bank Number</th>
<th>Account Number</th>
<th>Days Past Due</th>
<th>Comments</th>
</tr>
<%
for (int i = 0; i < defaulterList.size(); i++) {
AutoDefaulterVO defaulter = new AutoDefaulterVO();
defaulter = defaulterList.get(i);
loginIdEdit = defaulter.getDefaulterLoginID();
System.out.println("Printing only auto defaulter in jsp ");
%>
<tr>
<%-- <td><%=defaulter.getDefaultStatus()%></td> --%>
<td>Auto Defaulter</td>
<td><%=defaulter.getBorrowerName()%></td>
<td><%=defaulter.getBorrowerRating()%></td>
<td><%=defaulter.getAccuralStatus()%></td>
<td><%=defaulter.getBankNumber()%></td>
<td><%=defaulter.getAccountNumber()%></td>
<td><%=defaulter.getDaysPastDue()%></td>
<%-- <td><%=loginIdEdit%></td> --%>
<td>
<%
ResultSet rs = st
.executeQuery("select * from aip_comments");
while (rs.next()) {
System.out.println("Auto defaulter loginId printing-->"
+ defaulter.getDefaulterLoginID());
String loginId = rs.getString("login_id");
System.out.println("databse loginId printing-->"
+ rs.getString("login_id"));
if (defaulter.getDefaulterLoginID().equals(
rs.getString("login_id"))) {
%> <%=rs.getString("comments")%> <%
}
}
%>
</td>
<td>
<!-- <form name="editForm" action="edit.jsp">
<button type="button" data-toggle="modal" class="btn btn-default" data-target="#myModal">Edit</button>
-->
<form class="contact">
<button href="#edit-modal" type="button" data-toggle="modal"
class="btn btn-default" data-target="#<%=loginIdEdit %>">Edit</button>
<!-- <a data-toggle="modal" data-target="#<%=loginIdEdit%>" href="#">Edit</a> -->
<!-- <input type="submit" name="editButton" value="Edit"> -->
<!--<input type="hidden" id="edit" name="edit" value="<%=loginIdEdit%>" />-->
</td>
<div class="modal fade" id="<%=loginIdEdit%>" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">
Edit status and add comment for
<%=defaulter.getBorrowerName()%></h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="sel1"><span></span>Select status:</label> <select
class="form-control" id="sel1" name="sel1">
<option>Validate Error</option>
<option>Auto Weaver</option>
<option>ReDefault</option>
</select>
</div>
<div class="form-group">
<label for="defaultercomment"><span></span>Add
comment:</label> <input type="text" class="form-control"
name="defaultercomment" id="defaultercomment"<%-- value="<%=loginIdEdit%>" --%>>
</div>
</div>
<div class="modal-footer">
<button type="button" id="save" name="save"
class="btn btn-default" data-dismiss="modal" align="centre">Done</button>
</div>
</div>
</div>
</div>
</form>
<%
}
%>
</tr>
</table>
<%
}
%>
</body>
</html>
ajax URL redirects to below jsp page,defaulterUpdater.jsp where I only print the values to see if they're correctly retrieved.
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<% String selection = request.getParameter("sel1");
String comment = request.getParameter("defaultercomment");
System.out.println("selection-"+selection+"comment--"+comment);
%>
</body>
</html>
The values are accepted only for the first row..For rest of the rows null values are being printed. Any help will be appreciated. Thanks!
I got the code working. Basically needed an unique identifier for "done" button as is rule of javascript. Hence it was not working for all rows.
I gave unique id's to the form
and by submitting called the onclick method..
onClick="callAjax(this.form)"
So now it's working. Thank you all for your help!
You are putting the modal wrong inside the table. By table syntax it is wrong. You must put this modal out from the table and call ajax inside the shown.bs.modal event of bootstrap.
As you need to repeat buttons. Keep a hardwired id of the button which will open the modal, also keep an data-attribute-id to uniquely identify the button clicked which will help you to get details about which button clicked in the list(as buttons are repeating for each row, your data-attribute-id will be loginid of the row).
Then write jquery with event shown.bs.modal, like
$("#modalId").on("shown.bs.modal", function(e){
var btnClicked= $(e).relatedTarget();
var btnClickedId= btnClicked.data("attribute-id"); // id of clicked button
// here more code see attached link below for more
}
I have posted a similer answer previously in asp.net mvc but you will have idea as situation is similer to you.
Please visit my answer on question dynamically created bootstrap3 modals do not work
Hope it will help to get idea to resolve this.
#Update Section Removed your some code for clean view
<script type="text/javascript">
$(document).ready(function () {
$('#editModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget);//Button which is clicked
var clickedButtonId= button.data('loginidedit');//Get loginidedit of the button or get other variable same
$("#loginid").val(clickedButtonId);//Put here id of the btn clicked which has attribute for loginidedit
//you can get here other required filed or make ajax call to get other values formt he database for this loginidedit.
})
});
</script>
<body>
<div class="container">
//Table here
<table border="1" style="width: 100%" class="table table-hover">
<%
for (int i = 0; i < defaulterList.size(); i++) {
AutoDefaulterVO defaulter = new AutoDefaulterVO();
defaulter = defaulterList.get(i);
loginIdEdit = defaulter.getDefaulterLoginID();
System.out.println("Printing only auto defaulter in jsp ");
%>
<tr>
<td>
<button href="#edit-modal" type="button" data-toggle="modal"
class="btn btn-default" data-target="#editModal" data-loginidedit = "<%=loginIdEdit %>">Edit</button>
</td>
</tr>
<%
}
%>
</table>
//Modal here
<div class="modal fade" id="editModal" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
</div>
<form class="contact"> //give action, method attribute here or make ajax call on save button clicked,
<input type="hidden" name="????" id="loginid">// the modal on shown will fill this value.
<div class="modal-body">
<div class="form-group">
<label for="sel1"><span></span>Select status:</label> <select
class="form-control" id="sel1" name="sel1">
<option>Validate Error</option>
<option>Auto Weaver</option>
<option>ReDefault</option>
</select>
</div>
<div class="form-group">
<label for="defaultercomment"><span></span>Add
comment:</label> <input type="text" class="form-control"
name="defaultercomment" id="defaultercomment"<%-- value="<%=loginIdEdit%>" --%>>
</div>
</div>
<div class="modal-footer">
<button type="button" id="save" name="save"
class="btn btn-default" data-dismiss="modal" align="centre">Done</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
$(function() {
//twitter bootstrap script
$("button#save").click(function(e) {
$.ajax({
type : "POST",
url : "defaulterUpdater.jsp",
data : $('form.contact').serialize(),
success : function(msg) {
},
error : function() {
alert("Failed");
}
});
});
});

Categories

Resources