I'm making a widget that has a tabContainer in it, which needs to be started up after it's inserted into the DOM and ready.
However, my class actually responds with a view that you can instantiate yourself. Therefore, I want to have an 'onPlace' event or 'onComplete' event of some sort that starts up the tabContainer once it's been placed.
Can anyone lead me in any good direction on this? Can't seem to find much dojo / dijit documentation out there that can help!
Okay, after looking into the source code a bit I found this out:
If you widget inherits from dijit/_WidgetBase (mine did), you can overwrite the startup function which will happen after it's rendered.
For example:
tabContainer: value,
startup: function() {
this.tabContainer.startup();
}
I'm not sure if this is the most elegant, but if you have any input or solutions please feel free to add/comment/answer!
Related
I've got a question that searching did not actually yield any results. I apologize if this has been asked in the past.
I'm trying to define an event listener, and immediately remove the JS after defining the event listener. The problem is, I want the removal to take place prior to the event taking placing. Is this possible? I read in the JQuery 1.4 documentation that detach() is like remove, but maintains JQuery data. Is this a viable solution? Are there downsides to removing the code which places an event listener prior to the event taking place?
The code I'm trying to remove is dynamically generated code. Doing something like this:
<script id="12341234">
$( function() {
$('#test').click( function() {
alert('Hello');
});
});
</script>
Later in the script:
$('#12341234').remove();
That works fine for removing the script, it just doesn't fire the event listener (which makes sense).
The reason I'm trying to do this is for a very small amount of added security. Sensitive fields are already masked, no one can gain access to anything sensitive per se. I just have PHP generating a decent amount of JS, and I don't want the temptation of "inspect element". If they do actually see it, it's not a huge deal. I'd just prefer to remove it if possible.
Any help is much appreciated. Thank you in advance.
In case anyone is wondering, I figured out the answer to this.
It functions just as I theorized: It removes the script tags and everything in between, but the event listener remains intact. See below for example:
<script id="testscript">
$( function() {
$('#testbutton').click( function() {
alert('Hello!');
});
});
$('#testscript').detach();
</script>
This will keep your event-listener, while preventing your JS from being displayed on inspect.
A quick note, if someone is using any sort of debugging tools which can step through rendering, they can EASILY see the code before it's ever removed. However, if you simply don't want the average user to see the JS, this will work.
Sensitive data will still need masked or dealt with appropriately.
I still don't know the answer to the question as to whether or not detach() has a negative impact, or if it should be avoided for this use-case. However, I did some testing and it doesn't appear to have much performance impact versus remove(). We're talking 1% slower or less. I also dug a bit more through documentation, and reaffirmed my initial believe that my use-case is basically a standard use-case for detach(). There doesn't seem to be any downside to using it. I may be wrong, and if so feel free to correct me.
I'm working on a web interface with the help of primefaces framework.
In that interface, one of the objectives is to have the code divided in javascript functions that do not share information between each other and they don't allow being invoked by other parts (that eases testing and reduces the number and complexity of possible use-cases).
All "parts" are encapsulated using:
(function (window, document, undefined){
var $ = window.jQuery;
// main content here
})(window,document);
The communication required between each part is minimal and the required one is made using DOM events where an object is passed between each other. (if the event is not caught, it's just a functionality that didn't act. If it caused something to break, the js does not stop working, among other reasons).
This has been working for quite a while with minimal bugs found until I had to work with jsf+primefaces.
By reading the documentation, primefaces has many XML tags that do not map to HTML tags. One of the main ones I have to work with is <p:ajax>.
This tag was many on*-like attributes whose concept works much like the HTML3's ideology of writing javascript in HTML's "on*" attributes. Still, those <p:ajax> are always attached to specific XML elements like <h:inputText> or <p:commandButton> and that's where I started looking at.
In primefaces documentation, there's information about the inline on* attributes but I was fully unable to find information about jsf or primefaces' personalized DOM events.
How it appears with primefaces, I'm forced to change the javascript code so that functions/methods can be called inline in the HTML. That would require a lot of work also because, depending on the situation, the js code might even not be there (because the feature it enables is not required for that page).
How do I make the system on primefaces such that I have my javascript fully detached from the jsf/primefaces XML (and the whole HTML output I can manage).
EDIT:
I ran out of ideas on where to look at, I'll work on looking at primefaces source code now. I may get better luck there.
EDIT:
Meanwhile I got some ideas for searching using different keywords and I found this(see: "Client Side API"):
http://courses.coreservlets.com/Course-Materials/pdf/jsf/primefaces/users-guide/p-ajaxStatus.pdf
This is near what I wanted but it seems like it does not exist for the elements I mentioned above. I'll work on continuing searching for more.
After some testing, investigation, etc... I was finally able to understand the whole story of what was happening.
Primefaces was doing everything right after all! The <p:ajax> has the correct code to send all the events it should! The problem lies in jQuery itself.
jQuery's trigger() method (and it's shortcuts) works in such way that it handles all events directly inside jQuery bubbling and calling the callbacks registered using on() (or any of the shorthands).
The main issue in jQuery is that it only resend the "click" event to the DOM because it tries to use a method in the DOM element with the same name as the event. In the DOM, (at the moment) the only situation when that happens is the "click" event. That's why I was getting the click event and not the rest of the events.
With that, the mistery and confusion was, finally, solved. uff!
I have a general question regards where I should do view element addin initialzation. Say for instance I have a typeahead plugin that requires initialization like so.
$(element).typeahead();
Using Backbone.Marionette where is the best place todo this type of view specific code? My original thought was to override the onRender() method in my view class and do this specifically everytime for elements I know about at design time. However, I would like a more general approach like monitoring the newly added dom elements and checking if element has an identifier like 'data-typeahead' and then automatically initialising it. However, I don't know any jQuery function that would do this? Or even if this is a realistic idea in terms of the overhead of dom parsing especially on mobile devices?
Any thoughts / ideas on how to solve this or where to best place to do this sort of code would be awesome!
Thanks
Jon
For those interested I used #Trond suggestions and implemented view init statements in the onShow method.
I am trying to use Backbone.Paginator.js to run more than one app (multiple instances of paginator) on the same page.
I created a test page. (Navigate to backbone.paginator/examples/netflix-infinite-paging).
I left the code as is for app.js and create app2.js, which is a clone of app.js but all the javascript code is located in one file and the app has been renamed to app2.
Two instances work on first load of the page but subsequent request/refreshes only load app2.js's data.
Is it possible to run multiple instances on the same page?
I am interested in using an auto-paging (infinite/endless scroll) so
I tried to use Paul Irish's jQuery Infinite Scroll plugin but
I am unable to get it to work.
I am initiating the plugin to run on document ready (which does not
work, as expected), but also running the code in the app2's
ResultView, which does not work as well.
Any ideas on how to get an auto-paging infinite scroll solution?
I ran into https://github.com/joneath/infiniScroll.js but I am not
sure how to integrate it with Backbone.Paginator.js.
I am still learning and any help would be greatly appreciated! :)
UPDATE: After further testing across different browsers, it seems like the problem might be to caching issue/differences. For example, in Safari, it works sometimes (randomly) when refreshing the page. I am not sure how to debug that. Any ideas?
Questions:
1- Are you including the jQuery Javascript framework dependencies as well in your codebase?
2- I have downloaded the zip file, ran it on Xammp locally and it appears to be a downloaded demo not a test page, can you please confirm which page is your test page from the compressed file attached to your question?
3- Can you create a mockup (in case that there is some server side code happening) in jsfiddle?
4- The link provided for the Infinite scroll jquery plugin is broken, it should be: https://github.com/joneath/infiniScroll.js
If you want to make the jQuery paginator plugin to be independent, you might want to trigger it considering the container element as well
....
From the suggested link, I think that we should experiment with this. Else you might want to create a cookie or something for the browser to remember the changes to the plugin on multiple instances.. Here are some thoughts?
1#
Backbone.InfiniScroll(collection, **options**)
Instantiate a new InfiniScroll object after your Backbone view has been rendered.
myView = Backbone.View.extend({
initialize: function(){
_.bindAll(this, "render");
this.render();
this.infiniScroll = new Backbone.InfiniScroll(this.collection, {success: this.appendRender});
}
)};
2# At a glance from the Options menu
target: $(window),
Perhaps we should try:
$(body).find('#container1'),
-or-
$(window).children('div').hasClass('container'),
Just some ideas, haven't experimented it myself-
3# You might want to make (1) to be a javacript function and trigger it based on a class or on it's id for initializing the scroll over a desired container.
That's all the ideas I could come up by taking a look real quick, but feel free to reply if it helps out or at least gives some direction.
4# Another thought is that myView can be a variable with an id of a timestamp in Javascript, that way you can ensure uniqueness and since you are calling new then you could have several instances of the plugin running for your view.
I am adapting the Coverflow technique to work with a div. The coverflow function (included as a js file in the head section) is here. When I dynamically add a DIV, it doesn't show up in the coverflow. I am wondering if there is a way to add a destroy function to this js file so that whenever a new div add is added, I can call the destroy method and then reinstantiate. Any suggestions on how I should go about doing this?
I wasted a lot of hours trying to come up with a good technique but finally this seems to work. If you're passing a div to the function like this:
$("div.divname").coverflow({});
Then, do this when you add a new DIV:
addDiv();
divBackup = $("div.divname")
$("div.divname").remove()
$("parentdiv").append(divBackup)
$("div.divname").coverflow({});
If anyone has a good suggestion, please feel free to add it. Until then, figured this would help someone facing the same problem.
Why this works?
When you remove and add the div, all the eventhandlers are destroyed as well. So, the next time you call the coverflow function, it reattaches to everything that is present. Beware though! If you attached other handlers, they will be lost as well. I know this is not the optimal solution but use it if you have no other option.