button, jquery and modals - javascript

I'm trying to understand modals and js better. I have tried to use buttons that are realated to php files in order to make the content of the php files appear in a modal window once the button is clicked.
so...
button_1 gets file_1 and puts it in modal once it is clicked.
button_2 gets file_2 and puts it in modal once it is clicked.
etc.
I have acheived most of this but for some reason, each button needs to be clicked twice (for the first appearence of the modal window) for the modal to work. Afterwards, a simple click works fine, until the page is refreshed. At that point, two clicks are again needed.
My code works fine if I don't try to insert the information from the php file into a modal window. So... I'm guessing it is releated to the fact that the button has to do two things. 1. get the info and 2. open the modal window.
How do I combine both in one click?
I have tried to prefech files.
<link rel="prefetch" href="/folders/to/php/files/1.php">
I have also tried to pre-insert the modal in the html .
I have tried to use the load instead of click in the function.
I my tries have not changed the fact that I need to double click the buttons at first.
Any help appreciated!!
BONUS:
If I could get the buttons to dynamically find their related file, that would be bonus. Meaning I could simply add or remove buttons and they would find the correct files. All I would need to do is to add as many files as buttons.
Thanks for your time and help!
Here are the codes:
$("#liste > button").on('click', apar);
function apar() {
$(this).addClass("active").siblings().removeClass("active");
$('#main_p').load("/folders/to/php/files/" + (1 + $(this).index()) + ".php");
$(document).ready(function() {
// Do something with the DOM
$('.active').click(function() {
});
});
}
function renderHTML(data) {
var htmlP = data.url;
$('#main_p').html(htmlP);
}
// On page load, click on the first `btn` to automatically load the data for it
$('#liste > button:first').click(renderHTML);
.btn {
margin: 5px;
padding 0px 5px;
text-align: center;
background-color: #0095ff;
color: #FFF;
border: none;
}
.btn:hover,
.btn:focus {
outline: none !important;
color: #FFF;
}
.active {
background-color: #891;
}
<!doctype html>
<html>
<head>
<title> Modals </title>
<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.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div id="liste">
<button class="btn" data-toggle="modal" data-target="#myModal_1">
<div class="tree">to file 1</div>
</button>
<button class="btn" data-toggle="modal" data-target="#myModal_2">
<div class="tree">to file 2</div>
</button>
<button class="btn" data-toggle="modal" data-target="#myModal_3">
<div class="tree">to file 3</div>
</button>
<h4 id="main_tit"></h4>
<div class="main_p" id="main_p"></div>
<div id="main_ima"></div>
<script src="js/main.js" async></script>
</body>
</html>
here is the example of a 1.php file:
<div id="myModal_1" class="modal fade" 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">Look 1</h4>
</div>
<div class="modal-body">
<?php
echo "I have the 1.php <br>";
echo "its a go!";
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
UPDATE: I have added the automatic selection on button. So I have removed the button attributes in the html and have added this at the top of the JS:
var idVar = $("#liste").find("button").each(function(index){
$(this).attr("data-target","#myModal_" + (1+$(this).index()));
$(this).attr("data-toggle","modal");
$(this).attr("class","btn");
});

At the top of your js file there is $("#liste > button").on('click', apar);
Try to change it to:
$('body').on('click', '#liste > button', apar);
And put it at the end of your code after your $('#liste > button:first').click(renderHTML);
Let me know if this doesn't fix it.
Edit: Try creating new custom class for those buttons in HTML. It is good to set a marker to your custom classes, something like l-custom-class, or customClass, try to follow this example:
HTML:
<div id="#liste">
<button type="button" class="l-liste-button">btn1</button>
<button type="button" class="l-liste-button">btn2</button>
<button type="button" class="l-liste-button">btn3</button>
</div>
JS:
function apar(){
//some code for apar function..
}
function renderHTML(){
//some code for renderHTML function
}
$('body').on('click', '.l-liste-button', apar);
$('body').on('click', '.l-liste-button:first', renderHTML);
Here is JSFiddle

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>).

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

[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:

Materialize modal not working

I wrote a simple code for materialize modal.
HTML code:
<a class="waves-effect waves-light btn view" data-target="modal1">View Scores</a>
<!-- Modal Structure -->
<div id="modal1" class="modal">
<div class="modal-content">
<h4>Modal Header</h4>
<p>A bunch of text</p>
</div>
<div class="modal-footer">
Agree
</div>
</div>
JS code:
$(document).ready(function() {
// the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered
/*$('.view').click(function (){
$('#modal1').modal('open');
alert('edskjcxnm');
});*/
/*$('.view').leanModal();*/
$('#modal1').modal('open');
});
JSFiddle link: https://jsfiddle.net/7f6hmgcf/
Why isn't it working?
Initialize all modals first. $('.modal').modal();
Complete code will look like this
(function ($) {
$(function () {
//initialize all modals
$('.modal').modal();
//now you can open modal from code
$('#modal1').modal('open');
//or by click on trigger
$('.trigger-modal').modal();
}); // end of document ready
})(jQuery); // end of jQuery name space
Not 100% sure what you are asking for here, but if what you are asking is how to trigger modal on button click you can simply do it by setting an onclick like this:
<a class="waves-effect waves-light btn view" onclick="$('#modal1').modal('open');">View Scores</a>
But before you can do $('#modal1').modal('open'); you need to initiate the modal in your js, like this:
$(document).ready(function() {
$('#modal1').modal();
});
You can check out my solution in this fiddle: https://jsfiddle.net/AndreasMolle/7f6hmgcf/13/
Another solution might be to do it this way:
<a class="waves-effect waves-light btn view" href="#modal1">View Scores</a>
MaterializeCCS documents aren't too clear, here's how I solved my problem.
HTML
<!-- Modal Trigger -->
<a class="waves-effect waves-light btn modal-trigger" href="#modal1">Modal</a>
<!-- Modal Structure -->
<div id="modal1" class="modal">
<div class="modal-content">
<h4>Modal Header</h4>
<p>A bunch of text</p>
</div>
<div class="modal-footer">
Agree
</div>
</div>
JavaScript
$(document).ready(function(){
// the "href" attribute of .modal-trigger must specify the modal ID that wants to be triggered
$('.modal-trigger').leanModal();
});
I recently updated my project to materializecss 0.98.0 and with this version I need to initialize modals before open it.
//Old
$('#modal1').openModal();
//New
$('#modal1').modal().modal('open');
I don't find any configuration like "autoOpen" on the modal initial options :(.
$( document ).ready(function() {
$('.modal').modal();
$('#modal1').on('click', function() {
});
});
https://jsfiddle.net/juands/z512cb7f/3/ check this link
Try Materialize.Modal class
let modal=new Materialize.Modal($("#yourModal"));
modal.open(); //Open it on some event
modal.close(); //This is not needed as you can close it with the modal buttons. It's tricky

Bootstrap alert JS won't slide down

Using this JS:
$('#comment').click(function(e) {
e.preventDefault();
$('#comment').slideDown();
});
}
And this html code:
<div id="comment" class="alert alert-info" style="margin-top: 20px; display: none;"></div>
<button type="button" class="btn btn-default btn-sm" id="route_update">Edit</button>
it should, if successful, slide down with the message...But it don't, the blue bar won't go down.
Try this code:
$('#route_update').click(function() {
$('#comment').slideDown();
});
Explanation:
Your jQuery requires the hidden element to be clicked in order to show the alert. This won't work.
Using the 'Edit' button's ID to call the function works.

jquery modal: closing a modal and then having it available as a clickable option

I been scratching my head on this one for a while.
Writing a plugin in grails that calls on bootstrap-mini.js and most of its css. Everything works fine. The issue I am having is I have a remote form which onComplete runs java script:
https://github.com/vahidhedayati/ml-test/blob/master/grails-app/views/mailingListModal/_modalcreate.gsp
<g:javascript>
function ${controller}CloseModal() {
var myClone=$('#BuildModal${id}').clone();
$('#BuildModal${id}').dialog().dialog('close');
$(".modal-backdrop").hide();
$('body').removeClass('modal-open');
//var myCloner = myClone.clone();
$('#${divId}1').hide().append(myClone);
//$('body').append(myClone);
<g:if test="${!disablecheck.equals('true') }">
var controller="${controller }";
var divId="${divId }";
$.get('${createLink(controller:"MailingListEmail", action: "getAjaxCall")}?ccontroller='+controller+'&divId='+divId,function(data){
$('#${divId}').hide().html(data).fadeIn('slow');
});
</g:if>
}
</g:javascript>
The bits at the top of the function is all the things I have tried so far.
https://github.com/vahidhedayati/ml-test/blob/master/grails-app/views/mailingListEmail/contactclients.gsp
<div class="tbutton">
<button href="#BuildModalSENDERS" class="btn btn-block btn-success" role="button" data-toggle="modal" title="Configure New Sender">
New Sender?</button>
<div id="mailerSenders1">
<g:render template="/mailingListModal/modalcreate" model="[title:'Add Senders Email', controller: 'mailingListSenders', callPage: 'form' , divId: 'mailerSenders', id: 'SENDERS' ]" />
</div>
And finally modelForm which is included on the top of the modalcreate.gsp (now shown)
<div class="modal fade" id="BuildModal${id}" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<g:formRemote id="${controller}" name="urlParams" class="form-horizontal" url="[controller:controller, action:'save']"
update="BuildModal${id}" onComplete="${controller}CloseModal()"
>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">x</button>
<h3>${title }</h3>
</div>
<div class="modal-body">
<div class="form-group">
<g:render template="/${controller }/${callPage }"/>
<g:submitToRemote class="myformsubmit" url="[controller:controller, action:'save']" update="BuildModal${id}" onComplete="${controller}CloseModal()" value="Create" />
</div>
</div>
</g:formRemote>
</div>
</div>
</div>
</div>
So it is a remote Form that submits can calls the above CloseModal
The question is when I Close this how do I make it available again when the user clicks the button to create new email ?
After adding all the cloning at the top of java script the only difference I was able to make was to make it display the backdrop on 2nd click so it went black on 2nd click but did not show up the modal content.
ok got it working by doing this:
<button href="#BuildModalSENDERS" class="btn btn-block btn-success" role="button" data-toggle="modal" title="Configure New Sender"
Now adding
onClick="runCheck()"> .....
<g:javascript>
function runCheck() {
$('#mailerSenders1').show();
}
</g:javascript>
That seems to work fine, it now loads up the page, just to add when I did body it just loaded it up again from the commented out attempts, modal.hide etc did not work and the hide attempts just showed it up under some other layers of the same page.. anyways this works fine now. sorry

Categories