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).
Related
I am currently running a couple of jQuery scripts on the same page, this particular page has a product filter on it (using ajax). http://www.ctagroup.com.au/cta-group-home/products/selector/
One script i am using is this:
var $s = jQuery.noConflict();
$s('body').each(function () {
$s(this).html($s(this).html().replace(/(\®)/g, '<sup>®</sup>'));
});
So each ® is used accordingly site wide.
When a filter option is clicked it then returns without my script being run.
How can i get this script to run again everytime the ajax filter is used?
I don't know if you NEED that jQuery.noConflict();, I cannot see why you would really; but here is an example without it. NOTE I did NOT like the way you did it so, using your page I focused it a bit. You can modify that as you see fit targeting specific elements with selectors.
Put in a custom event handler somewhere called customFixReg
jQuery(document).on('customFixReg', function() {
jQuery('.sf-result').find('.prod-cont-selector').find('p')
.filter(':contains("®")').each(function() {
jQuery(this).html(jQuery(this).html()
.replace(/(\®)/g, '<sup>®</sup>'));
});
});
EDIT: Not liking the double selector this also works:
jQuery(document).on('customFixReg', function() {
jQuery('.sf-result').find('.prod-cont-selector').find('p')
.filter(':contains("®")').html(function(i, val) {
return val.replace(/(\®)/g, '<sup>®</sup>');
});
});
Then, when; where you need it, trigger it:
jQuery(document).trigger('customFixReg');
I grabbed some content and tested it here: https://jsfiddle.net/MarkSchultheiss/j787Ljzz/
Reference to comment, your page has THIS in consecutive lines on the page: SO it breaks based on the prior code. Line 789 on the page:
<script>
var $s = jQuery.noConflict();
$s('body').each(function () {
$s(this).html($s(this).html().replace(/(\®)/g, '<sup>®</sup>'));
});
</script>
<script>
jQuery(document).on('customFixReg', function() {
jQuery('ul.sf-result').find('.prod-cont-selector').find('h3,p')
.filter(':contains("®")').each(function() {
jQuery(this).html(jQuery(this).html()
.replace(/(\®)/g, '<sup>®</sup>'));
});
});
</script>
EDIT: I found a bug if the trigger recurred, it would double wrap so I filter those with a child <sup> element out.
jQuery(document).on('customFixReg', function() {
jQuery('.sf-result').find('.prod-cont-selector').find('p,h3').filter(':contains("®")')
.filter(function() {
return !$(this).children('sup').length;
})
.each(function() {
jQuery(this).html(function(i, val) {
return val.replace(/(\®)/g, '<sup>®</sup>');
});
});
});
Updated sample: https://jsfiddle.net/MarkSchultheiss/j787Ljzz/4/
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 :)
Let's say I have the following script
<script type="text/javascript">
$(function($, d) {
var custom = {
settings: { news: $('div.news') },
init: function() { this.settings.news.html('new'); }
}
}(jQuery, $(document)))
</script>
You can assume that the object has more functionality, but my question is where should I place it?
I know two approaches:
Place the script in the <head> tag. That way I will have to make sure the object is called only after document.ready, so the settings jQuery objects ($('div.news')) won't be empty.
The second way is less semantically correct in my opinion, but I can give up the document.ready function: I can just "physically" place the script after the html.
What solution would you prefer and why? Thanks from advance!
Any script that doesn't assist in rendering the layout of the page should be placed at the bottom of the body, preferrably as a reference to a script file (not the script itself). This allows the CSS + HTML to render the page visually, and then the JavaScript (or jQuery, in your case) is applied to the rendered elements.
It does not increase the performance of the page perse, but it does speed up the visual rendering, appearing to provide a faster experience for the end user.
See here for more details.
I place my code like this just before the closing body tag, and run init():
var custom: {
settings: { news: null },
init: function() {
this.settings.news = $('#news');
this.settings.news.html('new');
}
}
custom.init();
Something like that.
Edited to reflect Anthony's comment.
I use pie.js (http://css3pie.com/) a library that allows me to have css3 on ie6+. I apply pie.js on document.ready :
$(document).ready(function(){
if (window.PIE) {
$('.vexClass, #vexId').each(function(){
PIE.attach(this);
});
}
});
My problem is when the dom was modified the elements for which I have apply pie.js are not rendering well so I must load my function that apply pie.js to my elements when the dom is modified and only for section that was modified using OnSubtreeModified or another technique ... For example I have a panel that is displayed when dom was loaded, in that panel I have a button that is expanding another panel with buttons and other elements for which I want to apply pie.js, so for main panel all elements for which I have applied pie.js are rendered ok but the elements from expanded panel, pie.js is not applied :|
So how can I inject that pie.js when dom is modified for expanded panel?
Thank's.
If you are using wicket the only way to do that is through Wicket.Ajax.registerPostCallHandler
Add this in your project, every time when a ajax request is done your pie will be applied.
window.document.ready = function() {
Wicket.Ajax.registerPostCallHandler(pieStarter);
}
function pieStarter() {
if (window.PIE) {
go();
}
}
function go() {
$(''.vexClass, #vexId'').each(function() {
PIE.attach(this);
});
}
Do you get your data from an Ajax call? If so, you need to add the pie in the callback. There is no possibility (at least afaik) to add anything on something that you don't have at a given time.
If you need to add the pie in the callback, you should make an separate function for that. You can give a dom node to the function and it checks for every child node if pie is applied, and if not it does so.
You can't use the DOMSubtreeModified event since older versions of IE - which you are targeting - don't support this. You can, however, work around this by using this answer Detect changes in the DOM together with this script:
$(document).ready(function () {
function applyPIE() {
if (window.PIE) {
$('.vexClass, #vexId').not('[data-pie=attached]').each(function(){
PIE.attach(this);
$(this).attr('data-pie', 'attached');
});
}
}
onDomChange(function(){
alert('document updated, applying PIE now');
applyPIE();
});
$('#link').click(function () {
$('body').append('<h4>added content</h4>');
});
applyPIE();
});
It creates a local function applyPIE() which is called on document ready and every time the DOM changes - filtering out already processed elements. You may want to expand the .vexClass, #vexId set of selectors to match your needs.
JSFiddle: http://jsfiddle.net/hongaar/y3FaM/1/
I have a page that display some data. It is loaded from a database using php and mysql, I use zend framework to handle all this.
On this page I have two things that use jquery. one is a paginator and the other is a thumps up function.
the paginator works fine. It receives the data as json and applys it to the view. all the functions that I need to handle this are located in one js file. In this file I listen for clicks...
$(document).ready(function() {
$("a#next").click(getProgramms);
$("a#previous").click(getProgramms);
$("a#page").each(function() {
$(this).click(getProgramms);
});
});
Now I have a problem with the thumps up function. It is located in another js file. Everytime the thumbs up button is clicked the script should just alert "click". actually when you click before you use the paginator a "click" appears, but when you do it after nothing happens. but the html in the dom inspector appears to be the same.
in my thumpsup.js I just have
$(document).ready(function() {
$("a.tp").click(thumpsUp);
});
function thumpsUp() {
alert("click");
}
I do not know where the problem is. maybe the js files are interferring each other!?
function thumpsUp() {
var url = window.location.hostname + '/programme/thumpsup/id/'
+ $(this).attr('page');
$.post(url, {
"format" : "json"
}, function(data) {
alert(data);
}, 'html');
return false;
}
I'm guessing the paginator is rewriting your elements and they are losing their click event binding. Try using live() for event binding instead:
$(document).ready(function() {
$("a.tp").live('click',thumpsUp);
});
function thumpsUp() {
alert("click");
}
You might have the Script files (which are included in your mark up) the wrong way round. That's the only solution I can think of...
I'm pretty sure you can get away with two $(document).ready()'s (even if it is frowned upon).