I have a problem with Dojo in Internet explorer 7/8 (this works fine in Firefox).
Basically I have a tab container with a number of tabs in it (these are dojox.layout.ContentPane's). On one of these tabs I want to have a "comments box" which would popup a dialog and ask the user to put something in. The comment is then saved by an call to the back end and I want the tab to reload to show the new comment.
The logic of my save button works something like this:
<button data-dojo-type="dijit.form.Button" type="button" data-dojo-props="iconClass:'dijitIcon dijitIconSave', showLabel: true" title="Add your comment">Add Comment
<script type="dojo/on" data-dojo-event="click" data-dojo-args="evt">
require(["dojo/dom"], function(dom)
{
var tText = dijit.byId('comment_70').get('value');
if (tText == '')
{
alert('You have not entered any comment');
return;
}
var tJSONRPC = new JSONRpcClient('JSON-RPC');
try
{
tJSONRPC.be.addComment('70', tText);
var tTab = dijit.byId('Detail_70');
tTab.refresh();
}
catch (Ex)
{
alert(Ex);
}
});
</script></button>
Does not appear to be terrible taxing (the 70 at the end is the ID so that the user can have more than one of these open at the same time, hence the tabs).
As mentioned this works fine in Firefox but not in IE 8/7, it throws an error in some of the generated code within dojo (_32.focus(); to be precise), the error message I get in the debug console is "Unexpected call to method or property access"
Try this, with your line tTab.refresh();:
setTimeout(function() { tTab.refresh(); }, 0); // whenIdle
Its nearly impossible to tell where the thrown exception comes from - you should use the developement dojo-1.M.m-src/dojo/dojo.js code so optimized function- and variable-names are expanded (along with useful commenting once you step-through-debug).
Reason for the above is to eliminate, that exception occurs while handling button onclick-focus event (refresh will tear down DOM in the tab - along with your button)
Related
I have a kendo grid with a custom popup:
columns.Command(commands =>
{
commands.Edit();
}
.Editable(editing => editing.Mode(Kendo.Mvc.UI.GridEditMode.PopUp))
Each time I click the edit button the window pops up but when I close it the window is not removed from the DOM.
I saw this post: http://www.telerik.com/forums/popup-windows-do-not-get-removed-from-dom and Telerik says the issue has been fixed.
What are some things that would cause this behavior?
UPDATED
This grid is nested in a Kendo TabStrip if that helps. Other than that I don't see anything out of the ordinary. The popup is entirely managed by the grid.
UPDATED 2
So I got the un-minimized code for the grid (kendo.grid.min.js, version 2013.3.1119, starting at line 1172), slopped it into my project and modified just the following with the two log statements to verify that destroy is being bound and called:
_destroyEditable: function () {
var that = this;
var destroy = function () {
if (that.editable) {
// My edit
console.log("...destroy() called");
that._detachModelChange();
that.editable.destroy();
that.editable = null;
that._editContainer = null;
}
};
if (that.editable) {
if (that._editMode() === "popup") {
// My edit
console.log("Binding destroy() to 'deactivate'...");
that._editContainer.data("kendoWindow").bind("deactivate", destroy).close();
} else {
destroy();
}
}
},
Each time I click edit and then close the window I see the expected two messages yet the window is not removed. Here is a screenshot of the debugger:
The outlined windows are the dom elements generated.
After much trial and error and deep diving it turns out this problem has to do with our scripts in our site's layout. At some point whomever setup the kendo scripts put in not only the 'kendo.all.min.js' but right after it 'kendo.web.min.js', 'kendo.aspnetmvc.min.js' and then about 10 individual kendo.*.js including the grid.
After viewing this link:
http://docs.telerik.com/kendo-ui/getting-started/javascript-dependencies
I realized that the site is creating these objects multiple times. Removing the script references in accordance to the link above resolves the issue.
Well, I'm developing a firefox addon that reload a given set of url automatically with some modification. Its not possible to show the whole code. So, I've just copy paste the part of the code which is giving me the error.
The DOMContentLoaded event is suppose to be triggered everything a page is loaded, and it do it properly. The problem is that, if i open a new tab, then DOMContentLoaded event is not triggered in the old tab.
//Any code here runs only for the first time u start the browser
window.addEventListener("load", function() { myExtension.init(); }, false);
var myExtension = {
init: function()
{
var appcontent = document.getElementById("appcontent");
if(appcontent)
appcontent.addEventListener("DOMContentLoaded", myExtension.onPageLoad, true);
},
onPageLoad: function(aEvent)
{
var doc = aEvent.originalTarget; // doc is document triggered "onload" event
//execute on one the top page (not on iframes)
if ((aEvent.originalTarget.nodeName == '#document') && (aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec))
{setTimeout(function(){showInError(doc.location='about:home'}, 500);}
},
}
I'd like to write the problem in a simple way (sorry for my bad English)
1) i run firefox, and the tab (say tab no.1) is continuously reloaded as i want.
2) the tab no.1 page continues to load repeatedly if i leave the page uninterrupted(that's what it want)
3) if i open a new tab (say tab no. 2), the new tab (tab no. 2) begins to reload continuously as i wanted. However, the tab no. 1 stops reloading.
what i want is to to keep on reloading both tab no 1 and tab no. 2. How to do it? what is wrong is my code?
It looks like you are executing the script only on currently displayed page (active tab).
If you want to execute it on other tabs, you should attach event listeners to new tabs as you open them (and don't forget to remove them when you close the tab). You can get useful snippets for this functionality at this page:
https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads#WebProgressListeners
Try using gBrowser instead of document.getElementById("appcontent");
gBrowser.addEventListener("DOMContentLoaded", myExtension.onPageLoad, true);
https://developer.mozilla.org/en/Code_snippets/On_page_load#Basic_onPageLoad_for_a_browser_window
I have a really annoying issue with Autocomplete with Prototype 1.6. I set up and dialog-style div with a form, which contains an Autocomplete. Everything works fine until I click the scroll bar, or drag it; it closes the list of suggestions. I checked this solution but now I got an javascript error
event.srcElement is undefined
I was checking the controls.js and tried to catch the event object inside the onBlur event, but it travels empty. Printed the offsetX property and is undefined. Looks like the event doesn't exist anymore. either way, it prevents that the list closes but, If I click outside the area, the list now doesn't close. And that's kinda of issue too
Anyone with this same issue? Any idea?
Thanks in advance
I was having the exact issue yesterday, but after doing some r&d I got a pretty handy fix for this.
By default this script was hiding the result div (Suggestion List) on the blur event on the search text box so as soon as we click on result div's scroll bar focus gets lost from input element & result div closes. So I did a small edit in controls.js to change the behavior of script, so now result div close method doesn't invoke on blur (focus out) from input element but triggered on the click on the document except the text input element.
For your convenience I've put the edited controls.js here.
If you like to know what has changed in JS file, here it is;
Added a event listener to the document. Just below this line
"Event.observe(this.update, "keypress", this.onKeyPress.bindAsEventListener(this));"
Event.observe($(document), "mouseup", this.onMouseup.bindAsEventListener(this));
Added a new onMouseup method.
onMouseup: function(event) {
if(!this.hasFocus) {
this.hideTimeout = setTimeout(this.hide.bind(this), 250);
this.hasFocus = false;
this.active = false;
}
},
Modify the onBlur method (Comment out two line in block)
onBlur: function(event) {
//this.hideTimeout = setTimeout(this.hide.bind(this), 250);
//this.active = false;
this.hasFocus = false;
}
I hope this will solve your issue.
Thanks
Vinod Kumar
I am developing a website that parses rss feeds and displays them based on category. You can view it here: http://vitaminjdesign.com/adrian
I am using tabs to display each category. The tabs use ajax to display a new set of feeds when they are clicked.
I am also using two other scripts- One called equalheights, which re-sizes all of the heights to that of the tallest item. And the other script I am using is called smart columns, which basically resize your columns so it always fills the screen.
The first problem I am having is when you click a new tab (to display feeds within that category). When a new tab is clicked, the console shows a jQuery error:
$(".block").equalHeights is not a function
[Break On This Error] $(".block").equalHeights();
The main problem is that each feed box fills up the entire screen's width (after you click on a tab), even if there are multiple feed boxes in that category.
MY GUESS - although all of the feeds (across all tabs) are loaded on pageload, when a new tab is selected, both jQuery scripts need to be run again. any ideas on how I can make this work properly?
One thing to note - I used the ajaxSuccess method for making equalHeights work on the first page...but it wont work after a tab is clicked.
My jQuery code for the tabs are below:
$(".tab_content").hide(); //Hide all content
$("ul.tabs li:first").addClass("active").show(); //Activate first tab
$(".tab_content:first").show(); //Show first tab content
$("#cities li:nth-child(1)").addClass('zebra');
$("#column li ul li:nth-child(6)").addClass('zebra1');
//On Click Event
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
$(activeTab).fadeIn(); //Fade in the active ID content
$(".block").equalHeights();
return false;
});
Thanks to Macy (see answer below), I have brought my jQuery script to the following: (still does not work)
$(document).ajaxSuccess(function(){
var script = document.createElement('script');
script.src = 'js/equalHeight.js';
document.body.appendChild(script);
equalHeight($(".block"));
I found some small problems in your code. I am not sure that my suggestions will solve all the problems, but I decide to describe my first results here.
1) You should remove comma before the '}'. Currently the call look like $("#column").sortable({/**/,});
2) The function equalHeight is not jQuery plugin. It is the reason why the call $(".block").equalHeights(); inside your 'click' event handler follows to the error "$(".block").equalHeights is not a function" which you described. You should change the place of the code to equalHeight($(".block")); like you use it on other places.
3) The script http://vitaminjdesign.com/adrian/js/equalHeight.js defines the function equalHeight only and not start any actions. Once be loaded it stay on the page. So you should not load it at the end of every ajax request. So I suggest to reduce the script
$(document).ajaxSuccess(function(){
var script = document.createElement('script');
script.src = 'http://vitaminjdesign.com/adrian/js/equalHeight.js';
document.body.appendChild(script);
equalHeight($(".block"));
$("a[href^='http:']:not([href*='" + window.location.host + "'])").each(function() {
$(this).attr("target", "_blank");
});
});
to
$(document).ajaxSuccess(function(){
equalHeight($(".block"));
$("a[href^='http:']:not([href*='" + window.location.host + "'])").each(function() {
$(this).attr("target", "_blank");
});
});
4) I suggest to change the code of http://vitaminjdesign.com/adrian/js/equalHeight.js from
function equalHeight(group) {
tallest = 0;
group.each(function() {
thisHeight = $(this).height();
if(thisHeight > tallest) {
tallest = thisHeight;
}
});
group.height(tallest);
}
to
function equalHeight(group) {
var tallest = 0;
group.each(function() {
var thisHeight = $(this).height();
if(thisHeight > tallest) {
tallest = thisHeight;
}
});
group.height(tallest);
}
to eliminate the usage of global variables tallest and thisHeight. I recommend you to use JSLint to verify all your JavaScript codes. I find it very helpful.
5) I recommend you to use any XHTML validator to find some small but sometime very important errors in the markup. Try this for example to see some errors. The more you follow the XHTML standards the more is the probability to have the same results of the page in different web browsers. By the way, you can dramatically reduce the number of the errors in your current code if the scripts included in the page will be in the following form
<script type="text/javascript">
//<![CDATA[
/* here is the JavaScript code */
//]]>
</script>
I didn't analysed the full code but I hope that my suggestions will solve at least some of problems which you described in your question.
Essentially, when you add a new element to the document, the equalheights script has not attached its behavior to that new element. So, the "quick fix", is probably to re-embed the equalheights script after an ajax request has completed so that it re-attaches itself to all elements on the page, including the elements you just added.
Before this line: $(".block").equalHeights(); , add a line of script which re-embeds/re-runs your equalheights script.
$.getScript('<the location of your equalHeightsScript>');
$.getScript('<the location of your smartColumnsScript>');
$(".block").equalHeights();
or
var script = document.createElement('script');
script.src = '<the location of your script>';
document.body.appendChild(script);
A better solution would be to upgrade the plugin so it takes advantage of live. However, I'm not up to that at the moment :)
Some Error Here
$("ul.tabs li").click(function() {
$("ul.tabs li").removeClass("active"); //Remove any "active" class
$(this).addClass("active"); //Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
.
.
.
});
Should be re-written like this
$("ul.tabs li").click(function() {
$(this).addClass("active").Siblings("li").removeClass("active");; //Remove any "active" class Add "active" class to selected tab
$(".tab_content").hide(); //Hide all tab content
.
.
.
});
I don't think you need to run the scripts again after the ajax, or at least that's not the "main" problem.
You seem to have some problems in the script smartColumn.js
Right now it seems to only operate on the ul with the id "column" ('#column'), and it is working on the one UL#column you do have, but of course your HTML has many other "columns" all of which have the class "column" ('.column') that you want it to work on as well.
Just to get the beginning of what you are trying to do, change all the selectors in smartColumn.js that say 'ul#column' to say 'ul.column' instead, and then alter the HTML so that the first "column" has a class="column" rather than an id="column".
That should solve the 100% wide columns at least.
That should solve your "Main" Problem. But there are other problems.
Using the event click with live function leads to strange behavior when using Firefox*.
With live in Firefox, click is triggered when right-clicking also! The same does not happen in Internet Explorer 7 neither in Google Chrome.
Example:
Without live, go to demo and try right clicking
the paragraphs. A dialog menu should
appear.
With live, go to demo and try right
clicking "Click me!". Now both dialog
menu and "Another paragraph" appear.
*tested with firefox 3.5.3
As far as I know, that is a known issue (bug?). You can easily work around it by testing which button was clicked as follows:
$('a.foo').live("click", function(e) {
if (e.button == 0) { // 0 = left, 1 = middle, 2 = right
//left button was clicked
} else {
//other button was clicked (do nothing?)
//return false or e.preventDefault()
}
});
you might prefer using a switch depending on your specific requirements, but generally you would probably just want to do nothing (or or simply return) if any button other than the left button is clicked, as above:
$('a.foo').live("click", function(e) {
switch(e.button) {
case 0 : alert('Left button was clicked');break;
default: return false;
}
});
I think it's a known "bug", you could potentially query the event object after attaching the click handler ( which gets attached to the document ) and see if its a right click, otherwise manually attach the click handler after you manipulate the DOM.
After looking it up, e.button is the property you want to query:
.live('click', function(e){
if ( e.button == 2 ) return false; // exit if right clicking
// normal action
});
See my answer here: if you don't mind changing the jQuery source a bit, adding a single line in the liveHandler() works around the problem entirely.