I'm trying to call EasyUI's draggable everytime I dynamically create new HTML elements. I have the draggable method enclosed like so:
function initializedrag() {
console.log("initializedrag called")
$(".item").draggable({
revert:true,
proxy:'clone',
onStartDrag:function(){
$(this).draggable('options').cursor = "not-allowed";
$(this).draggable('proxy').css('z-index',3);
},
onStopDrag:function(){
$(this).draggable('options').cursor="move";
}
});
console.log("end of initializedrag")
}
And I use load to load in a new html site that contains a div with some li items and a tags that have a class of .item, like so, when the page is ready:
$(function() {
console.log("ready");
$("#shop").load("shopcontent/cat1.html");
initializedrag();
...
});
Through the console.logs, it's calling the function fine, however, the drag functionality isn't actually working. The exact same draggable works when I have a element that is already on the page, and draggable on page load. However, I need it to work whenever I call the initializedrag function.
What's going on here?
FIXED!
It was quite simple really, I just enclosed the initializedrag() in a function that gets called when the content is loaded!
So instead of:
$("#shop").load("shopcontent/cat1.html");
initializedrag();
I did:
$("#shop").load("shopcontent/cat1.html", function() {
initializedrag();
});
Which is odd because I put the contents of initializedrag() in a function just like above yesterday, but it didn't work :)
Related
I need to exclude some divs (one or several) from the page that I .load() from the same domain to modal, I use this to load pages:
$(document).ready( function() {
$("#div-id-where-to-load-page").load("loaded-page-url");});
I tried something like this:
$(document).ready( function() {
$("#div-id-where-to-load-page").load("loaded-page-url").remove(#div-id-to-remove);});
and its not working, if I break it to separate functions it doesn't work either, I am new to JS, what am I doing wrong?
All scripts are loaded from the separate file (if it is important).
You can have a callback function on the .load() method. This way you guarantee that the elements you want to remove are already loaded to the DOM when you call the .remove().
$(document).ready( function() {
$("#div-id-where-to-load-page")
.load("loaded-page-url", function() {
$('#div-id-to-remove').remove();
});
});
I load a part of my basketpage inside an accordion div in my header. This works great and shows my basket in a nice dropdown.
The last problem I need to solve with this is to get the buttons in the loaded content to work. Is it possible to write an callback that make these works? Im not sure even what to google for this one..
This is how the buttons is setup in the loaded content:
checkout
Script Im using to load the content:
$('.dcjqg-accordion ul.sub-menu').load('/m4n?seid=etailer-basket div#centerbox.itembox.centerbox');
use the callback function of .load().
$('.dcjqg-accordion ul.sub-menu').load('/m4n?seid=etailer-basket div#centerbox.itembox.centerbox', function() {
$("#_ec_oie2").on("click", function() {
if (UI.pb_boolean(this, 'click')) { }
return false;
});
});
checkout
You need to use a child selector for the event. You can attach an event to the .sub-menu element that will fire on the content loaded in through the ajax. Something like the following could work:
$(".dcjqg-accordion ul.sub-menu").on("click", ".action.actionbasket.checkout", function() {
if( UI.pb_boolean(this, 'click') ) {}
return false;
});
Notice the second parameter to the on method. It is a selector that will be used to look at the target of the click event. I used .action.actionbasket.checkout since that is what is on your a tag.
This code may not work exactly, but this should help get you in the right direction.
Here is the link to the jQuery documentation for the on method: https://api.jquery.com/on/
I have the following in my javascript file:
var divId = "divIDer";
jQuery(divId).ready(function() {
createGrid(); //Adds a grid to the html
});
The html looks something like:
<div id="divIDer"><div>
But sometimes my createGrid() function gets called before my divIder is actually loaded onto the page. So then when I try to render my grid it can't find the proper div to point to and doesn't ever render. How can I call a function after my div is completely ready to be used?
Edit:
I'm loading in the div using Extjs:
var tpl = new Ext.XTemplate(
'<div id="{divId}"></div>');
tpl.apply({
});
You can use recursion here to do this. For example:
jQuery(document).ready(checkContainer);
function checkContainer () {
if($('#divIDer').is(':visible'))){ //if the container is visible on the page
createGrid(); //Adds a grid to the html
} else {
setTimeout(checkContainer, 50); //wait 50 ms, then try again
}
}
Basically, this function will check to make sure that the element exists and is visible. If it is, it will run your createGrid() function. If not, it will wait 50ms and try again.
Note:: Ideally, you would just use the callback function of your AJAX call to know when the container was appended, but this is a brute force, standalone approach. :)
Thus far, the only way to "listen" on DOM events, like inserting or modifying Elements, was to use the such called Mutation Events. For instance
document.body.addEventListener('DOMNodeInserted', function( event ) {
console.log('whoot! a new Element was inserted, see my event object for details!');
}, false);
Further reading on that: MDN
The Problem with Mutation Events was (is) they never really made their way into any official spec because of inconcistencies and stuff. After a while, this events were implemented in all modern browser, but they were declared as deprecated, in other words
you don't want to use them.
The official replacement for the Mutation Events is the MutationObserver() object.
Further reading on that: MDN
The syntax at present looks like
var observer = new MutationObserver(function( mutations ) {
mutations.forEach(function( mutation ) {
console.log( mutation.type );
});
});
var config = { childList: true };
observer.observe( document.body, config );
At this time, the API has been implemented in newer Firefox, Chrome and Safari versions. I'm not sure about IE and Opera. So the tradeoff here is definitely that you can only target for topnotch browsers.
To do something after certain div load from function .load().
I think this exactly what you need:
$('#divIDer').load(document.URL + ' #divIDer',function() {
// call here what you want .....
//example
$('#mydata').show();
});
Through jQuery.ready function you can specify function that's executed when DOM is loaded.
Whole DOM, not any div you want.
So, you should use ready in a bit different way
$.ready(function() {
createGrid();
});
This is in case when you dont use AJAX to load your div
inside your <div></div> element you can call the $(document).ready(function(){}); execute a command, something like
<div id="div1">
<script>
$(document).ready(function(){
//do something
});
</script>
</div>
and you can do the same to other divs that you have.
this was suitable if you loading your div via partial view
I am trying to use jquery to load a dojo chart. I am using this code. However in the second click, in the first button i get this error. The same occurs if i click in the first button, click in the second and click again in the first. This problem is Driving me crazy.
demo here
<script type="text/javascript">
$(document).ready(function () {
$('.lista_').click(function () {
$.get('index1.php', function (data) {
dojo.addOnLoad(function () {
require(["dojo/_base/xhr", "dojo/parser", "dojo/dom"], function (xhr, parser, dom) {
var um = [];
dijit.registry.filter(function (w) { //problem here, maybe this code destroy something that should not be destroyed
if (dojo.indexOf(um)) {
w.destroyRecursive();
}
});
$('#paginas').html(data);
dojo.parser.parse(dojo.byId('paginas'));
});
});
});
});
});
</script>
It looks like you are trying to remove the old chart before inserting/parsing the new one, but I don't think that is happening. This may cause Dojo to barf up various errors.
dijit.registry.filter(function (w) { //problem here, maybe this code destroy something that should not be destroyed
if (dojo.indexOf(um)) {
w.destroyRecursive();
}
});
I'm not sure what you are doing here. The filter function will return an array of widget's for which the callback returns true. Additionally, dojo.indexOf is used to search for an element in an array (I'm not sure what sort of black magic you are doing with it there :P).
I think (if I've understood your intentions), you should rather do:
dijit.registry.findWidgets(dojo.byId("paginas")).forEach(function(w) {
w.destroy();
});
This will destroy the widget(s) inside #paginas before inserting and parsing the newly fetched HTML.
Edit: When you click the 2nd button, and the chart is removed, the <style> tag is removed too. That's why you see artifacts from the tooltip div, because it's no longer hidden by CSS. You can solve this by having the claro.css import in the main file, i.e. put this:
<style type="text/css">
#import "http://ajax.googleapis.com/ajax/libs/dojo/1.7/dijit/themes/claro/claro.css";
</style>
in the main file's header instead of in the HTML you load with jquery (index1.php).
I'm using Phonegap to build a small (test only) Macrumors application, and remote hosts actually work (there is no same host browser restrictions). I am using the jQuery Load() function to load the contents of the Macrumors homepage http://www.macrumors.com/ into a bin, hidden div, then the each function to loop through all the article classes to show the title in a box with a link to the page.
The problem is, after the Macrumors HTML content is loaded, the each function doesn't work with the article class. Also, in the load function (which allows you to specify certain selectors, id's and classes included, to only load in those sections of the page) the class doesn't work; none of the classes do, in both the load function and each function. And many Id's don't work in the each function either.
Can anybody explain this to a noob like me?
Here is the code:
function onDeviceReady()
{
// do your thing!
$('#bin').load('http://www.macrumors.com/ #content');
$('.article').each(function(){
var title = $('a').html();
$('#content').append('<b>'+title+'</b>')
});
}
And the HTML stuff
<body onload="onBodyLoad()">
<div id="bin">
</div>
<div id="content">
</div>
</body>
I sincerely apologize if there's some very simple mistake here that I'm missing; I'm a major JS newbie.
.load() is asychronous. It hasn't completed yet when you're executing .each(). You need to put your .each() and any other code that wants to operate on the results of the .load() in the success handler for .load().
You would do that like this:
function onDeviceReady()
{
// do your thing!
$('#bin').load('http://www.macrumors.com/ #content', function() {
$('.article').each(function(){
var title = $('a').html();
$('#content').append('<b>'+title+'</b>')
});
});
}
I'm also guessing that your .each() function isn't working quite right. If you want to get the link out of each .article object, you would need your code to be like this so that you're only finding the <a> tag in each .article object, not all <a> tags in the whole document:
function onDeviceReady()
{
// do your thing!
$('#bin').load('http://www.macrumors.com/ #content', function() {
$('.article').each(function(){
var title = $(this).find('a').html();
$('#content').append('<b>'+title+'</b>')
});
});
}