ExtJS 4 - Printing Panels does not render Checkboxes and Radio Buttons? - extjs

I am building an ExtJS4 Web Application. I have a form that the user can fill up. I am able to do basic CRUD on the data that the user inputs. I added functionality to this by enabling the user to print the form. To achieve this, I wrote an override for the form.Panel X-Types as such. I modified a code I found online:
print: function(pnl) {
if (!pnl) {
pnl = this;
}
// instantiate hidden iframe
var iFrameId = "printerFrame";
var printFrame = Ext.get(iFrameId);
if (printFrame === null) {
printFrame = Ext.getBody().appendChild({
id: iFrameId,
tag: 'iframe',
cls: 'x-hidden',
style: {
display: "none"
}
});
}
var cw = printFrame.dom.contentWindow;
var stylesheets = "";
var markup;
// instantiate application stylesheets in the hidden iframe
var printTask = new Ext.util.DelayedTask(function(){
// print the iframe
cw.print();
// destroy the iframe
Ext.fly(iFrameId).destroy();
});
var strTask = new Ext.util.DelayedTask(function(){
var str = Ext.String.format('<html><head>{0}</head><body>{1}</body></html>',stylesheets,markup);
// output to the iframe
cw.document.open();
cw.document.write(str);
cw.document.close();
// remove style attrib that has hardcoded height property
// cw.document.getElementsByTagName('DIV')[0].removeAttribute('style');
printTask.delay(500);
});
var markUpTask = new Ext.util.DelayedTask(function(){
// get the contents of the panel and remove hardcoded overflow properties
markup = pnl.getEl().dom.innerHTML;
while (markup.indexOf('overflow: auto;') >= 0) {
markup = markup.replace('overflow: auto;', '');
}
while (markup.indexOf('background: rgb(255, 192, 203) !important;') >= 0) {
markup = markup.replace('background: rgb(255, 192, 203) !important;', 'background: pink !important;');
}
strTask.delay(500);
});
var styleSheetConcatTask = new Ext.util.DelayedTask(function(){
// various style overrides
stylesheets += ''.concat(
"<style>",
".x-panel-body {overflow: visible !important;}",
// experimental - page break after embedded panels
// .x-panel {page-break-after: always; margin-top: 10px}",
"</style>"
);
markUpTask.delay(500);
});
var styleSheetCreateTask = new Ext.util.DelayedTask(function(){
for (var i = 0; i < document.styleSheets.length; i++) {
stylesheets += Ext.String.format('<link rel="stylesheet" href="{0}" />', document.styleSheets[i].href);
}
styleSheetConcatTask.delay(500);
});
styleSheetCreateTask.delay(500);
}
I used the delay functions to ensure that the function finishes its operations because there are times that the print preview fails.
This code works, it can print out text fields, labels, as well as field sets. However, it does not render radio buttons at all. Now, I am not sure why it does not.

Related

how to bind property of visibility of dropdown

I want to change the color of label when dropdown is shown and return the color of label to normal when dropdown hides. How can I do it with binding?
so there will be a property
property: {
icon: {
check: Boolean,
apply: handleVisibility
}
}
this.handleVisibility = function(value) {}
this.bind()?
my code
var label = new qx.ui.basic.Label("Default");
label.setFont("bold");
this.getRoot().add(label, {
left: 20,
top: 20,
});
// create a combo box
var comboBox = new qx.ui.form.ComboBox();
// fill the combo box with some stuff
for (var i = 1; i < 31; i++) {
var tempItem = new qx.ui.form.ListItem(
"2^ " + i + " = " + Math.pow(2, i)
);
comboBox.add(tempItem);
}
// add the combobox to the documents root
this.getRoot().add(comboBox, {
left: 20,
top: 40,
});
I've appended about 20 lines to your code, here, to show how you might do it. You can plug this into https://playground.qooxdoo.org to test it.
var label = new qx.ui.basic.Label("Default");
label.setFont("bold");
this.getRoot().add(label, {
left: 20,
top: 20,
});
// create a combo box
var comboBox = new qx.ui.form.ComboBox();
// fill the combo box with some stuff
for (var i = 1; i < 31; i++) {
var tempItem = new qx.ui.form.ListItem(
"2^ " + i + " = " + Math.pow(2, i)
);
comboBox.add(tempItem);
}
// add the combobox to the documents root
this.getRoot().add(comboBox, {
left: 20,
top: 40,
});
// Get easy access to the textfield of the comboBox and its popup list
let textfield = comboBox.getChildControl("textfield");
let popup = comboBox.getChildControl("popup");
// When the popup's `visibility` property changes, modify the textfield's
// `backgroundColor` property. The value of the `visibility` property will be
// "hidden" or "visible". We use a `converter`, to convert the value
// from one of those, to the color to be used. (A color of `null`, used in
// this example when the popup is hidden, means use the default color.)
popup.bind(
"visibility",
textfield,
"backgroundColor",
{
converter : function(data, model, source, target)
{
return data == "visible" ? "cyan" : null;
}
});

Export Kendo chart to pdf with a logo in angularJS

Here is my code of angularjs to export only pdf but i want to export with a custom logo. Any help on this question?
My Kendo Chart HTML Code is here:
<div kendo-chart="vm.chart"
k-options="vm.chartOptions"
k-data-source="vm.chartOptions.datasource">
</div>
And Export Button code is here..
vm.saveAsPdf = function (event) {
var elem ;
if (navigator.userAgent.indexOf("Chrome") !== -1) {
elem = event.toElement;
}
else {
elem = event.currentTarget;
}
//$(elem).parent().next().find('.k-chart').getKendoChart().saveAsPDF();
debugger;
var chart = $(".k-chart").getKendoChart();
var fileName = $(elem).closest('li').children().find('.ng-binding').text().trim();
chart.exportPDF({ paperSize: "auto", margin: { left: "1cm", top: "1cm", right: "1cm", bottom: "1cm" } }).done(function (data) {
kendo.saveAs({
dataURI: data,
fileName: fileName + ".pdf"
});
});
}
Use the render event of the chart to draw on its surface once the chart has been rendered.
Then use the Kendo Drawing Image to add the logo.
render: function(e){
var chart = e.sender;
var draw = kendo.drawing;
var geom = kendo.geometry;
var rect = new geom.Rect(
[50, 0], // Position of the top left corner
[400, 60] // Size of the rectangle
);
var image = new draw.Image("https://www.w3.org/Icons/SVG/svg-logo-h.svg", rect);
chart.surface.draw(image);
}
DEMO
In the demo I am adding a random image near the top left of the chart.

How can I hide a (ionic) header without hiding the entire content of the templates?

I have 2 headers and I want to hide the 2nd when scrolling trough the content, which is implemented with 'ion-slide-box' and 'ion-slide' to be able to slide the tabs and change from one template to the other (with different controller each template).
.scroll-content{
top: 0 !important;
bottom: 0 !important;
}
1st header implemented in a directive template
<fake-statusbar></fake-statusbar>
2nd header
<ion-content scroll="false" class="bar-positive">
<ion-slide-box slide-tabs-scrollable="false" show-pager="false" ion-slide-tabs>
<ion-slide ion-slide-tab-label="Catalog"><ion-nav-view name="tab-games"></ion-nav-view></ion-slide>
<ion-slide ion-slide-tab-label="Social"><ion-nav-view name="tab-chats"></ion-nav-view></ion-slide>
<ion-slide ion-slide-tab-label="Video"><ion-nav-view name="tab-videos"></ion-nav-view></ion-slide>
</ion-slide-box>
</ion-content>
I am trying to call the 'slidingTabs' class which is by default the class of the 2nd header (is hidden), in a different directive to hide that selected class when scrolling trough the content.
.directive('headerShrink', function ($document, $ionicScrollDelegate) {
var fadeAmt;
var shrink = function (header, content, amt, max) {
amt = Math.min(44, amt);
fadeAmt = 1 - amt / 44;
ionic.requestAnimationFrame(function () {
header.style[ionic.CSS.TRANSFORM] = 'translate3d(0, -' + amt + 'px, 0)';
for (var i = 0, j = header.children.length; i < j; i++) {
header.children[i].style.opacity = fadeAmt;
}
});
}; return {
restrict: 'A',
link: function ($scope, $element, $attr) {
var starty = $scope.$eval($attr.headerShrink) || 0;
var shrinkAmt; var header = $document[0].body.querySelector('div.slidingTabs');var headerHeight = header.offsetHeight; $element.bind('scroll', function (e) {
var scrollTop = null;
if (e.detail) {
scrollTop = e.detail.scrollTop;
} else if (e.target) {
scrollTop = e.target.scrollTop;
}
if (scrollTop > starty) {
// Start shrinking
shrinkAmt = headerHeight - Math.max(0, (starty + headerHeight) - scrollTop);
shrink(header, $element[0], shrinkAmt, headerHeight);
} else {
shrink(header, $element[0], 0, headerHeight);
}
});
}
};
})
and I add in each template content 'header-shrink scroll-event-interval="5"'
All of this works only for the 1st header class (to hide the 1st header) or when I call the class 'bar-positive' which hide the whole content. NOT with' .slidingTabs' class. Can someone have an idea why it doesn't work? Or maybe can someone give me a hint of how to implement it? I am trying to guide myself from these two demos
Shrinking Header: Nightly
and
Facebook Style Shrinking Header & Tabs Ionic beta.13 tabs

kendo grid with kendo tooltip from an inline template does not work

I have a kendo Grid with tooltip displaying the details in a kendo tooltip. The following template when used as an external template works. However, i am unsure if the template can be passed as an inline template.
Here is my code,
External Template
<script id="javascriptTemplate" type="text/x-kendo-template">
<ul>
# for (var i = 0; i < data.applications.length; i++) { #
<li>#= data.applications[i].name #</li>
# } #
</ul>
</script>
and it is called in teh controller as,
$scope.toolTipOptions = {
filter: "td:nth-child(4)",
position: "right",
content: function(e) {
var grid = e.target.closest(".k-grid").getKendoGrid();
var dataItem = grid.dataItem(e.target.closest("tr"));
var template = kendo.template($("#javascriptTemplate").html());
return template(dataItem);
},
show: function(e) {
this.popup.element[0].style.width = "200px";
this.popup.element[0].style.left = "10px";
}
}
But when i try to pass an inline template , it complains that template is not a function. any pointers as to how i could pass an inline template in this case
$scope.toolTipOptions = {
filter: "td:nth-child(4)",
position: "right",
content: function(e) {
var grid = e.target.closest(".k-grid").getKendoGrid();
var dataItem = grid.dataItem(e.target.closest("tr"));
var template = "<ul>\# for (var i = 0; i < data.applications.length; i++) { #<li>#= data.applications[i].name #</li>\# } #</ul>"
return template(dataItem);
},
show: function(e) {
this.popup.element[0].style.width = "200px";
this.popup.element[0].style.left = "10px";
}
}
In the second solution, you probably just need kendo.template(). In your code, template is defined one line above, as a string.

Extjs htmleditor wont set doctype and head tags

I am building a section in my app where you can send emails.
In order to do that, this user needs to paste a complete html content and preview it with the html editor in extjs.
The problem is that Extjs remove head and body and changing the doctype tag
have a look here, click on the buttons at the bottom: http://jsfiddle.net/LKJSm/
Ext.onReady(function () {
Ext.tip.QuickTipManager.init();
var top = Ext.create('Ext.form.Panel', {
items: [{
xtype: 'htmleditor',
name: 'htmlContent',
height: 300,
anchor: '100%'
}],
buttons: [{
text: 'Set doctype with head and body',
handler: function () {
top.down('htmleditor').setValue("<DOCTYPE /><head></head><body>body here</body>");
}
}, {
text: 'Alert Content',
handler: function () {
var editor = top.getForm().findField('htmlContent');
alert(editor.getValue());
}
}]
});
top.render(document.body);
});
here is a solution provided in Extjs forums: http://www.sencha.com/forum/showthread.php?146160-HTMLEditor-strips-dtd-head-and-body-tags
Ext.define('MyHTMLEditor', {
extend:'Ext.form.HtmlEditor',
alias: 'widget.myhtmleditor',
tagsToComment: ['!DOCTYPE', 'html', 'head', 'body'],
/**
* Pushing value to wysiwyg iframe loses dtd, html, head and body tags.
* Override hack to comment them out when pushing to iframe, and then uncomment
* them on the way back (see this.cleanHtml).
*/
pushValue: function() {
var me = this,
v;
if(me.initialized){
v = me.textareaEl.dom.value || '';
if (!me.activated && v.length < 1) {
v = me.defaultValue;
}
if (me.fireEvent('beforepush', me, v) !== false) {
///////////// change
for (var i=0;i<me.tagsToComment.length;i++) {
v = v.replace(RegExp('<(\s*\/?'+me.tagsToComment[i]+'.*?)>', 'ig'), '<!--$1-->');
}
/////////////
me.getEditorBody().innerHTML = v;
if (Ext.isGecko) {
// Gecko hack, see: https://bugzilla.mozilla.org/show_bug.cgi?id=232791#c8
me.setDesignMode(false); //toggle off first
me.setDesignMode(true);
}
me.fireEvent('push', me, v);
}
}
},
/**
* Uncomment the tags mentioned in pushValue
*/
cleanHtml: function(html) {
var me = this, i,
result = me.callParent(arguments);
for (i=0;i<me.tagsToComment.length;i++) {
result = result.replace(RegExp('<!--(\s*\/?'+me.tagsToComment[i]+'.*?)-->', 'ig'), '<$1>');
}
return result;
},
});
use of html tags are not allowed, in fact they are identified as thereat. if you want the tags to be displayed you need to change as follows
top.down('htmleditor').setValue("<DOCTYPE /> <head></head><body>body here</body>");
this will display the tags on the editor for now.
if you don't want them to show up on the editor you need to concatenate the tags when you pass it to the email client.

Resources