Using Bootstrap Modal window as PartialView - javascript

I was looking to using the Twitter Bootstrap Modal windows as a partial view. However, I do not really think that it was designed to be used in this fashion; it seems like it was meant to be used in a fairly static fashion. Nevertheless, I think it'd be cool to be able to use it as a partial view.
So for example, let's say I have a list of Games. Upon clicking on a link for a given game, I'd like to request data from the server and then display information about that game in a modal window "over the top of" the present page.
I've done a little bit of research and found this post which is similar but not quite the same.
Has anyone tried this with success or failure? Anyone have something on jsFiddle or some source they'd be willing to share?
Thanks for your help.

Yes we have done this.
In your Index.cshtml you'll have something like..
<div id='gameModal' class='modal hide fade in' data-url='#Url.Action("GetGameListing")'>
<div id='gameContainer'>
</div>
</div>
<button id='showGame'>Show Game Listing</button>
Then in JS for the same page (inlined or in a separate file you'll have something like this..
$(document).ready(function() {
$('#showGame').click(function() {
var url = $('#gameModal').data('url');
$.get(url, function(data) {
$('#gameContainer').html(data);
$('#gameModal').modal('show');
});
});
});
With a method on your controller that looks like this..
[HttpGet]
public ActionResult GetGameListing()
{
var model = // do whatever you need to get your model
return PartialView(model);
}
You will of course need a view called GetGameListing.cshtml inside of your Views folder..

I do this with mustache.js and templates (you could use any JavaScript templating library).
In my view, I have something like this:
<script type="text/x-mustache-template" id="modalTemplate">
<%Html.RenderPartial("Modal");%>
</script>
...which lets me keep my templates in a partial view called Modal.ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<div>
<div class="modal-header">
<a class="close" data-dismiss="modal">×</a>
<h3>{{Name}}</h3>
</div>
<div class="modal-body">
<table class="table table-striped table-condensed">
<tbody>
<tr><td>ID</td><td>{{Id}}</td></tr>
<tr><td>Name</td><td>{{Name}}</td></tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<a class="btn" data-dismiss="modal">Close</a>
</div>
</div>
I create placeholders for each modal in my view:
<%foreach (var item in Model) {%>
<div data-id="<%=Html.Encode(item.Id)%>"
id="modelModal<%=Html.Encode(item.Id)%>"
class="modal hide fade">
</div>
<%}%>
...and make ajax calls with jQuery:
<script type="text/javascript">
var modalTemplate = $("#modalTemplate").html()
$(".modal[data-id]").each(function() {
var $this = $(this)
var id = $this.attr("data-id")
$this.on("show", function() {
if ($this.html()) return
$.ajax({
type: "POST",
url: "<%=Url.Action("SomeAction")%>",
data: { id: id },
success: function(data) {
$this.append(Mustache.to_html(modalTemplate, data))
}
})
})
})
</script>
Then, you just need a trigger somewhere:
<%foreach (var item in Model) {%>
<a data-toggle="modal" href="#modelModal<%=Html.Encode(item.Id)%>">
<%=Html.Encode(item.DutModel.Name)%>
</a>
<%}%>

I have achieved this by using one nice example i have found here.
I have replaced the jquery dialog used in that example with the Twitter Bootstrap Modal windows.

Complete and clear example project
http://www.codeproject.com/Articles/786085/ASP-NET-MVC-List-Editor-with-Bootstrap-Modals
It displays create, edit and delete entity operation modals with bootstrap and also includes code to handle result returned from those entity operations (c#, JSON, javascript)

I use AJAX to do this. You have your partial with your typical twitter modal template html:
<div class="container">
<!-- Modal -->
<div class="modal fade" id="LocationNumberModal" 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">
Serial Numbers
</h4>
</div>
<div class="modal-body">
<span id="test"></span>
<p>Some text in the modal.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">
Close
</button>
</div>
</div>
</div>
</div>
</div>
Then you have your controller method, I use JSON and have a custom class that rendors the view to a string. I do this so I can perform multiple ajax updates on the screen with one ajax call. Reference here: Example but you can use an PartialViewResult/ActionResult on return if you are just doing the one call. I will show it using JSON..
And the JSON Method in Controller:
public JsonResult LocationNumberModal(string partNumber = "")
{
//Business Layer/DAL to get information
return Json(new {
LocationModal = ViewUtility.RenderRazorViewToString(this.ControllerContext, "LocationNumberModal.cshtml", new SomeModelObject())
},
JsonRequestBehavior.AllowGet
);
}
And then, in the view using your modal: You can package the AJAX in your partial and call #{Html.RenderPartial... Or you can have a placeholder with a div:
<div id="LocationNumberModalContainer"></div>
then your ajax:
function LocationNumberModal() {
var partNumber = "1234";
var src = '#Url.Action("LocationNumberModal", "Home", new { area = "Part" })'
+ '?partNumber='' + partNumber;
$.ajax({
type: "GET",
url: src,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
$("#LocationNumberModalContainer").html(data.LocationModal);
$('#LocationNumberModal').modal('show');
}
});
};
Then the button to your modal:
<button type="button" id="GetLocBtn" class="btn btn-default" onclick="LocationNumberModal()">Get</button>

Put the modal and javascript into the partial view. Then call the partial view in your page.
This will handle form submission too.
Partial View
<div id="confirmDialog" class="modal fade" data-backdrop="false">
<div class="modal-dialog" data-backdrop="false">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Missing Service Order</h4>
</div>
<div class="modal-body">
<p>You have not entered a Service Order. Do you want to continue?</p>
</div>
<div class="modal-footer">
<input id="btnSubmit" type="submit" class="btn btn-primary"
value="Submit" href="javascript:"
onClick="document.getElementById('Coordinate').submit()" />
<button type="button" class="btn btn-default" data-
dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
Javascript
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$("#Coordinate").on('submit',
function (e) {
if ($("#ServiceOrder").val() == '') {
e.preventDefault();
$('#confirmDialog').modal('show');
}
});
});
</script>
Then just call your partial inside the form of your page.
Create.cshtml
#using (Html.BeginForm("Edit","Home",FormMethod.Post, new {id ="Coordinate"}))
{
//Form Code
#Html.Partial("ConfirmDialog")
}

Related

AJAX call not triggered on show.bs.modal

I have a button which is supposed to trigger a modal with a contact form. Part of the show.bs.modal function is an AJAX call to my DB to get some file details which are then meant to be shown in the modal-body.
The problem is that the modal does indeed open, but with no modal-body content, which means that the JavaScript code to trigger to the AJAX call is not working. I do not see any network activity in the browser debug menu, no call to the PHP file, and even an alert on top of the JS code telling me that that a button was pressed is not triggered. It seems like the whole JS code is circumvented, yet the modal still shows.
The same code works in another project, anyone has any idea as to why this is happening?
Button:
<div class="card-footer bg-light text-center">
<button id="modal_btn" name="modal_btn" type="button" class="btn bg-teal-400" data-toggle="modal" data-target="#modal_contact_form" data-imgid="'.$row['image_id'].'" data-keyboard="true">
<span class="icon-ico-mail4"></span> Anfragen
</button>
</div>
Modal:
<!-- Contact form modal -->
<div id="modal_contact_form" class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-teal-300">
<h3 class="modal-title">Kaufanfrage - Artikel #1234</h3>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal">Abbrechen</button>
<button type="submit" class="btn bg-teal-300">Nachricht Senden</button>
</div>
</form>
</div>
</div>
</div>
<!-- /contact form modal -->
JavaScript:
<script type="text/javascript">
// DISPLAY EDIT RECORD MODAL
$('#modal_contact_form').on('show.bs.modal', function (event) {
//var button = $(event.relatedTarget) // Button that triggered the modal
window.alert("button clicked.");
var imgid = $(event.relatedTarget).data('imgid') // Extract info from data-* attributes
var modal = $(this);
var dataString = 'action=contact&imgid=' + imgid;
$.ajax({
type: "POST",
url: "./assets/ajax/ajax_action.php",
data: dataString,
cache: false,
success: function (data) {
console.log(data);
modal.find('.modal-body').html(data);
},
error: function(err) {
console.log(err);
}
});
});
</script>
try this:
$(document).on('show.bs.modal','#modal_contact_form', function (event) {
// TODO ....
});
Or you can use the onclick button trigger instead of modal show trigger
$("#modal_btn").click(function(event){
// TODO ...
});
Try This
const bsModal = document.querySelector('#exampleModal');
$(bsModal).on('shown.bs.modal', function() {
// YOUR CODE HERE....
})

CKEditor is not working with bootstrap modal

I want to show ckEditor on bootstrap modal but the ckEditor is not opening as shown below. After searching through the internet I have got some solution in a different way like this link but I will perform an ajax request hence I have to open the modal using $('.cia_modal').modal('toggle'). The above-mentioned solution link does not work for me
Modal Button:
<button class="btn btn-info btn-xs cia_modal_btn" data-id="<?php echo $post->post_id; ?>" data-table="post" data-attr="post_id">
Create New Post
</button>
Modal:
<!--Modal-->
<div class="modal fade cia_modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-primary">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">×</span>
<span class="sr-only">Close</span>
</button>
<h4 class="modal-title">Create New Post</h4>
</div>
<div class="modal-body">
<form action="/action_page.php">
<div class="form-group">
<textarea class="ck_editor" name="post" id="" cols="30" rows="10"></textarea>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!--End Modal-->
Javascript:
<script type="text/javascript">
$(document).on("click", ".modal_btn", function (e) {
e.preventDefault();
e.stopPropagation();
let cia_modal = $('.cia_modal');
//Set modal show/hide
cia_modal.modal('toggle');
let id = $(this).attr('data-id');
let table = $(this).attr('data-table');
let attr = $(this).attr('data-attr');
//Set Form Data
let formData = new FormData();
formData.append('id',id);
formData.append('table',table);
formData.append('attr',attr);
$.ajax({
type: 'post',
url: '<?php echo base_url()?>post/create_post',
data: formData,
contentType: false,
processData: false,
success: function (data) {
//
}
});
});
</script>
Please help me. Thanks
I assume, you are using CKEditor 4.x.
You need to create editor using CKEDITOR.replace( 'ck_editor' ), you can do it only on element that is existing inside document. It doesn't matter if it's hidden or not. If your modal is inside DOM, but hidden, then just initialize editor. Otherwise you need to wait until element is appended then call CKEDITOR.replace.
Depending on how bootstraps implements modal.show. If it's just changes CSS to make it visible, then most likely you can initialize editor at the start of your script, if it adds elements to document, then you need to use some of bootstrap events to create editor in right time. See shown.bs.modal: https://getbootstrap.com/docs/4.0/components/modal/#events
Just initialize the editor:
<script type="text/javascript">
ClassicEditor.create($('.ck_editor')[0])
.then( editor => {
console.log( editor );
})
.catch( error => {
console.log( error );
});
$(document).on("click", ".modal_btn", function (e) {
//....

Struts2 action not being called on page refresh

I'm making a CRUD application for a school project, where there is a list of 'lesson groups', which you can add or remove.
I have a bootstrap modal that looks like this, where you can input a lesson group name and press a button to submit it:
<div class="modal fade" id="lessonGroupAddModal" tabindex="-1" role="dialog"
aria-labelledby="lessonGroupAddModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="lessonGroupAddModalLabel">Les groep toevoegen</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form class="addLessonGroupForm" role="form">
<div class="form-group">
<label for="lessonGroupName-input" class="col-2 col-form-label">Naam</label>
<div class="col-10">
<input class="form-control" type="text" value="" id="lessonGroupName-input">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Sluiten</button>
<button id="addLessonGroupButton" type="button" class="btn btn-primary">Toevoegen</button>
</div>
</div>
</div>
</div>
The button works by a JavaScript AJAX post request, this looks like this:
$("#addLessonGroupButton").on("click", function() {
if($("input[type=text]#lessonGroupName-input").val()) {
$.ajax({
type: 'POST',
url:'lessongroup/add.action',
dataType: 'json',
data : "lessonGroupName="+$("input[type=text]#lessonGroupName-input").val(),
});
}
location.reload();
});
The action method i'm using for this looks like this:
public String addLessonGroup() {
if (this.lessonGroupName == null || this.lessonGroupName.equals("")) {
return ERROR;
}
LessonGroup previousLessonGroup = this.getLessonGroups().last();
TestDAOLessonGroup.getInstance().create(new LessonGroup(previousLessonGroup.getId() + 1, lessonGroupName));
System.out.println("added lesson group with name " + lessonGroupName);
return SUCCESS;
}
The TestDAOLessonGroup is a singleton which saves that objects, i'm 100% sure the object is only getting made once.
The execute method of the controller looks like this:
public String execute() {
if (lessonGroups == null) {
lessonGroups = new TreeSet<>();
}
lessonGroups.clear();
lessonGroups.addAll(TestDAOLessonGroup.getInstance().getLessongroups());
return SUCCESS;
}
This puts the most recent lesson groups into the variable, which i am getting in the view.
My struts.xml action mapping looks like this:
<action name="lessongroup" class="employeemanagement.LessonGroupListingAction"
method="execute">
<result name="success">index.jsp</result>
</action>
I'm 100% sure this mapping works, and the lesson grouups are getting loaded in the view.
The problem is that when you add a new lesson group to the DAO via the post request, and it reloads the page by the location.reload(); statement, it doesn't call up the action the first time. When I add another lesson group, it works just fine.
How can I make it so that the Action would get called on the first page refresh? Am I using the right approach for this?
The url is not mapped to the action. You should add
<action name="add" class="employeemanagement.LessonGroupListingAction"
method="add">
<result type="json"/>
</action>
The json plugin is required to return json type result.
This action should be mapped to the url in ajax call
$("#addLessonGroupButton").on("click", function() {
if($("input[type=text]#lessonGroupName-input").val()) {
$.ajax({
type: 'POST',
url:'add.action',
dataType: 'json',
data : "lessonGroupName="+$("input[type=text]#lessonGroupName-input").val(),
success: function(data) {
console.log(JSON.stringify(data));
}
});
}
});

Boostrap modal not loading when wired using jquery

I have the following link and I'm trying to load a bootstrap modal when its clicked but the javascript function doesnt seem to be firing. Instead of the view loading inside a modal, its loading as a new page?
#*this is the modal definition*#
<div class="modal hide fade in" id="report-summary">
<div id="report-summary-container"></div>
</div>
<script >
$('a.js-report-summary').click(function (e) {
var url = $(this).attr('href'); // the url to the controller
e.preventDefault();
$.get(url, function (data) {
$('#report-summary-container').html(data);
$('#report-summary').modal('show');
});
});
</script>
public ActionResult ReportSummary()
{
// some actions
return PartialView("ReportSummary", viewmodel)
}
// Report summary view which contains modal
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">#ViewBag.FormName - Analysis</h4>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">
Close</button>
</div>
</div>
</div>
There are no errors showing in the console either so why isn't the jquery function firing?
in your click function, add parameter e this will stand for event
then in the function itself add e.preventDefault() This will stop the refreshing effect.
on your controller method try
public ViewResult ReportSummary()
{
// some actions
if(Request.IsAjaxRequest())
return PartialView("ReportSummary", viewmodel);
else
return View("ReportSummary", viewmodel);
}
on your view
$('#exampleModal').on('show.bs.modal', function (event) {//give your model wrapper an id
//do some ajax and get html
$.ajax({
url:'',
success:function(data){
$('#report-summary-container').html(data);
}
});
})
on your anchor tag, add data-toggle="modal" data-target="#exampleModal"
if you dont want to use bootstrap events trigger your modal with
$('#myModal').modal('show')

ASP.net MVC 4 Validation Within bootstrap Modal and PartialView

In my application I was using simple View the Validation, both client and server side validation, was working fine, but now I have changed to bootstrap modal and PartialView. The problem is that Client Side Validation dosn't work any more and for server side validation when I click submit he redirect me to new page (see picture) instead of showing the error on the current modal pop-up.
Create Controller :
[HttpGet]
public ActionResult Create()
{
ViewBag.CAT_ID = new SelectList(db.CATEGORIE, "CAT_ID", "LIBELLE");
ViewBag.C_GARANT = new SelectList(db.GARANTIE, "C_GARANT", "LIB_ABREGE");
return PartialView("_Create");
}
//
// POST: /Taux/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(TAUX taux)
{
if (ModelState.IsValid)
{
db.TAUX.Add(taux);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.CAT_ID = new SelectList(db.CATEGORIE, "CAT_ID", "LIBELLE", taux.CAT_ID);
ViewBag.C_GARANT = new SelectList(db.GARANTIE, "C_GARANT", "LIB_ABREGE", taux.C_GARANT);
return PartialView("_Create", taux);
}
_Create Partial View :
#model pfebs0.Models.TAUX
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="CreateTaux">Add</h3>
</div>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="modal-body">
<div class="form-group">
<div class="form-group">
<label for="Categorie">Categorie : </label>
#Html.DropDownList("CAT_ID", String.Empty)
#Html.ValidationMessageFor(model => model.CAT_ID)
</div>
//Other Form input.
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-default">Submit</button>
</div>
}
</div>
<script>
$("select").addClass("form-control");
$("input").addClass("form-control");
$("label").addClass("control-label");
</script>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval") }
Index View where I puted the modal :
<p>
#Html.ActionLink("Ajouter", "Create", "Taux",
new { id = "btnAdd", #class="btn btn-default"})
</p
<div id="modalDiv" class="modal fade" >
<div class="modal-dialog">
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(function () {
$.ajaxSetup({ cache: false });
$('#btnAdd').click(function () {
$('.modal-dialog').load(this.href, function () {
$('#modalDiv').modal({
backdrop: 'static',
keyboard: true
}, 'show');
});
return false;
});
});
</script> }
So what I have to add or change to Have client validation in my modal and for server validation to be redirected to modal, instead new page like in picture ?
You can rely on the built in bootstrap functionality of the role and data-target attributes. If you define your modal's role as "dialog" and give it an id then you can reference that in a HTML button with a data-target and data-toggle attributes.
You also need to avoid loading your _Create partial from an ajax request. Just load it along with Index using #Html.Partial. It will not appear in your view if the attributes are set correctly.
Here are the steps I did to get it working:
First modify your _Index to load partial view and update your modalDiv to define a role.
<div class="modal fade" id="modalDiv" tabindex="-1" role="dialog" aria-hidden="true">
#Html.Partial("~/{PathToView}/_Create.cshtml", new pfebs0.Models.TAUX())
</div>
Now instead of using #HtmlActionLink and JavaScript to load dialog, create a button as follows. Make sure to remove the JS click event code.
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#modalDiv">Ajouter</button>
Now bootstrap will handle showing and hiding dialog automatically with the defined role and data attributes and MVC validation will appear correctly. You can leave your controller code as-is.

Categories

Resources