Is it possible to update modal content via javascript? [resolved] - javascript

[Resolved - I had two modals defined with different Ids but when I disabled one, it worked as expected. Changed it so all content goes through one modal. At some point I may revisit to figure out where the conflict was.]
I have a mvc core page on which I have a modal that uses a partial view. In the modal, I'd like to present a summary list and let the user click an item in the list to view additional details on the modal. However, while the element is reporting it has been changed (via an alert check) it is not visibly updated. I then created a simple test to change the background color of a div to see if the approach itself is valid.
In this case the alerts identify that the color was changed, but again, it does not visually change. So the question is, how can I dynamically update text or CSS within a modal dialog using a js/jquery function? Is it even possible? I'm not interested in reloading the modal.
My test modal content (_TestContentModal):
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="closeMe"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<div id="test">
background color test
</div>
<div>
<button onclick="UpdateDetails('yellow');">Change background to yellow</button>
</div>
</div>
<div class="modal-footer">
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Close</button>
</div>
</div>
<script>
function UpdateDetails(newColor) {
alert('Before change: ' + $('#test').css("background-color")); // Before change: rgba(0, 0, 0)
$('#test').css("background-color", newColor);
alert('After change: ' + $('#test').css("background-color")); // After change: rgba(255, 255, 0)
// clicking a second time confirms that the color was updated:
// Before change: rgba(255, 255, 0)
// After change: rgba(255, 255, 0)
}
</script>
Clicking the button properly triggers the function and the alerts show/confirm that the background color is being changed, however it is not visibly changed. A second button click confirms the new color was set.
I'm relatively new to modals and it is quite possible that I'm going about this entirely the wrong way. Thanks in advance for any advice or solution.
Edit:
Including some additional code in response to initial answer. Since the above code seems to function as intended elsewhere the problem must lie in the handling of the modal.
On parent page is the reference to the modal:
<partial name="_TestModal" />
This is the content of _TestModal.cs:
<!--Modal-->
<div aria-hidden="true" aria-labelledby="modal-test-label" role="dialog" tabindex="-1" id="modal-test" class="modal fade">
<div class="modal-dialog modal-lg">
</div>
</div>
A button on the parent page activates the modal:
<div>
<a class="btn btn-secondary popup"
style="color: black;"
data-url='#Url.Action("GetTest","Runways")'
data-toggle="modal"
data-target="#modal-test">
Update<i class="fa fa-plus"></i>
</a>
</div>
The GetTest action of the controller returns the partial that contains the modal content shown at the top:
return PartialView("_TestContentModal");
And finally, the parent page has this script to handle the modal:
(function ($) {
function Index() {
var $this = this;
function initialize() {
$(".popup").on('click', function (e) {
modelPopup(this);
});
function modelPopup(reff) {
var url = $(reff).data('url');
$.get(url).done(function (data) {
$('#modal-test').find(".modal-dialog").html(data);
$('#modal-test > .modal', data).modal("show");
});
}
}
$this.init = function () {
initialize();
};
}
$(function () {
var self = new Index();
self.init();
});
}(jQuery));
To be clear: the color is not visibly changing. There are no errors reported in the browser console so the alerts were added to see how the element was responding. Minus the alerts, Brando Zhang's answer demonstrates the expected behavior, but in my case it does not turn yellow, with or without the timer delay. And again, the alerts were only added as a debug aid.

Do you mean you want to show the test backgournd color to yellow before the alert After change?
If this is your requirement, I suggest you could try to use setTimeout to not fired the alert immediately.
More details, you could refer to below codes:
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close" id="closeMe"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body">
<div id="test">
background color test
</div>
<div>
<button onclick="UpdateDetails('yellow');">Change background to yellow</button>
</div>
</div>
<div class="modal-footer">
<button data-dismiss="modal" id="cancel" class="btn btn-default" type="button">Close</button>
</div>
</div>
<script>
function UpdateDetails(newColor) {
alert('Before change: ' + $('#test').css("background-color")); // Before change: rgba(0, 0, 0)
$('#test').css("background-color", newColor);
setTimeout(function () { alert('After change: ' + $('#test').css("background-color")); }, 1)
// After change: rgba(255, 255, 0)
// clicking a second time confirms that the color was updated:
// Before change: rgba(255, 255, 0)
// After change: rgba(255, 255, 0)
}
</script>
Result:

Related

Jquery.load HTML and insert into bootstrap modal

I'm kind of stuck at the moment. Would really appreciate if someone can help me with this.
First time asking a question, so please bear with me :)
I have a main page with a few buttons. Each button opens a bootstrap modal. I am able to load dynamic content into the modal. Also inserting external HTML works, but here's the catch.... The HTML content I insert also has some 'fancy' features like my main page has (ex. animated progress bar/skills) For the external HTML to work I need to reference the same script as my main page has, but if so, things on my main page gets broken.
My question is, is there any way that I can insert HTML into my modal and have the inserted HTML be able to use the existing functions on my main page?
var iModal = document.getElementById('iModal');
iModal.addEventListener('show.bs.modal', function handler() {
// Button that triggered the modal
var button = event.relatedTarget;
var modalTitleArg = button.getAttribute('data-bs-title');
var modalId = button.getAttribute('data-bs-id');
var modalTitle = iModal.querySelector('.modal-title');
var modalBody = iModal.querySelector('.modal-body');
modalTitle.textContent = modalTitleArg;
if (modalId == 1) {
$('.modal-body').load('Content1.html', function() {
$.getScript("js/functions.js") //get script, modal works, broken mainpage.
});
} else if (modalId == 2) {
$('.modal-body').load('Content2.html', function() {
//$.getScript("js/functions.js") //script reference in html, modal works broken mainpage
});
} else {
$('.modal-body').load('Content3.html', function() {
//$.getScript("js/functions.js") // no script at all, broken modal, mainpage works fine
});
}
this.removeEventListener('show.bs.modal', handler);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button type="button" class="btn btn-outline-light mt-2" data-bs-toggle="modal" data-bs-target="#iModal" data-bs-id="1" data-bs-title="Title1">Click me 1</button>
<button type="button" class="btn btn-outline-light mt-2" data-bs-toggle="modal" data-bs-target="#iModal" data-bs-id="2" data-bs-title="Title2">Click me 2</button>
<button type="button" class="btn btn-outline-light mt-2" data-bs-toggle="modal" data-bs-target="#iModal" data-bs-id="3" data-bs-title="Title3">Click me 3</button>
<!-- modal -->
<div class="modal fade" id="iModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="myModalLabel">Title</h3>
<!-- data-bs-title -->
<button type="button" class="btn-close btn-sm" data-bs-dismiss="modal" aria-hidden="true"></button>
</div>
<div class="modal-body">
<!-- external html content -->
</div>
<div class="modal-footer">
<button type="button" class="btn-close btn-sm" data-bs-dismiss="modal" aria-hidden="true"></button>
</div>
</div>
</div>
</div>
<script src="js/functions.js"></script>
If in your "Content1.html", "Content2.html" etc. there is already an attached <script src="js/functions.js"></script> (as in a simple web page), then you can add content simply through an iframe tag (via the src attribute). Sample part of the code from your example:
...
<div class="modal-body">
<iframe class="modal-body-frame"></iframe>
</div>
...
<script>
...
const modalFrame = document.querySelector('.modal-body-frame');
if (modalId === 1) modalFrame.src = 'Content1.html';
...
</script>
...
But if you need to embed the script into the content every time, then you can use the srcdoc attribute of the iframe tag. Example below:
...
<div class="modal-body">
<iframe class="modal-body-frame" srcdoc=""></iframe>
</div>
...
<script>
...
const modalFrame = document.querySelector('.modal-body-frame');
if (modalId === 1) {
$.get('Content1.html', function(data) {
modalFrame.srcdoc = data.replace('</head>', '<script src="js/functions.js"></script></head>');
})
}
...
</script>
...
When using frame, it is important not to forget about Feature Policy and the ability to add permission via the allow attribute (Example: <iframe srcdoc="<p>Example test page</p>" allow="fullscreen"></iframe>).

Modal won't close and prevent default on no click, and won't execute func on yes click

I have a modal with two buttons. One is a yes button and one is a no button. If yes button is pressed, I would like the remainder of the function to execute. If no btn clicked, I would like the page to prevent default and not execute. However, it seems that regardless of which button is clicked, nothing happens besides the modal closing. I am using a modal example I found elsewhere, so this may be the issue. After glancing at it for some time I cannot seem to find where the issue is. Am I missing something small? Or perhaps my Jquery is wrong? Below is my code:
Modal:
<!-- Modal for delete-->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content border-primary mb-3 box-shadow-none img-responsive">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="card-body bg-light">
<div id="del" class="center">
<label>Are you sure you want to delete?</label>
</div>
</div>
<div class="modal-footer">
<div id="deleteYes">
<button type="button" class="btn btn-default" data-dismiss="modal" id="deleteYes">Yes</button>
</div>
<div id="deleteNo">
<button type="button" class="btn btn-default" data-dismiss="modal" id="deleteNo">No</button>
</div>
</div>
</div>
</div>
</div>
And here is my Jquery:
$(".btnDeleteTerminalCommand").click(function (e) {
$("#deleteModal").modal('toggle');
if ($("#deleteNo").click) {
return e.preventDefault();
}
var rowId = "#" + $(this).data("rowindex");
var row = $(rowId);
var termId = row.find(".tdTermId").html().trim();
var cmdId = row.find(".tdCmdId").html().trim();
var cmdVal = row.find(".tdCmdVal").html().trim();
var cmdID = row.find(".cmdID").html().trim();
var data = {
TerminalID: termId,
CommandID: cmdId,
CommandValue: cmdVal,
ID: cmdID
};
$.ajax({
url: '#Url.Action("DeleteTerminalCommand", "TerminalCommand")',
type: "POST",
data: data,
success: function (response) {
console.log("Success");
window.location.href = response.Url;
}
});
});
Any advice helps! Thank you!
Your click handler will toggle the modal and immediately continue to execute the rest of the function before the user can click anything. If your modal has two buttons, create a click handler for each button. Perhaps the No button just closes the modal. The Yes button handler can execute the actions required to accomplish the task.
$(".btnDeleteTerminalCommand").click(function(e){
$("#deleteModal").modal('toggle');
}
$("#deleteNo").click(function(e){
$("#deleteModal").modal('hide');
}
$("#deleteYes").click(function(e){
// build data object
// ajax post
}

Changing data in bootstrap modal

I'm working on jeopardy game where I pass questions into a bootstrap modal based on the button clicked. The button has an attribute data-num, (the index in the array of questions), which is used to to change the title in the modal. It also passes this index as an attribute data-num to the reveal answer button, which, when clicked, will change modal title to the answer.
This works for the first question, but when I click on the second question, the proper question loads, but the answer to the first question loads when I click the getanswer button, even though the proper index shows up in inspect element under button data-num.
What am I doing wrong?
var questions = [{
prompt: "What generic data type should we use when we want to use varying data types for a variable?",
correctAnswer: "Object",
},
{
prompt: "Rewrite the following Javascript statment in C#: var flag = true ",
correctAnswer: "bool flag = true"
},
{
prompt: "double num1 = 9.34534910;\n int num2= (int)num1;\nSystem.Console.WriteLine(num2);",
correctAnswer: "9"
}
];
function showQuestion(event, $modal) {
var button = $(event.relatedTarget);
var num = parseInt(button.data('num'));
var question = questions[num];
$modal.find('.modal-title').text(question.prompt);
$modal.find('.modal-body button').attr('data-num', num)
}
$("#myModal").on('show.bs.modal', function(event) {
showQuestion(event, $(this));
}
);
$("#myModal").on('hidden.bs.modal', function() {
$('#myModal').removeData('bs.modal');
}
);
$("#getanswer").click(function() {
var num = ($(this).data('num'));
console.log(num)
}
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bs-example">
<!-- Modal HTML -->
<div id="myModal" class="modal fade">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<p class="modal-title" data-answer="">Modal Window</p>
<button id="getanswer" type="button" data-num="" class="btn btn-primary clickable">Reveal answer</button>
</div>
</div>
</div>
</div>
<div class="question">
<button type="button" class="btn btn-info gridbtn ten" data-toggle="modal" data-target="#myModal" data-num="0">$10</button>
</div>
<div class="question">
<button type="button" class="btn btn-info gridbtn fifty" data-toggle="modal" data-target="#myModal" data-num="1">$50</button>
</div>
</div>
Use this (on the #getAnswer click event):
var num = ($(this).attr('data-num'));
instead of
var num = ($(this).data('num'));
Perhaps since you set the value with attr, it also works to retrieve it that way.
It DOES seem like your way should work, but this is what I found through trying stuff.

Leaflet map freezing in bootstrap 3.0 modal

I'm trying to load map in bootstrap modal but map appear partly, it's also freezing so I can't select any region. Despite of using map.invalidateSize() my problem is still resisting. Is there anybody to make it work in bootstrap modal or any other kind of modal?
here is my code:
<script type="text/javascript">
var LbsConfig = {
Url:'https://map.ghasedakbahar.ir:6443/arcgis/rest/services/iran/FeatureServer/0',
View: [35.6970, 51.4079],
MapID: 'map-id',
Color: {
Default: '#9ab9ff',
Selected: '#ff0659'
}
};
var map = LbsMap();
LbsShowNew(map, function (regions) {
var maxRegions = 5;
var errRegions = 'The number of areas is more than 5 areas';
if (regions.length > maxRegions) {
alert(errRegions);
return;
}
jQuery('#Regions').val(regions.join(','));
jQuery('#count-selected').html(regions.length);
});
$('#myMap').on('show.bs.modal', function () {
setTimeout(function () {
map.invalidateSize();
}, 10);
});
</script>
#map-id {
padding: 0;
width: auto;
height: 400px;
}
<!-- Modal -->
<div class="modal fade" id="myMap" role="dialog" style="margin-top:70px">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content font-yekan">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">'SendSmsDetail'</h4>
</div>
<div class="modal-body" id="modal-body">
<div id="map-id"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
I remember having the same problem before. There is a lot of similar problem on internet and maybe this one can help you :
Leaflet map not showing properly in bootstrap 3.0 modal
I think what is happening is that, when the map is created, the
container width/height for your `map-canvas' element has not yet been
adjusted to the width/height of the modal dialog. This causes the map
size to be incorrect (smaller) than what it should be.
You can fix this by calling map.invalidateSize(). This will work to
re-adjust the width/height bounds of the L.Map's container.
You can automatically call this by hooking into the event where the
Bootstrap modal becomes shown.
$('#myModal').on('show.bs.modal', function(){
setTimeout(function() {
map.invalidateSize();
}, 10);
});
Insert this code into your JavaScript. When the modal is shown, the
map will then invalidate its size. The timeout is because there may be
some animation/transition time for the modal to display and be added
to the DOM.

Bootstrap modal with angular. Modal not closing with a specific data-ng-click function

I am trying to figure out why this particular Bootstrap confirmation modal is not working with my desired function. It does appear to work with a basic function bringing up an alert window but when I put the function I want it, it executes the function (in this case deletes an image from File-stack and my db) but it hangs up the modal window to where the modal window closes but there is that grey overlay stuck and it makes the page no longer functional. The function that seems to be holding this up is in the first button in the modal-footerdiv towards the bottom. The close button works fine and again it works fine when I put a simple function in place of the removeMoreImage() function Here is the code for the Bootstrap modal:
<button type="button" class="btn btn-danger" data-toggle="modal" data-target="#confirm-modal-more"> <span class= "glyphicon glyphicon-remove-circle"></span> REMOVE IMAGE</button>
<div id="confirm-modal-more" class="modal fade" 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">Remove Image Confirmation</h4>
</div>
<div class="modal-body">
<p>Are you sure you want to delete this image?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-ng-click="removeMoreImage(picture.url, car)" data-dismiss="modal" >REMOVE</button>
<button type="button" class="btn btn-default" data-dismiss="modal">CANCEL</button>
</div>
</div>
</div>
</div>
Here is the function that is is executing causing the hangup:
var getIndexIfObjWithOwnAttr = function(array, attr, value) {
for (var i = 0; i < array.length; i++) {
if (array[i].hasOwnProperty(attr) && array[i][attr] === value) {
return i;
}
}
return -1;
}
$scope.removeMoreImage = function(image, data) {
var index = getIndexIfObjWithOwnAttr(data.morePictures, 'url', image);
data.morePictures.splice(index, 1);
filepickerService.remove(image);
console.log(image + " has been removed!");
}
Any insights or advice would be great. It seems like sync issue but I am not sure.
I ended up using some query to force the modal close and it seems to work nicely though it is not as elegant of a solution as I was hoping for but it seems to work. This is the code I added to the function that was hanging up the modal.
$('#confirm-modal-more').modal('hide');
$('body').removeClass('modal-open');
$('.modal-backdrop').remove();
You can close the modal in the function and return a result to the parent controller:
$uibModalInstance.close('some result of modal');
$uibModalInstance.dismiss('some reason for discarding and closing');
$scope.removeMoreImage = function(image, data) {
var index = getIndexIfObjWithOwnAttr(data.morePictures, 'url', image);
data.morePictures.splice(index, 1);
filepickerService.remove(image);
console.log(image + " has been removed!");
// close modal
$uibModalInstance.close();
}
https://angular-ui.github.io/bootstrap/#/modal

Categories