I am trying to use jQupload to upload an image asynchronously. The script uses an iframe off of the page to upload and then catches the .load() event of the iframe to return the JSON message that is returned.
If I display the form at the bottom of a standard HTML page and include the javascript then it works fine. However, I would like to load the upload form into a modal window and I am using facebox for this. The form is therefore included with the style tag set to "display:none" at the bottom of the page and it displays in the modal window when a specific button is clicked.
Within the modal window, the form submit's without a problem and the iframe is populated, however the code the form's submit event is not being caught by the javascript. I have tried alerting a simple string in the function but I get no result. However, if I alert out a string using the "onsubmit" tag of the form then it works ok.
The following line of code executes ok and adds a target attr to the form:
$(this).attr("target",data.iframe);
This is the next line of code that is not firing within the modal window:
$(this).submit(function(){
alert('hello!');
$("#"+data.iframe).load(function(){
var data1=$("#"+data.iframe).contents().find("body").html();
data1='{"formid":{"value":"'+id+'"},'+data1.substr(1);
if($.jQupload.callback[id]){
eval($.jQupload.callback[id]+"('"+data1+"')")
}
else{
if($.jQupload.output[id]){
$.jQupload.jsonMessage(data1)
}
else{
$.jQupload.defaultMessage(data1)
}
}
$("#"+data.iframe).contents().find("body").html("");
$("#"+data.iframe).unbind("load")
})
});
This code comes from within the jQupload functions which are called using the following 2 lines:
$("#image_upload_form").jqupload();
$("#image_upload_form").jqupload_form();
This is the full jQupload code and is being used as described at http://jqframework.com/jqupload_doc.html :
/* jQupload - jQuery Upload v0.1
* jQupload is distributed under the terms of the MIT license
* For more information visit http://jqframework.com/jqupload
* Copyright (C) 2010 jqframework.com
* Do not remove this copyright message
*/
$.jQupload = {
fadeOutTime:3000,
callback:{},
output:{},
init: function(id,obj){
if(obj.callback){
$.jQupload.callback[id]=obj.callback
}
if(obj.output){
$.jQupload.output[id]=obj.output
}
if(obj.fadeOutTime){
$.jQupload.fadeOutTime=obj.fadeOutTime
}
},
defaultMessage:function(data){
alert(data)
},
jsonMessage:function(data){
eval("data="+data);
$("#"+$.jQupload.output[data.formid.value]).html(data.message).fadeOut($.jQupload.fadeOutTime)
}
};
$.fn.extend({
jqupload:function(obj){
return this.each(function(){
var id=this.id;
if(typeof this.id=="object"){
id=$(this).attr("id")
}
if(!obj)
obj={};
$.jQupload.init(id,obj)
})
},
jqupload_form:function(){
return this.each(function(){
var id=this.id;
if(typeof this.id=="object"){
id=$(this).attr("id")
}
var data=$.extend(
{},
{iframe:id+"_iframe"},
data
);
$("body").append("<iframe name="+data.iframe+' id="'+data.iframe+'"></iframe>');
//$("#"+data.iframe).css({position:"absolute",left:"-1000px",top:"-1000px",width:"0px",height:"0px"});
$("#"+data.iframe).css({position:"absolute",left:"0px",top:"0px",width:"500px",height:"500px"});
$(this).attr("target",data.iframe);
$(this).submit(function(){
$("#"+data.iframe).load(function(){
var data1=$("#"+data.iframe).contents().find("body").html();
data1='{"formid":{"value":"'+id+'"},'+data1.substr(1);
if($.jQupload.callback[id]){
eval($.jQupload.callback[id]+"('"+data1+"')")
}
else{
if($.jQupload.output[id]){
}
$.jQupload.jsonMessage(data1)
else{
$.jQupload.defaultMessage(data1)
}
}
$("#"+data.iframe).contents().find("body").html("");
$("#"+data.iframe).unbind("load")
})
});
return true
})
}
});
Any ideas?
Matt, I believe the problem is the selector you're using not actually rigging anything up to the form:
$(this).submit(function() {...
only works in a certain context, it should be this to work everywhere:
$("#myFormId").submit(function() {....
Related
I use a jQuery window libray https://github.com/humaan/Modaal
which triggers events this way $("class of element").modaal({arg1, arg2,...});
--- I updated my question here to make it more general and used an iframe / Html instead of an external svg ---
To trigger an element e.g. in an external Html which is loaded within an iframe, I applied the following code to the iframe:
<iframe src="External.html" id="mainContent" onload="access()"></iframe>
which calls this function:
function access() {
var html = document.getElementById("mainContent").contentDocument.getElementById("IDofDIVelement");
html.addEventListener('click', function() {clicker();});
}
function clicker()
{
// console.log('hooray!');
$("#mainContent").contents().find("IDofDIVelement").modaal({});
//return false;
}
Actually it will only work on every second click. Any idea what I did not consider properly?
Best
You do not need to wait windows loading but iframe only:
$(function() {
$("#mainContent").bind("load",function(){
var myIframeElement = $(this).contents().find(".modaal");
myIframeElement.modaal({
content_source: '#iframe-content',
type: 'inline',
});
});
});
The reason why it did not work was that the iframe was not completely loaded, while jQuery tried to attach the function. As $(document).ready(function(){} did not work, the workaround was to initialize it with
$( window ).on( "load",function() {
$("#mainContent").contents().find("IDofDIVelement").modaal({});
});
This worked properly to attach the functionallity to an element within the iframe.
Actually modaal will vanish the envent handler after the overlay was opened and closed again.
So maybe someone wants to trigger an iframe element for modaal, too, here is a setup which would solve this issue.
(It can be optimised by #SvenLiivaks answer):
$(window).on("load", function() {
reload();
});
function reload() {
var length = $("#iframeID").contents().find("#IDofDIVelement").length;
// The following check will return 1, as the iframe exists.
if (length == 0) {
setTimeout(function() { reload() }, 500);
} else {
$("#iframeID").contents().find("#IDofDIVelement").modaal({
content_source: '#modalwrapper',
overlay_close: true,
after_close: function reattach() {
reload();
}
});
}
}
Im using ContentTools and everything works as expected when using the standard Ignition. However when I instead of using the Blue button add my own to Start editing/Save and Discard changes the Editor is unable to reactivate. This means that the user can Edit, then Save once. All subsequent attempts at reactivation fail silently.
Init code:
window.addEventListener('load', function() {
editor = ContentTools.EditorApp.get();
editor.init('.editable', 'id');
ContentTools.IMAGE_UPLOADER = imageUploader;
$('#btnStartEdit').click(function() {
editor.start();
$(this).hide();
$('#btnSaveChanges').fadeIn();
$('#btnDiscardChanges').fadeIn();
});
$('#btnSaveChanges').click(function() {
editor.save();
$('#btnStartEdit').fadeIn();
$('#btnSaveChanges').fadeOut();
$('#btnDiscardChanges').fadeOut();
});
$('#btnDiscardChanges').click(function() {
editor.revert();
$('#btnStartEdit').fadeIn();
$('#btnSaveChanges').fadeOut();
$('#btnDiscardChanges').fadeOut();
});
ContentTools.EditorApp.get()._ignition.unmount();
});
Instead of using the save() and revert() methods directly I recommend you use stop(true) for save and stop(false) for cancel/revert.
The save and revert methods don't stop the editor (for example save(true) can be used to auto-save content while the user continues to edit). Using stop should allow you to restart the editor, e.g:
window.addEventListener('load', function() {
editor = ContentTools.EditorApp.get();
editor.init('.editable', 'id');
ContentTools.IMAGE_UPLOADER = imageUploader;
$('#btnStartEdit').click(function() {
editor.start();
$(this).hide();
$('#btnSaveChanges').fadeIn();
$('#btnDiscardChanges').fadeIn();
});
$('#btnSaveChanges').click(function() {
editor.stop(true);
$('#btnStartEdit').fadeIn();
$('#btnSaveChanges').fadeOut();
$('#btnDiscardChanges').fadeOut();
});
$('#btnDiscardChanges').click(function() {
editor.stop(false);
$('#btnStartEdit').fadeIn();
$('#btnSaveChanges').fadeOut();
$('#btnDiscardChanges').fadeOut();
});
ContentTools.EditorApp.get()._ignition.unmount();
});
I m creating a Dialog box in my javascript using Alertify library,
alertify.myAlert || alertify.dialog('myAlert',function factory(){
return {
main:function(content){
this.setContent(content);
},
setup:function(){
return {
options:{
modal:false,
basic:true,
maximizable:false,
resizable:false,
padding:false,
visible:false
}
};
},
hooks: {
onshow: function() {
this.elements.dialog.style.height = '50%';
this.elements.dialog.style.width = '15%';
}
}
};
});
And, invoking it using below code..
alertify.myAlert("my html content");
Once it is launched, how can I close it ?
I tried diff combinations like alertify.myAlert.close(), alertify.myAlert.hide() but nothing worked..
try this :-
alertify.alert().destroy();
#Nero, #MK : Thank you.
close() and then show() did the job. They retain the state of dialog.
2 more questions,
Can we refer an external HTML file inside alertify.dialog() implementation. Currently am using below code, which takes the html code and builds dialog content.
alertify.myAlert('MY HTML Content');
It looks dirty to have all html code in here. Do we have any option to specify path to html file?
How to set the visibility of Dialog to false intially. I tried setting visibility:hidden, show:false, hide:true etc in options but didn work.
you can use the same class by applying the remove
$('.alertify').remove();
How can I put HTML in custom JavaScript message box? I have an HTML file and I want to load its content (not its code) in a message box. In front of my var I can write HTML code and it works good, but I want to load HTML with a lot of code in a separate file. Here is my JS code:
var showreadylist = function(element) {
var div = //any code that i could load my html here ! ;
div.click(function(event) {
$(".vote-notification").fadeOut("fast", function() { $(this).remove(); });
});
var where = where || 'parent';
if (where == 'parent'){
element.parent().append(div);
}
else {
element.after(div);
}
div.fadeIn("fast");
};
I am assuming you are able to use your custom js box as mentioned in description,
I am just providing you option to get data from html via ajax and append to your target div.
I am not sure about click event handler, but you need to handle in this way, this is just example code provided by you.
Sample code is as below
var showreadylist = function(element) {
var div = //any code that i could load my html here ! ;
$.get("htmlfile", function(data){
div = data;
div.click(function(event) {
$(".vote-notification").fadeOut("fast", function() { $(this).remove(); });
});
var where = where || 'parent';
if (where == 'parent'){
element.parent().append(div);
}
else {
element.after(div);
}
div.fadeIn("fast");
});
};
Alternatively you could use bootstrap modals
http://getbootstrap.com/javascript/#modals
Or JQuery Ui's dialog box
http://jqueryui.com/dialog
I'm using RequireJS to structure my JS and DJAX (basically PJAX) as a way to dynamically load content without a full page reload.
The issue I have is that after DJAX has finished loading the content I need to rerun my scripts (e.g. a script that adds multiple images into a carousel) so that the new page renders correctly. I thought the best way to do this would be to simply rerun the function I'm running on $(document).ready(); but I'm getting this output in the console:
Uncaught TypeError: Cannot read property 'djaxLoad' of undefined
which is referring to this line in load-posts.js
bootstrap.init();
I'm guessing I'm writing something incorrectly.
Here is bootstrap.js which is my main file which fires on document.ready and initialises all my modules
require(['base/responsive', 'base/main-menu', 'base/social-share', 'base/randomise-colours', 'base/infinite-scroll', 'base/load-posts', 'base/image-fade', 'base/carousel', 'base/misc'],
function(responsive, main_menu, social_share, randomise_colours, infinite_scroll, load_posts, image_fade, carousel, misc) {
var $ = jQuery;
function djaxLoad() {
//If page has JS (detected with Modernizr) then hide content until the
//doc is ready to avoid flash of unstyled content
$('#djax-container').css('display', 'block');
main_menu.init();
social_share.init();
randomise_colours.init();
load_posts.init();
image_fade.init();
infinite_scroll.init();
carousel.init();
misc.init();
responsive.init();
}
$(document).ready(djaxLoad);
}
);
And this is load-posts.js which handles DJAX for me. DJAX works, I just need to get the scripts to fire again.
define(['djax', 'base/bootstrap'], function(djax, bootstrap) {
var $ = jQuery,
$body = $('body');
return {
init: function() {
if($body.length >= 1) {
this.setUp();
} else {
return false;
}
},
setUp: function() {
this.pjaxLinks();
},
pjaxLinks: function() {
//Initialise DJAX, but stop it from running on pagination links (URL is /page...)
$('body').djax('.updateable', ['page']);
//When clicking a djax link
$(window).bind('djaxClick', $.proxy(function() {
this.addLoader();
},this));
//When the new content has loaded in
$(window).bind('djaxLoad', $.proxy(function() {
this.removeLoader();
},this));
},
addLoader: function() {
$body.addClass('loader-visible');
},
removeLoader: function() {
$body.removeClass('menu-visible');
$('html, body').scrollTop(0);
function removeLoaderDelay() {
$body.removeClass('loader-visible');
bootstrap.djaxLoad();
}
setTimeout(removeLoaderDelay, 1000);
}
};
});
The djaxClick function runs on a link click, and the djaxLoad function runs after the content has been loaded in. I'm adding a loader overlay to the page, then removing it after the content has loaded in.
A bit late but for future reference: In the documentation at https://github.com/beezee/djax you'll find the djaxLoad-event. This is specifically made for your usecase. You can use it as follows:
$(window).bind('djaxLoad', function(e, data) {
// your scripts to run on ajax-calls
});
The site further explains: "the data object passed with the event contains the requested url, the page title for the requested page, and the contents of the requested page as a string".
$(window).bind('djaxLoad', function(e, data) {
var responseObj = $('<div>'+data.response+'</div>');
//do stuff here
});