Bootstrap remote Modal doesn't update content after first run - javascript

It comes javaScript and jQuery are beeing a big challenge for me. Like it's not enough I've started to use ajax to get over my problem - which is:
I've got some empty tables on my page. Each cell of a table has got its own id. A php-script is parsing a .xlsx file and puts the right link to the cell of my html table through javaScript code like:
document.getElementById("cellNrXY").innerHTML = "someLink";
If the link is clicked, then a Modal (Bootstrap) appears and loads the remote content (which is different depending on the clicked link).
My problem was that the remote content was cached in modal, so it worked only on first run. After closing the modal and choosing another link the previous modal appeared und didn't change to the new remote content.
I've read a lot solutions here that are based on:
$(this).removeData('bs.modal');
but had no luck with it. After some trying with different solutions one worked properly. The only problem was: when I've clicked the second time on some other link, the modal opened up with previous content and it took some seconds for the modal beeing updated. This is why I wanted to show a rotating element while the new modal content is beeing loaded. Somewhere here I've read a solution tu use ajax for this, which I've added "on luck" and ... it worked:
$("#myModal").on("show.bs.modal", function(e) {
$.ajax({
beforeSend: function() { $('#myModal')
.html('<div class="rotatingElement"></div>')
.show(); },
complete: function() { $('#myModal').html.hide(); }
});
var link = $(e.relatedTarget);
$(this).find(".modal-body").load(link.attr("href"));
});
The only thing is - I've no idea why this is working. Is there any chance that somebody here explain the functionality of this code to me?

if you read about the event show.bs.modal you will know that this event fires immediately when the show instance method is called. If caused by a click, the clicked element is available as the relatedTarget property of the event. Learn more about Events
so what is happening is every time you open a modal this event triggers and makes an ajax call which you see like this $.ajax({ wchi has 2 options set
A pre-request callback function beforeSend
A function to be called when the request finishes complete
so whenever the modal triggeres the ajax requet is made and every time ajax request i made just before sending the request the modal html is overridden $('#myModal').html('<div class="rotatingElement"></div>').show(); and a loader is added in form of a div element with class rotatingElement and as soon as the requet completes that loader is removed via complete function $('#myModal').html.hide(); and then the e.relatedTarget property as described above gets the anchor object and the href of that anchor .../remoteContent.php is loaded in side the modal body in the following 2 steps
var link = $(e.relatedTarget);
$(this).find(".modal-body").load(link.attr("href"));

Related

Stop Safari extension from caching messages

I'm having problems with creating a safari extension that has been causing me headaches.
The problem is this: I have created an extension that gets images from a web page using an injected script. I have a function in the popover that displays the web images and allows the user to click and send the selected image to a backend. This all goes through the global page which handles signals and messages. The scenario is this:
When the popover opens, it sends a signal to the global page to initiate the response (image URLs) from the injected script.
When the global page gets the message from the injected script, it calls the function in the popover passing in the data from the injected script as an argument.
The popover shows all images returned from the global page via the injected script.
The problem is that every time I open the popover, it appends the images from the last call instead of giving a fresh list of images. For instance, on first popover open, I get one image (assuming the page has only one image). If I close the popover and open it again, I get two of the same image. If I close and open the popover a third time, it appends the first image with the one from the second time and gives me 3 of the same image. On the fourth open of the popover I get 1 + 1 + 1 + 1, so 4 images. So it seems to be appending the messages and not giving me a fresh message every time.
My question is: how can I destroy the messages that are being cached after each popover closes? I hope I am being clear. Perhaps something else is happening with my code that I am not aware of. Please help if you can. Here is my code from the global HTML:
function popoverHandler(event) {
//check for popover opening
if (event.target.identifier === "MyPopUp") {
//send message to injected script to send page info
safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("getContent", '', false);
//this works fine, I get this message every time popover opens
console.log('getContent message sent');
//listen for message containing page info from injected script
safari.application.addEventListener('message', function (messageEvent) {
//only get message from current tab
if (messageEvent.name === "pageInfo" && messageEvent.message.url === safari.application.activeBrowserWindow.activeTab.url) {
pageInfo = messageEvent.message;
//the problem seems to be in here. Every time I open the popover, //I get the current page info plus all the page info messages from //the previous time I open the pover, all duplicates of the previous //messges
console.log(pageInfo);
// call a function in the popover, passing the pageInfo data //received from the injected script
safari.extension.popovers[0].contentWindow.onPageDetailsReceived(pageInfo);
}
});
}
}
Ok, so I was able to solve the problem. First of all, I separated the popoverHandler from the eventListener. For some reason, it was firing the function too many times and returning several lists of the same images. The major issue, however, was that in the popover.js, I was storing the list of images as a var. When I removed the var, the data stopped persisting and I was getting a fresh list every time.

Added data disappear

jQuery Core 3.1.0
Chrome, Firefox
Below is a model of jquery.ajax() success behaviour.
Shortly: I managed to fetch data via AJAX. In this model example the data is represented by "Just something" placeholder. Now I want to add the data to the document.
<script>
var add_date = $("#add_date");
function add_date_ajax(){
$('.frame_date').append("Just something");
debugger; // 1
}
debugger; // 2
add_date.click(add_date_ajax);
</script>
A problem: the data appear and then disappear in half a second.
I placed breakpoints.
When the page is loading, it stops at breakpoint 2. That is correct.
When I click #add_date element, the script stops at breakpoint 1. That is also correct.
But when I click "resume script execution", the script again goes to breakpoint 2. This seem strange to me. As if the page is reloaded. Maybe that is why the added text disappears.
Could you help me cope with the problem?
Added later:
https://jsfiddle.net/mv1yu3zw/1/
It disappears because you are reloading the page. The html
Add date
should be
Add date
To bind all your events, you should use the ready on document.
To avoid the reloading of your page (because of the href of the a tag), you have to call preventDefault or use a button.
You should write your code like this:
$(document).ready(function() {
$("#add_date").on("click", add_date_ajax);
});
function add_date_ajax(event) {
event.preventDefault();
$('.frame_date').append("Just something");
}

How to get shown.bs.modal to trigger when the modal uses a remote URL

The Problem
I cannot get shown.bs.modal to fire correctly when my modal is generated by passing in a remote url.
In the following code the hidden.bs.modal consistently work.
The Code
$('#my_modal').on("shown.bs.modal", set_up_modal);
$('#my_modal').on("hidden.bs.modal", tear_down_modal);
$('#my_modal').modal({ remote: target_url });
set_up_modal = function() { console.log('up') };
tear_down_modal = function() { console.log('down') };
What I have tried
I have read the docs.
I have tried changing my .on to read more like $('body').on("shown.bs.modal", '#my_modal', saa.set_up_modal); but this has produced no change (again hidden.bs.modal works).
Update
I have added console.log($._data( $('#my_modal')[0], "events" )); and can confirm that shown is being bound to the object, just not getting called.
I have tried using show.bs.modal instead, this works but I need the elements to be visible on screen for what I want to do to them.
Found a temporary solution from a pull request here https://github.com/twbs/bootstrap/commit/4b1a6e11326fee97a5ebc194be040086f40f97fb
Editing line 81 of the modal.js file as per below has fixed the issue for me until the pull request is made
- that.$element.find('.modal-dialog') // wait for modal to slide in
+ that.$element // wait for modal to slide in

Executing javascript functions in loaded tab in YUI

I have a tabset that loads an edit page into a tab on the details page of a user edit. I create the tabs dynamically and they are loaded from the server when the tab is clicked.
I have javascript code that needs to run when this tab is loaded so that calendar and autocomplete controls are available.
How can I ensure that the javascript existing in the imported html is loaded? Is this possible to do.
I have tried various events on the tab such as beforeDataLoadedChange and contentChange but to no avail.
if you want an event to fire when you click on a tab you can use activeTabChange event , check this example http://jsfiddle.net/ekcgd/.
However for an event that gets fired if data or contents inside a tab is loaded you may try using loadHandler which is called when a request to pull your data from server has success or failure.
this.loadHandler = {
success: function(o) {
this.set(CONTENT, o.responseText);
},
failure: function(o) {
}
};
modify this default loadHandler to fire a custom event on success and subscribe to that event so that you can run js code that you need .

jQuery code repeating problem

I have a piece of code in jQuery that I use to get the contents of an iFrame after you click a link and once the content is completed loading. It works, but I have a problem with it repeating - at least I think that is what it is doing, but I can't figure out why or how.
jQuery JS:
$(".pageSaveButton").bind("click",function(){
var theID = $(this).attr("rel");
$("#fileuploadframe").load(function(){
var response = $("#fileuploadframe").contents().find("html").html();
$.post("siteCreator.script.php",
{action:"savePage",html:response, id: theID},
function(data){
alert(data);
});
});
});
HTML Links ( one of many ):
<a href="templates/1000/files/index.php?pg=0&preview=false"
target="fileuploadframe" class="pageSaveButton" rel="0">Home</a>
So when you click the link, the page that is linked to is opened into the iframe, then the JS fires and waits for the content to finish loading and then grabs the iframe's content and sends it to a PHP script to save to a file. I have a problem where when you click multiple links in a row to save multiple files, the content of all the previous files are overwritten with the current file you have clicked on. I have checked my PHP and am pretty positive the fault is with the JS.
I have noticed that - since I have the PHP's return value alerted - that I get multiple alert boxes. If it is the first link you have clicked on since the main page loaded - then it is fine, but when you click on a second link you get the alert for each of the previous pages you clicked on in addition to the expected alert for the current page.
I hope I have explained well, please let me know if I need to explain better - I really need help resolving this. :) (and if you think the php script is relevant, I can post it - but it only prints out the $_POST variables to let me know what page info is being sent for debugging purposes.)
Thanks ahead of time,
Key
From jQuery .load() documentation I think you need to change your script to:
$(".pageSaveButton").bind("click",function(){
var theID = $(this).attr("rel");
var lnk = $(this).attr("href");//LINK TO LOAD
$("#fileuploadframe").load(lnk,
function(){
//EXECUTE AFTER LOAD IS COMPLETE
var response = $("#fileuploadframe").contents().find("html").html();
$.post("siteCreator.script.php",
{
action:"savePage",
html:response,
id: theID
},
function(data){alert(data);}
);
});
});
As for the multiple responses, you can use something like blockui to disable any further clicks till the .post call returns.
This is because the line
$("#fileuploadframe").load(function(){
Gets executed every time you press a link. Only add the loadhandler to the iframe on document.ready.
If a user has the ability via your UI to click multiple links that trigger this function, then you are going to run into this problem no matter what since you use the single iframe. I would suggest creating an iframe per save process, that why the rendering of one will not affect the other.

Categories

Resources