How can I reuse a cloned element? - javascript

I have a Bootstrap modal on my page. Basically, what happens is the user picks some options on the page, clicks a go button and that modal pops up and gets populated with the live output of the job they started.
After the job runs, I'd like for the user to be able to close the modal, choose more options, and run the job again. The problem is, I can't seem to get rid of the output from the previous job.
I tried this answer, which was to clone the div and use replaceWith() to restore the content to it's original state. This works for the first two times (job runs once, then when you start another the modal is back to it's original state), but for any time after that, the modal pops up with the content of the previous run until it's text gets overridden.
I have this at the beginning, to capture the contents before anything is done:
$(document).ready(function() {
modalHold = $("#postModal").clone();
});
And, this runs when the modal closes:
$('#postModal').on('hidden.bs.modal', function (){
$("#postModal").replaceWith(modalHold.clone());
})
I would've expected the replaceWith(modalHold.clone()) to replace it with a new clone of the original element, however it seems that I'm still modifying the original. Any help would be appreciated, or if there's a better way of doing this I'd be glad to hear it.

Bootstrap does some javascript magic with the Modal, so I guess you can't just clone whole the Modal's HTML. As a workaround you may try to play with class="modal-body" node only, clone and replace it.
But the truth is on another way. You need to implement a function which would reset your inputs and call it each time the Modal is being hidden.
var modalDefault = {
input1: '',
input2: 'Hello!'
};
var resetModal = function() {
$('#modalInput1').val(modalDefault.input1);
$('#modalInput2').val(modalDefault.input2);
}
// ...
$('#postModal').on('hidden.bs.modal', resetModal);

Not sure why I didn't think of this to begin with, but dhilt's answer helped point me in the right direction. The idea of creating defaults and just switching back to those could be helpful in some cases, but I had some content (including job info and a loading bar) inside the modal that I'd really like to be displayed each time a job starts, until it is done and the output can be displayed.
Instead of doing any fancy cloning, I placed that content into a div and just grabbed its innerHTML:
$(document).ready(function() {
modalHold = $('#jobOutputHolder').html();
});
When the .load () runs, it will update #jobOutputHolder with the output of the job. Then, on hide of the modal:
$('#postModal').on('hidden.bs.modal', function (){
$('#jobOutputHolder').html(modalHold);
})
With this method, I can run a job, see the loading screen, see the job output, close the modal, and repeat as many times as I need without ever seeing the output of previous jobs.

Related

Content hide/show

my goal is to hide the content of my homepage when someone visits. onClick to begin button the content should be shown. Content should stay open when user goes to other page and comes back to homepage. But it will be hidden when user closes the window and opens up the homepage again. To achieve this goal I have put the following code but it keeps the content open even when user closes and opens the window. So please help me out.
if (! localStorage.noFirstVisit) {
// hide the element
$("#content").hide();
// check this flag for escaping this if block next time
localStorage.noFirstVisit = "1";
}
Another issue is when the content shows the design gets little messed up(by widening the divs, bringing horizontal scroll)
$(".roll-button").click(function(){
$("#content").show();
});
I would highly appreciate if you check website, suggest me fix or show me proper way to achieve this goal. url:iamicongroup.com
You can totally use sessionStorage to detect whether it is new tab(window) or not.
When you first visit this page, set sessionStorage.noFirstVisit = "1";.
After you go to another page and back, sessionStorage.noFirstVisit is still "1".
But when you close the tab or browser and open the page newly again, sessionStorage.noFirstVisit will be undefined.
Documentation is here
The documentation also provide the difference between sessionStorage and localStorage.
I would suggest reading this: Detect Close windows event by Jquery
It goes over window unloading (beforeunload), which I believe is what you're after. You can set/unset your localstorage values there based on certain criteria being met; for example:
$(window).on("beforeunload", function() {
if(localStorage.noFirstVisit = "1" {
// do something
localStorage.noFirstVisit = "[someValue]"
}
else {
// do something
localStorage.noFirstVisit = "1"
}
})
Another issue is when the content shows the design gets little messed up(by widening the divs, bringing horizontal scroll)
how about adding something like 'ng-cloak' in angular, to avoid the undesirable flicker effect caused by show/hide.
when clicking the roll-button, it prevents the divs from showing unfinished..

Element is Statement Combined With If Statment Not Responding Properly on Hover

Really need some JQuery help here. I'm about to launch my laptop out the window. I have come a long way with this piece of code an I think I am almost there but I am stuck on the last hurdle.
I am only going to include the pertinent pieces of code here because it is a very large piece.
I have a navigation menu for a mock solar system. Here is the link to the larger external piece if you want to see the whole thing. http://jsbin.com/zagiko/1/edit (please note this uses mostly CSS3).
I have a nav menu for the piece and when you click on the values in the nav menu the current script assigns a class of active. That all works perfectly. I built in a button to test the active state on click and the state changes are working. But I need it to respond to the state change on hover. I am not a JQuery person; I am learning. It almost seems like the hover isn't working because it is responding to the data loaded when the page loads instead of responding in real time. But I am just guessing.
What I need is an if statement that will respond to the live data (not on page load or when the document is ready). The if statement should basically say if this div is active then this other div can appear on hover. But if this div is not active then it cannot appear.
The current if statement I wrote is
if($("a.active").is('.uranus')){
$('#uranus .infos').hover(
function () {
$("#descriptionsp").fadeIn("2000");
})
};
The current script that runs when the site loads that sets up the menus is:
$(window).load(function(){
var e=$("body"),
t=$("#universe"),
n=$("#solar-system"),
r=function() {
e.removeClass("view-2D opening").addClass("view-3D").delay(2e3).queue(function() {
$(this).removeClass("hide-UI").addClass("set-speed");
$(this).dequeue()})
},
i=function(e){
t.removeClass().addClass(e)
};
$("#toggle-data").click(function(t){
e.toggleClass("data-open data-close");
t.preventDefault()
});
$("#toggle-controls").click(function(t){
e.toggleClass("controls-open controls-close");
t.preventDefault()
});
$("#data a").click(function(e){
var t=$(this).attr("class");
n.removeClass().addClass(t);
$(this).parent().find("a").removeClass("active");
$(this).addClass("active");
e.preventDefault()
});
Really need you help. Thanks in advance!
Right now, your block of code is only being checked when the javascript is loaded. At this time, the .uranus element is probably not active, so nothing will happen.
First of all, you want to move this block inside of document ready, otherwise your elements such as .uranus might not even exist yet.
Your logic is very close, but you need to move the if statement inside of the hover function like this:
$('#uranus .infos').hover(
function () {
if($("a.active").is('.uranus')){
$("#descriptionsp").fadeIn("2000");
}
});
This way, every time you hover on #uranus .infos, it will only execute the code if the .uranus is also .active

How to make jquery div replacement take effect instantly

I have a javascript function which creates an image dynamically, then shows that image either in a div or on a separate page.
Since the image creation takes a few seconds I'd like to display a simple 'please wait' message so that the user knows something is happening, and I am doing this by replacing the contents of an initially empty div with some text.
$('#chartImage').html('Please wait...');
This works fine on it's own - the div contents are displayed immediately when the triggering link is clicked. The problem is when I add the actual image creation code after it, the 'please wait' does not show up until after the image creation is complete, and only for a split second, so it's kinda pointless.
Is there something like a flush method to make sure all actions have taken effect before continuing?
Alternatively if there is a better way to do this I'm happy to hear it...
-------------EDIT-----------------
Here is a more complete description of what I'm doing, using open flash chart to make an image:
function createChartImage(chartid)
{
$('#chartImageDiv'+chartid).html('Please wait...');
ofc = findSWF("ofc_chart_"+chartid);
x = ofc.post_image( getUploadChartURL(chartid), 'doneChartUpload', false );
setTimeout("",1000); //allow some time for upload to complete
window.location.href = getViewChartImageURL(chartid);
}
The 'please wait' appears to take effect immediately before the final line. If I change the div's contents again at that point, the 'please wait' never shows at all.
(According to the docs for the charts I'm using, the function 'doneChartUpload' should be called when the upload is complete which would remove the need for the setTimeout, but I spent a long time trying to get it working, even copying code verbatim from the page below, to no avail.)
http://teethgrinder.co.uk/open-flash-chart-2/adv-upload-image.php
From assessing your code i would definitely split it up:
function generateChartImageProcess(chartid){
displayLoader();
createChart(chartid);
}
function createChart(chartID){
ofc = findSWF("ofc_chart_"+chartid);
x = ofc.post_image( getUploadChartURL(chartid), 'doneChartUpload', false );
setTimeout("",1000); //these two lines here to be replaced by your chart generations complete process
window.location.href = getViewChartImageURL(chartid);
}
function displayLoader(){
$('#chartImageDiv'+chartid).html('Please wait...');
}
function chartGeneratedComplete(arguments){
//TODO
}
This happens because the image isn't loaded yet, and it takes some time for the browser to load it before it can be displayed.
You could try using the jquery.load() method to add a callback for the event of the image being loaded like this, (supposing the div containing the image has the id #imageContainer):
$('#imageContainer img').load(function() {
// Remove the Please wait
});
BlockUI is a good tool to use for these situations: http://jquery.malsup.com/block/. In both cases (using BlockUI or rolling your own), trigger the "waiting" code first, run your image generator, and then remove the waiting effect after the image is loaded.

jQuery dialog - a unique dialog gets duplicated on an ajax site

I have a fully ajaxed website, which uses jQuery's $.get calls to fetch the central content of the website upon header clicks.
One of the "screens" (views, actually, using Zend) has a hidden div which is "dialoged" when a user clicks a certain button. This is what happens to me:
I get to the desired screen, and click the open dialog button.
Dialog opens fine. Closing and reopening works as expected.
I go to another screen (mind you, this is ajax, which simply replaces the main content with new content - the hidden div is inside this content, however, and gets replaced along with the main content)
I come back to the previous screen (still ajaxing), and click the open dialog button again. Now all of a sudden, there are two of those hidden divs, both with the identical ID (I can see that if I do a console.log($("div#hiddenDiv").length); ) and they are both spawned in dialog form - I have them on top of each other.
The dialogs get duplicated for as many times as I redo this. If I go to another screen, come back, and open dialog again - I get 3, etc.
I took a lot of precautions - I empty the memory at every ajax click, setting all variables I have nothing to do with anymore to null. I also take care to replace the entire content, the hidden divs as well, on every new ajax call, i.e. screen-transition. I checked and made sure that the function which summons the dialog isn't called more than once - it simply dupes the dialog upon returning to the screen which contains it by default, and I have no idea why. Mind you - no other element is duped. Only this hidden soon-to-be-dialog div.
Also worth noting is the fact that the duping process never begins until I open the dialog for the first time. From that moment on, every ajax [departure/return/dialog-opening]-scheme dupes the invisible div.
Does anyone have any idea why this is happening?
Edit: Code example:
// This causes the screen change when it detects a hash change
// ... stuff ...
if(window.location.hash){
ajaxData(newhash);
}
// ... stuff ...
// This causes the actual change of on-screen content (i.e. this is the ajax call)
function ajaxData(value) {
// ... stuff ...
$.ajax({
url: "/siteexample/"+value,
type: "GET",
mode: "abort",
dataType: type,
success: function(data){
$("#main_content").html(data); // the hidden div is always inside this "data", so it always gets removed when a new screen loads
loaderdisplay('hide');
// Clean Memory
data = null;
},
data: ({ajax : 'Y'})
});
// ... stuff ....
// And finally, this is the part that summons the dialog
function summonDialog() {
console.log("here"); // this shows up only once, so I know this function is not called multiple times.
var dialogBox = $("div#new_window"); // this is the infamous div
$(dialogBox).dialog({
modal: true,
title: "Some title",
resizable: false,
zIndex: 22000,
width: 800,
buttons: {
"Save": function(){
// some function, ends with:
$(dialogBox).dialog("close"); // destroy doesn't change anything
dialogBox = null;
},
Cancel: function(){
$(this).dialog("close"); // destroy doesn't change anything
dialogBox = null;
}
}
});
}
So the sequence of events is:
1. ajaxData to the location where the div is.
2. ajaxData away from it.
3. ajaxData back, and open dialog, everything fine.
4. ajaxData away from it.
5. ajaxData back and open dialog, duped.
Rinse and repeat, from now on they're getting duped.
Edit2:
I was able to temporarily hack this into a fix with this in the summonDialog function:
var dialogBox = $("div#new_window");
var usableDialog = dialogBox[0];
$(dialogBox).remove();
$(usableDialog).dialog({
// ... dialog code as usual ...
But I don't like the solution much. Marc's explanation makes sense, but since I have many different hidden divs with the potential to become dialogs scattered across many different views, removing each one in such a way would be tedious, since they tend to have different context-appropriate IDs and removing by "ui-dialog-content" class (which all divs get once they're dialog-opened) could produce some issues in other parts of the site, since it's a too general scope.
I believe the div that is the dialog will be attached and hidden on the body. Thus, when you replace the #main_content html, you're not really removing it. I would recommend removing the div and re-enabling the .dialog plugin on each html(data) reload.
Something like this:
success: function(data){
$("#new_window").remove();
$("#main_content").html(data);
loaderdisplay('hide');
summonDialog();
}
And easy way to test this is to simply console.log($("#new_window").length); when you get dupes.
I had exactly the same problem, The dialog was duplicated even after
$('.content').html('');
So I added this:
$("#divEditAdvice").remove();
That was the solution as #Marc mention above.

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