Creating DOJO buttons with Javascript function causing conflicts in buttons created - javascript

my apologies for any mistake in english, I am brazilian.
I have a website with DOJO library, I use it in many things.
I am having some dificulty to create buttons in javascript.
I wrote a function to create the buttons, it is working, creating buttons.
But, when a new button is created, the former button lost the event "onclick".
It can be viewed here: http://jsbin.com/xuzevi/edit?html,js,output
To create the button, I used this code:
require([ 'dojo/dom', 'dojo/parser', 'dijit/form/Button', 'dojo/domReady!' ],
function( dom, parser, Button)
{
var div_Compra = document.getElementById(p_Div);
if( ! div_Compra ) { console.log('ERRO - div_Compra: '+p_Div); return false; }
var botao = new Button({ label: '' });
if( ! botao ) { console.log('ERRO - botao'); return false; }
botao.startup();
botao.set('iconClass', 'dijitEditorIcon dijitEditorIconSelectAll');
botao.set('showLabel', false);
botao.placeAt(div_Compra);
botao.on('click', function() { Mensagem(p_Indice); });
}
);
Thanks.

The issue is not in the above mentioned code. Main problem is your usage of innerHTML in CPR_Compra.Cadastro method. You cannot think, the dojo dijits as just HTML tags, they are DOM objects, nodes and more. When you updated the div_Cadastro.innerHTML, it kind of destroyed the wigit, but retained the HTML tags, so the onclick event stopped working.
Instead of using innerHTML use appendChild, that way the dom nodes wont be destroyed. below is the JSBin with working implementation.
http://jsbin.com/butacuquza/edit?js,output

from https://davidwalsh.name/dojo-widget
To create a widget programmatically, you create DOM nodes which act as placeholders for the future widget
and read this: https://davidwalsh.name/dojo-behavior
Widget Creation with dojo.behavior
Widget creation is an even better opportunity to use dojo.behavior:

for others who came to here like me, a few more links:
HTML DOM appendChild() Method
https://www.w3schools.com/jsref/met_node_appendchild.asp
The Node.appendChild() method adds a node to the end of the list of children of a specified parent node.
https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild

Related

Having an issue with Polymer not recognizing a class I make in the imported file

fairly new to Polymer -- I'm having an issue that I can't seem to figure out. I have this bit of javascript code at the end of the file I am importing for my custom polymer element:
Polymer('metafaq-name', {
ready: function (){
var subby = document.querySelector('.classname');
console.log(subby);
subby.onclick = function () {
console.log('clicky');
}
}
});
and despite me being relatively new to javascript I'm pretty sure there's no (major) errors because it works on any class that's in the main html file, just not on the classes IN the custom polymer element html file where I create it.
Any ideas? I can't seem to get it to recognize any class or ID that's in the file. My thoughts have been that there might be an issue with how the custom element is actually getting imported, like maybe it's adding the script before the rest of the element, but I thought by adding a 'ready' it would fix this issue, so now I'm out of ideas.
Any help would be appreciated! Thanks!
Shan
Your node resides in shadow DOM (in template, if you will), so you should do a query on shadowRoot.
Like this:
this.shadowRoot.querySelector('.className')
If you just want to assign a click handler, you could just say so in in your tag as an on-click - (check under 'Declarative event mapping') - attribute.
For example:
<button on-click="{{hiThere}}">
And then:
Polymer('your-element)', {
hiThere: function() {
alert('hi')
}
})

using custom plugin on run-time created table jquery

I am creating a table run time in the memory and later appending it to dom.
Something like this :
var myTable = $('<table></table>').attr({ id: "dataMatrixtable" }).attr({class: "tipTable",cellpadding: "5",cellspacing: "0"});
myTable.appendTo(this.top.$("#tableContainer"));
This.top because table is in a iframe.
Now I wrote a plugin something like this.
(function($){
$.fn.extend({
mailServer : function() {
this.addClass("blah");
},
})
})(jQuery)
when i am calling this function mailServer after appending the table to dom
$("#dataMatrixtable").mailServer();
or
this.top.$("#dataMatrixtable").mailServer();
either way its not working (not appending the class)
Where as it works for the elements which is already in the dom when page loads..
How to solve this issue.please help
Actually I found a way its working now ..
What I did is
myTable.mailServer(); (its working and I am able to access the plugin funciton mailServer()
In place of doing
$("#dataMatrixtable").mailServer();

Using classes to observe a page

I am writing a script that needs to detect elements added to a Web page, for example events rendered in a calendar (div tags). I don't care about elements that are removed. There should be at most 20-30 such elements on the page.
My idea - short and easy code - is to use a specific class ("myName") to brand elements already in the page. At regular intervals I would poll the page:
// Get all divs in the calendar:
var allDivsCount=myCalendar.querySelectorAll("div").length;
// Get already branded divs
var oldDivsCount=myCalendar.querySelectorAll("div.myName").length;
if (allDivsCount > oldDivsCount) {
// brand the new divs and do stuff
}
Is this a good practice, or is there a better way to do it? Are there libraries that already have such logic implemented?
I am trying to avoid DOMNodeInserted as some browsers don't support it and it is deprecated (due to performance issues, from what I've read).
I know that you're against DOMNodeInserted but I'll added it anyways for options (in case you're not supporting older version of IE).
I blogged about this a while back but it seems like the same solution still applies today (but like I said, depending on the browsers you currently support).
Example:
$(document.body).on('DOMNodeInserted', function (e) {
if (e.currentTarget.toString() === 'HTMLBodyElement') {
console.log(e);
}
});
This triggers any changes within the body not just the body itself.
$('#context').append($('<div />')); // triggers the event above
If you can intercept a DOM change (an AJAX call for instance) and create a global callback function, that would be ideal instead of the setInterval option.
var globalCallback = function() {
/** Do something when the DOM changes */
};
/** Global AJAX event to watch for all AJAX complete within the body */
$('body').ajaxComplete(globalCallback);
This is just one example (AJAX callbacks) of course.

How to lookup/debug a list of all jQuery events bindings if you don't know the id or class of the elements

I added jQuery click events dynamically using the click()-function:
$("#elementId").click(function() {
debugger;
//Some code
});
I realize that you can find the events by using the data attribute:
$('#elementId').data("events");
But what if you want to find them, if any, dynamically? E.g.
<div id="containerWithComplexStructure">
//Some elements with .click events may be in here
</div>
How do you then find them if you don't know their id or class?
And can you access them through the Chrome Developer Tools frame (or similar tools), being able to browse their variables etc.?
Similar to this (click the image to enlarge):
Chrome Developer Tools view, stopped at a breakpoint http://imageshack.us/a/img138/1209/findclickfunction.png
For a single known element see: How to debug JavaScript/jQuery event bindings with Firebug (or similar tool)
Easy, console.log( jQuery('#elementId').data('events') ); in your code;
or just jQuery('#elementId').data('events'); in the console.
To view events from all elements:
var elements_with_events = 0;
$('*').each(function(i,e){
if($(e).data('events')){
console.log( $(e) );
console.log( $(e).data('events') );
elements_with_events++;
}
});
console.log( elements_with_events + ' elements have events.' );
... and wait for the crash. Actually this works surprisingly fast.
You could add a class when attaching events also. Then you aren't searching for events per say but classes.

What event fires when elements are added or removed in the document?

I am making a sort of tabbed interface for a Tiddlywiki, and I am wondering how to get this code to fire every time a tiddler is opened or closed. Tiddlywiki is an HTML notebook type of thing that runs in the browser, and a tiddler is a div in #tiddlerDisplay. There can be, and usually are, more than one in it at a time.
The divs I want to list are contained in #tiddlerDisplay, and the list itself is jQuery("#mainMenu > #singleTiddlerList").
config.macros.singleTiddler.update = function(){
jQuery("#mainMenu > #singleTiddlerList").empty();
jQuery("#tiddlerDisplay > div").each(function(i,e){
jQuery("#mainMenu > #singleTiddlerList").append(jQuery(
createTiddlyButton(document.createElement("li"),jQuery(e).attr("tiddler"),"",config.macros.singleTiddler.clickHandler)
).parent());
});
};
Update: I can't just add a custom event, unless I can do it from outside the current code (such as something that fires on document load).
First create two custom events for your append/clearing of divs. Have them bind in the document you use the code posted above.
jQuery(document).bind('div-removed',function(e){
// code stuff to do for removal
jQuery("#mainMenu > #singleTiddlerList").empty(); // required
// other stuff here
});
jQuery(document).bind('div-appended',function(e){
// code stuff to do on append
jQuery("#tiddlerDisplay > div").each(function(i,e){
jQuery("#mainMenu > #singleTiddlerList").append(jQuery(
createTiddlyButton(document.createElement("li"),jQuery(e).attr("tiddler"),"",config.macros.singleTiddler.clickHandler)
).parent());
}); // required
//other stuff here
});
Then in your code change slightly the execution:
config.macros.singleTiddler.update = function(){
$(document).trigger("div-removed");
$(document).trigger("div-appended");
};
It's definitely not the only way (I think now it can also be done with .promise() but it's a start. update updated to check if this works.
One way is jQuery("#tiddlerDisplay").bind("DOMSubtreeModified", config.macros.singleTiddler.update);, however i think this only works in Chrome (maybe Opera or Safari, not sure), and also appears to be deprecated. Firefox has a duo of events to accomplish the same thing, but i think these are also deprecated.
Another way I found after reading this article and exploring the TiddlyWiki source code is this:
(function( $, oldRem ){
Story.prototype.displayTiddler = function(){
var resp = oldRem.apply( this, arguments );
$("#tiddlerDisplay").trigger("displayTiddler");
return(resp);
};
})( jQuery, Story.prototype.displayTiddler );
(function( $, oldRem ){
Story.prototype.closeTiddler = function(){
var resp = oldRem.apply( this, arguments );
$("#tiddlerDisplay").trigger("closeTiddler");
return(resp);
};
})( jQuery, Story.prototype.closeTiddler );
jQuery("#tiddlerDisplay").bind("displayTiddler", config.macros.singleTiddler.update);
jQuery("#tiddlerDisplay").bind("closeTiddler", config.macros.singleTiddler.update);
Notice that the event fires after the tiddler opens or closes. Also, as the article states, jQuery can be bugged in the same way, but I don't know about the native DOM methods, and I kind of doubt it. There's supposed to be an event for it, but regardless, everyone should totally drop them and use jQuery!

Categories

Resources