dijit.findWidgets return null array? - javascript

On the JSTL page I have following divs
<div dojoType="dijit.layout.TabContainer" style="width: 100%; height: 100%;" doLayout="false" id="dojoTabbedPane" >
<c:forEach items="${summariesMap}" var="summaryEntry">
<div dojoType="dijit.layout.ContentPane" title="${summaryEntry.key}">
I try to find all divs under (including dojoTabbedPane) in order to recersively destroy all the contentPane under it. Then I can use jQuery.load() to reload contents and use
dojo.parser.parse(dijit.byId("dojoTabbedPane"));
to re-parse the component to make sure the tabbedPane can be rendered(otherwise it doesn't and cause memory leak or error)
Here the question is:
(1) Am I on the right track to re-parse the dojo TabbedContainer?
(2) Why each time the findWidgets function just return array with size 0?
Thanks in advance.

I'll answer 2 first: because dijit.findWidgets expects a DOM node, not a widget. If you need to find all widgets inside another widget, you can use getDescendants instead:
var descWidgets = dijit.byId("dojoTabbedPane").getDescendants();
Onto question 1: First off: if you want to destroy all the tabs in a TabContainer, you can use :
dijit.byId("dojoTabbedPane").destroyDescendants();
Now, if I understand you correctly, you subsequently grab a string of HTML from the server (using jQuery), and want to add it to the TabContainer. This new content contains several ContentPane divs, and you want these to become the new tabs in the TabContainer.
I may be wrong here, but I don't think that's doable without some gnarly hack. Once you've parsed/instantiated a TabContainer, you should add tabs using addChild, passing instantiated ContentPanes.
This means that if you get new HTML content like this from the server (via your jQuery load):
<div dojoType="dijit.layout.ContentPane" title="new tab1">foo</div>
<div dojoType="dijit.layout.ContentPane" title="new tab2">bar</div>
.. then your best bet is to remove the old TabContainer and make a new one, then parse the whole thing. If you're able to change the content you get from your server, perhaps you can simply wrap that in <div dojoType="dijit.layout.TabContainer....

Related

How to load multiple CKEditor toolbars on the same web page

I have two divs on the same page using CKEditor. I can get a toolbar to load for the first div, but not the second. I realize this is the case because I'm using an id for ckToolbar instead of a class. However, if I use a class, the toolbar doesn't show up.
Div 1
<div id="ckEditor">
<div id="ckToolbar"></div>
<div class="editor" data-bind="wysiwyg: txtBody, value:txtBody, valueUpdate:'keydown'"></div>
</div>
Div 2
<div id="ckEditor">
<div id="ckToolbar"></div>
<div class="editor" data-bind="wysiwyg: txtHelpText, value:txtHelpText, valueUpdate:'keydown'"></div>
</div>
Config.js
config.extraPlugins = 'sharedspace';
config.sharedSpaces = { top: 'ckToolbar' };
I am also using Knockout JS. I created a custom binding and a div instead of a textarea because I couldn't use the CKEDITOR replace function with my binding.
You can't have two elements on the same page with same id's. How is JavaScript supposed to recognize which one you have in mind? You should either use classes or different id's and adjust you knockout code to handle that.
Sorry for the general answer but there is simply no way around it. You can't have two elements with same id on a single page.
NOTE: CKEditor auto replaces elements with ckeditor class however if you are using knockout, I don't think this will me much of a use for you.

div doesn't recognize its child elements (javascript)

Layout of the code:
An .html file & I link to an external .js and .css in head. Various table cells onclick make a "popup" div change its position and become visible. To do this, I made the JS functions reference a global variable which I set by adding
<script>var popup = document.getElementById('popdiv');</script>
just above the end of /body.
popdiv has 3 child elements:
<div id='popdiv'>
<div class='header'>Time Slot</div>
<div class='xout' onclick='hide(event)'>X</div>
<div class='showtag'>tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11</div>
</div>
Anything I do with popup works fine, except when I try to call popup.firstChild, which screws everything up. popup.firstChild.type returns undefined, and popup.childNodes.length returns 7. I gave the nested div an id so I could grab it; [getheader].parentNode.type is also undefined.
And I replaced the .header selector in my .css file with a first-child of popdiv selector (#popdiv >:first-child) and its style was still correctly applied; all 3 children will also inherit style attributes like color:red--if I set them in the CSS file. Not so if I set them with JavaScript.
In this case there are other ways I can access the divs, but I want to know for the sake of understanding JavaScript what the heck happened--or if I misunderstand something fundamental about parent-child HTML elements. Did I do something awful that could break other things? (Having the extra script at the end of the file feels wrong, but I don't know the actual reason it doesn't work out fine.)
Thank you in advance
Try document.getElementById('popdiv').children[0] as described here - for getting first child. Also you can use popup.firstElementChild that give you the same result.
And you can use document.getElementById('popdiv').childrento get all children.

Dynamically loading widgets in Dojo ContentPanes

I have a JSP page with 6 custom widgets in a TabContainer. The code looks something like this:
<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props="region: 'center', gutters:false">
<div data-dojo-type="dijit/layout/ContentPane" title="<b>Registries</b>">
<div data-dojo-type="my/custom/Widget"></div>
</div>
...(5 more ContentPanes like this)
</div>
When the page loads, each tab loads each widget and it's pretty slow. Most of the time, I only need to access one of those tabs and don't care about the others, so I decided I want to load this content dynamically.
When the href property is specified for a Dojo ContentPane, that content will not be loaded or parsed until that tab is selected. The only problem is, that means I would have to create 6 new .html files that have nothing besides in them. It's like a declarative way to programmatically load widgets... kind of weird.
Is there a way I can simply tell the ContentPane I just want it to dynamically load my custom widget instead of having to create html markup? Currently, I created a Spring controller method that accepts a String with a "widget" property and returns a string that is a div with the data-dojo-type set to the widget name, which is a programmatic way define declarative markup to be loaded programatically... it just keeps getting weirder! So now all of my content panes look like this:
<div data-dojo-type="dijit/layout/ContentPane" title="<b>Registries</b>" data-dojo-props='href:"rest/dynamicWidgetHtml/my.custom.Widget/"'></div>
Where "my.custom.Widget" is a spring controller path variable.
Any way to simplify this and eliminate the need for calling the server to build the div so the widget can be dynamically loaded when the tab is selected?
Would like to know how familiar are you with JavaScript and Dojo widgets.?
I have tried to answer the questions with some assumptions.
1) Assuming that data-dojo-type="my/custom/Widget" is a custom dojo widget i.e dojo widget contained in a javascript file.
2) You are able to attach a function to the onShow event of the ContentPane as shown below.
First is you need to attach a function to the contentPane "onShow" event. say myFirstTabContentPaneShowAction()
and specify a element tag with a unique ID. I have used widget1 as an example below. The onShow event will be fired when you select the tab.
<div dojoType="dijit.layout.ContentPane" onShow="myFirstTabContentPaneShowAction()">
<div id="widget1" ></div>
</div>
The myFirstTabContentPaneShowAction() will be as follows.
function myFirstTabContentPaneShowAction() {
require ( ["dojo/parser", "dojo/dom", "my/custom/Widget"] , function ( parser, dom) {
widgetHandle = parser.instantiate([dom.byId("widget1")], {data-dojo-type: "my.custom.Widget"});
});
Hope it helps.

Minimal jQuery template

I am creating a UI, in which user can add / delete items (of similar layout).
It starts with one item and you can click 'add' to add more. The UI consists of several different types of items.
What I am doing currently is populating a single item item 1 ( of each type ) and on add event, I clone the item 1, replace the changes done by user in item 1 and append the clone to the container.
In simple words, instead of dynamically creating html with jQuery, I am cloning html of a div. But in this approach , I had to change a lot of things to keep to give the new item to initial state.
So, I want to avoid the replacing the edits done by user, so I was thinking something like below,
<script type="text/template" id="item_type1">
<div>
<div>Box</div>
</div>
</script>
<script type="text/template" id="item_type2">
<div>
<div>Box2</div>
</div>
</script>
And on add event, I want to do something like $('#item_type1').html() and $('#item_type2') to create new items.
I know there are sophisticated libraries like handlebar and mustache and underscore has its own way of implementing templates.
But I am not using any of these already and thus do not want to included them just to copy content. I dont want anything special. I am not passing variables. I am just cloning some markup to use again and again.
Is this way to insert html in script tags , going to work in all browsers ? and is it a good way ?
EDIT:
Its for the wp plugin and I assume js is turned on , else the plugin wont work anyways.
What about:
Your HTML should be, for example:
<script type="text/template" id="item_type1">
<div>
<h1>Box1</h1>
<p>
</p>
</div>
</script>
And your code would be:
var templateHtml = $('#item_type1').html();
var $item = $(templateHtml);
$('body').append($item);
$item.on('click', function() {});
This is an easy way that will work on all browsers.
Step 1: Create an HTML file with your template inside of it
Step 2: Using jQuery's load() method, call your HTML template into a div element in the main HTML file:
$("#main-div").load("yourtemplate.html")
Step 3: Be amazed
Is this a good idea? It depends:
If it's a self contained application on a known environment with a determined supported browser and with equally determined settings (like if JavaScript is on or not) then yea, sure. Why not?
If it's open to the public in every single browser possible with many different configurations, then no, it's a horrible idea. If your user doesn't have JavaScript enabled, then your content doesn't show up. Also, if one of your scripts break in production, then you are again left with no content. You can learn this lesson from when Gawker made this same mistake

Need to pull additional data: how do I do that without making an AJAX call?

this should be a pretty straightforward question. My app is built on Ruby on Rails (I doubt that this is very important though -- I'm noting this so you all understand the syntax below)
I have these two div:
<div id = "1"><%= user.Name %></div>
<div id = "2">Placeholder</div>
When someone mouses over div with id 1, I would like to replace the content of the div with id 2.
The catch is that the content I want to replace div 2 with is contained in the user object. So ideally, I'd like to set some kind of additional tag on the div that I can lookup on the JavaScript mouseover. Otherwise, I'll have to do an AJAX call that will result in a DB query to pull the relevant data.
I have no idea what that tag would be ... any hints on what I could do?
Thanks!
Ringo
if possible, you can use the html5 'data-*' atribute to store whatever you want for further manipulation. learn more about this atribute | browser compatibility

Categories

Resources