div.appendChild(div) equivalent in ExtJS4 - javascript

I am transitioning my code to ExtJs4.1.1.
In one part of the code I have used Javascript's appendChild() method to add new div elements to an existing div container.
I want this to be done in ExtJs now.
Existing code:
var container = document.getElementById('treeContainer');
var nodeDiv = document.createElement("div");
// nodeDiv related code... setting properties and attributes
nodeDiv.innerHTML = "<div class='NodeContent'>" + node.displayText + "</div>";
nodeDiv.className = "Node";
//... more such code...
//add div to the container
container.appendChild(nodeDiv);
This code works perfectly fine.
But now I am using an ExtJs Panel wherein I want to display the same content.
How do I do it?
I tried doing:
xtype: 'panel',
autoScroll: true,
border: 10,
bodyStyle:{"background-color":"white"},
height: Ext.getBody().getViewSize().height *0.80,
id: 'treeContainer'
Ext.getCmp('treeContainer').update(nodeDiv); //this didnt work
Ext.getCmp('treeContainer').addChildEls(nodeDiv); //no success
I get this output on firing the below command in debugger:
Ext.getElementById('treeContainer')
<div class=​"x-panel x-panel-default" style=​"height:​553.6px;​" id=​"treeContainer">​
[object HTMLDivElement]
​</div>​
Any help!?

The panel's update function expects a HTML string instead of a DOM object:
// using a HTML string
Ext.getCmp('treeContainer').update("<div class='NodeContent'>" + node.displayText + "</div>");
// using a DOM object
Ext.getCmp('treeContainer').update(nodeDiv.outerHTML);
Note, that using this function will always replace all existing HTML content in the panel.
If you really want to append HTML (i.e. preserve existing HTML content), you need to get a target element to append your HTML/DOM node to.
This could be the panel's default render target element:
var panel = Ext.getCmp('treeContainer'),
renderEl = panel.isContainer ? panel.layout.getRenderTarget() : panel.getTargetEl();
// using a DOM node
renderEl.appendChild(nodeDiv);
// using a HTML string
renderEl.insertHtml('beforeEnd', "<div class='NodeContent'>" + node.displayText + "</div>");
Or - as this may change depending on your panel's layout - you just create a containg element in your initial html config:
{
xtype: 'panel',
id: 'treeContainer',
html: '<div class="html-content"></div>'
}
and append your content there:
Ext.getCmp('treeContainer').getEl().down('.html-content').appendChild(nodeDiv);
In any of the latter two cases, you should update the panel's layout afterwards, as you changed it's content manually:
Ext.getCmp('treeContainer').updateLayout();

Related

Jquery add data to html before adding to DOM

I am building html on the fly need to add data before I add it to DOM. Since I am looping thru' lot of information, I would like to add the relevant data info along with the dom I am building instead of adding the html and then looping thru again to add the data.
result.forEach(function(record) {
html += '<div id ="' record.ID + '">test content </div> ';
//add data to above
});
I can do another loop here after adding it to DOM
$(body).append(html);
testresult.forEach(function(record) {
$("#" +record.ID).data(record);
});
Instead of concatenating strings to piece together your HTML, you may way to try something like this:
result.forEach(function(record) {
$('.selector').append(function () {
var $div = $('<div></div>');
$div.attr('id', record.testID).text('some text');
return $div;
});
});
This creates a new div jquery object for each item in result. You can use the record object to add attributes, data, text, etc to you object. It will be added the DOM when the callback passed into .append returns your new jquery DOM object.
Start trying to use jQuery to create your html elements so you can take fully advantage of jQuery and its plugins.
Ex:
var div = $("<div></div>") // create the element
.text("test content") // change the inner text
.attr("id", record.testID); // set the element id
div.appendTo("body");
You can check out [http://www.w3schools.com/jquery/] as a great source for learning jQuery.
You have quotes problem in the following line :
html += '<div id =record.testID' + '>test content </div> ';
________^______________________^___^_____________________^
You should fix that using double quotes because as it's now the string will be considered as '<div id =record.testID'.
html += '<div id="'+record.testID+'">test content </div>';
Or you could use separated definition :
$.each(result, function(index,record) {
var div = $('<div>test content</div>');
div.attr('id', record.testID);
div.data('test', record.testDATA);
$('body').append(div);
})
Hope this helps.
var result = [{testID: 1,testDATA: 'data 1'},{testID: 2,testDATA: 'data 2'},{testID: 3,testDATA: 'data 3'}]
var html='';
$.each(result, function(index,record) {
var div = $('<div>test content</div>');
div.attr('id', record.testID);
div.data('test', record.testDATA);
console.log(div.data('test'));
$('body').append(div);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Do getElementById for an HTML element inside a ExtJS panel

I need to fetch an HTML element from an ExtJS panel and replace it with another HTML element.
I have a normal ExtJS panel -> rptPanel, whose innerHTML is copied to another panel -> outputDataPanel.
Please refer the code below.
var html = rptPanel.body.dom.innerHTML;
me.outputDataPanel.insert(me.itemIndex,{
html : html,
border : 0,
cls : 'htmlView_font_higher htmlView_font',
style : 'margin: 10px 0px 20px 0px; width: 100%;'
});
Now, I need to fetch an HTML element inside outputDataPanel (something like getElementById('table_data') on outputDataPanel ) and replace it with another HTML element.
Can anyone please help?
Try this (I suppose this is not Sencha's best practice):
outputDataPanel.getEl().down('#table_data')
You can set an ID to that element and get it like so:
// by id
var el = Ext.get("myDivId");
// by DOM element reference
var el = Ext.get(myDivElement);
// by id
var el = Ext.getDom('myDivId');
// by DOM element reference
var el = Ext.getDom(myDivElement);
Alternative way would be:
set an item-id to that element, lets say it's an item in the panel:
{
'text': 'myBTN',
iconCls: 'sprite',
disabled: true,
itemId: 'btn1',
handler: function(btn,e){
self.myFunction();
}
}
later on the code look for it by
this.down("#btn1")

JQuery get calling <script> tag when dynamically loaded

How can I locate the tag which calls a JQuery script, when
the tag is dynamically loaded, so won't be the last
tag on the page?
I'm using the MagicSuggest autosuggest library. I want to give certain suggested items a different background color depending on their contents, which I'm currently doing by adding JQuery inside a tag, which I'm adding on to the String which is returned to be rendered inside the selection div. Then, to get the div the item is suggested in, I need to essentially get the parent() of the tag, and change it's css() properties. How can I get this current script tag however?
I'm currently assigned each new tag an id generated from incrementing a JS variable - which works, but isn't very 'nice'! Is there anyway I can directly target the tag with JQuery?
If it perhaps makes it clearer, here is my current selectionRenderer function.
selectionRenderer: function(a){
var toRet = a.english;
var blueBgScript = "<script id=ft" + freeTextFieldID + ">$('#ft" + freeTextFieldID + "').parent().css('background', 'blue');</script>"
if(a.id==a.english){
toRet += blueBgScript;
freeTextFieldID++;
}
return toRet;
},
Why don't you add some code at afterrender event instead? Add some tag to flag the options that need a different background, then detect the parents and add a class (or edit the bg property) or whatever you like:
var newMS = $('#idStr').magicSuggest({
data: 'states.php',
displayField: 'english',
valueField: 'id',
selectionRenderer: function(a){
var toRet = a.english;
if(a.id==a.english) toRet = "<span class='freetext'>" + toRet + "</span>";
return toRet;
},
});
$(newMS).on('selectionchange', function(event,combo,selection){
var selDivs = $(event.target._valueContainer[0].parentNode).children('div'); //Get all the divs in the selction
$.each(selDivs,function(index,value){ //For each selected item
var span = $(value).children('.freetext'); //It if contains a span of class freetext
if(span.length == 1) $(value).css('background','blue'); //Turn the background blue
});

Populating HTML table with Javascript and retaining CSS style

So far I have the code below working. My only problem is the associated styles of the HTML table are not being applied when the table is inserted into its parent div. What is the best way to resolve this? I am using jQuery in tandem with jQuery mobile.
var tableBase = '<table data-role="table" id="score-table" style="margin-left: auto; margin-right: auto;" class="ui-responsive table-stroke ui-table ui-table-reflow"><thead><tr><th data-priority="1">Event</th><th data-priority="2">Score</th></tr></thead><tbody>';
function buildTable(data) {
var tableCopy = tableBase;
data.forEach(function(element, index, array) {
tableCopy = tableCopy + '<tr><td>' + element.event + '</td><td>'
+ element.points + '<td></tr>';
});
tableCopy = tableCopy + '</tbody></table>';
return tableCopy;
}
I then have have a #('#targetDiv').html(buildTable(myData)) that inserts the tables html into its div. Everything works except the styles are not applied. I am using the responsive/reflow table from jQuery mobile.
I think you have too rerun the plugin for the table after it's inserted to the DOM:
http://jquerymobile.com/demos/1.2.0-alpha.1/docs/pages/page-dynamic.html
// Pages are lazily enhanced. We call page() on the page
// element to make sure it is always enhanced before we
// attempt to enhance the listview markup we just injected.
// Subsequent calls to page() are ignored since a page/widget
// can only be enhanced once.
$page.page();
// Enhance the listview we just injected.
$content.find( ":jqmData(role=listview)" ).listview();

css styling a dojo dialog

I have a dialog that has groupings of label and ValidationTextBoxs that are programmaticly added to the the dialog. example: first name:XXXXXX
If I specify no css formatting the labels and ValidationTextBox appear nicely side by side. BUT the groupings of are smushed on top of one another with no spacing.
If I add add css for height, margin, padding. the first grouping is fine, however the following labels start at where the beginning of the of the current ValidationTextBox. not at the beginnig of the next line. so the alignment is all out of whack.
Yes I have tried individually changing the height, padding, and margins of the labels, and textbox. placing at the end of line NO LUCK. I thought of wrapping the grouping in spans or divs but get same behavior and setting the size of the enclosing div/span. BUT no luck.
could someone explain why the following function
function buildDialogField(fieldHolder, id, title, value, widgetId)
{
var newLabel, newField;
if (value === null) {
value = "";
}
newLabel = "<div class='datadiv'><label for='" + id + "'>" + title + ":</label>";
dojo.place(newLabel, fieldHolder);
newField = new dijit.form.ValidationTextBox({
id: widgetId,
name: "myData",
value: value,
trim: true
});
dojo.place(newField.domNode, fieldHolder);
dojo.place("</div>", fieldHolder);
}
generates the following html
<div class='datadiv'>
<label for='name'>me:</label>
</div>
<div id="widget_305" class="dijit dijitReset dijitInlineTable dijitLeft dijitTextBox dijitValidationTextBox" wairole="presentation" role="presentation" widgetid="305">
The ending div appears after the label but before ValidationTextBox. though that is not what I coded!!!
thanks to anyone whom helps me clear up my confusion.
You're sending invalid/incomplete HTML to dojo.place, and it (or the browser) is "completing" it for you. dojo.place isn't just an alias for elem.innerHTML += "...", but you seem to sort of be treating it as such.
I think it should actually be trivial to fix this code:
newLabel = "<div class='datadiv'><label for='" + id + "'>" + title + ":</label></div>";
dojo.place(newLabel, fieldHolder);
newField = new dijit.form.ValidationTextBox({
id: widgetId,
name: "myData",
value: value,
trim: true
});
// the following is equivalent to dojo.place(newField.domNode, newLabel)
newField.placeAt(newLabel);
To explain. the newLabel variable ends up receiving the generated top-level DOM node generated from the HTML content passed to dojo.place. (Notice I completed the HTML string by adding the ending </div>.) In this case, that's actually the div, not the label - so you might want to change the variable name.
Then, we place the widget inside that div - by default, placeAt places the widget as the last child of the specified node (just like dojo.place(nodeToBePlaced, targetNode) would by default).
You can tell it otherwise by passing another parameter - see http://dojotoolkit.org/api/dijit/_Widget/placeAt and http://dojotoolkit.org/api/dojo/place for details.

Categories