Basically I am i need of an Ext.Panel which contains an XML-Editor together with syntax-highlighting, line numbers and editing.
I have searched through the web and found the Javascript API CodeMirror.
I have implemented something, but the alignment of the CodeMirror-object-Textfield does not adjust itself to the Top/left of the Ext.Panel and also no line-numbers are seen:
<!DOCTYPE html>
<html>
<head>
<!-- ext imports -->
<script type="text/javascript" language="javascript" src="/ext-5.1.1/build/ext-all-debug.js"></script>
<link rel="stylesheet" type="text/css" href="/ext-5.1.1/build/packages/ext-theme-neptune/build/resources/ext-theme-neptune-all.css">
<script type="text/javascript" src="/ext-5.1.1/build/packages/ext-theme-neptune/build/ext-theme-neptune.js"></script>
<!-- codemirror imports -->
<script type="text/javascript" language="javascript" src="/CodeMirror-master/lib/codemirror.js"></script>
<link rel="stylesheet" href="/CodeMirror-master/lib/codemirror.css">
<script type="text/javascript" src="/CodeMirror-master/mode/xml/xml.js"></script>
<script type ="text/javascript">
Ext.onReady(function(){
var panel_1 = Ext.create('Ext.panel.Panel', {
frame:true,
id: 'panel_1_id',
title: 'panel_1',
padding: '10 10 10 10',
margin: '10 10 10 10',
autoScroll: true
});
var vp = new Ext.Viewport({
layout: 'fit',
items: [panel_1],
autoScroll: true,
renderTo : Ext.getBody()
});
var myCodeMirror = CodeMirror(panel_1.body, {
value: "<XXX><YYY><AAA>foo1</AAA></YYY><ZZZ>foo2</ZZZ></XXX>"
});
});
</script>
</head>
<body>
</body>
</html>
So the following questions arise:
1.) I thought about extending Ext.Component and somehow pack the CodeMirror object inside it?
Is this possible?
2.) Is it possible to adapt my little codeexample from above to align it correctly?
This can be solved with a few slight tweaks to your code.
The key point here is that the behaviour of CodeMirror will vary depending on the type of the first parameter you pass to the CodeMirror constructor. Passing a HTML element (as in your example) will result in the HTML DOM function appendChild() being called. And this is why there is a large space before your new element, because it is being appended after the body of the panel.
If you pass in a function (acting as a callback) to the CodeMirror constructor then you will be returned with the HTML element that is the CodeMirror. Constructing the element this way enables you to replace the body element of the panel with the new HTML element (rather than appending).
This can be achieved by creating a simple function. The code changes you require are as follows....
Create a function to pass to CodeMirror constructor
var codeMirrorCallbackFunction = function(codeMirrorEl) {
var panelDom = panel_1.el.dom;
// the node at index 1 is the body (index 0 is panel header)
panelDom.replaceChild(codeMirrorEl, panelDom.childNodes[1]);
};
Create the CodeMirror object passing the function as 1st parameter
var myCodeMirror = CodeMirror(codeMirrorCallbackFunction, {
value: "<XXX><YYY><AAA>foo1</AAA></YYY><ZZZ>foo2</ZZZ></XXX>"
});
Update the padding of the Panel
// without this change the panel header and codemirror html overlap
padding: '25 10 10 10'
You are doing good, you only need to add a property like
var myCodeMirror = CodeMirror(panel.body, {
value: "<XXX><YYY><AAA>foo1</AAA></YYY><ZZZ>foo2</ZZZ></XXX>",
lineNumbers: true
});
Related
Note: I just vastly simplified the program and have left it with the bare essentials ...
So I am trying to add graphs within a sigma.js graph. First, let me post the javascript (sigmaAngualr.js) ...
app = angular.module('sigmaAngular', []);
app.controller('NetworkDataCtrl', function($scope){
var i, s;
$scope.newName = null;
$scope.s = null;
$scope.N = 3;
$scope.newNode = function (id, label){
return {id: id,
label: label,
x: Math.random(),
y: Math.random(),
size: Math.random()+0.2,
color:'#333'}
};
$scope.addNodeGraph = function(id, label){
$scope.s.graph.addNode($scope.newNode(id, label));
console.log(id+'-'+label);
};
$scope.tempNodes = [];
for( i=0; i<$scope.N; i++ )
$scope.tempNodes.push($scope.newNode('id'+i, 'Node'+i));
$scope.s = new sigma({graph:{nodes:$scope.tempNodes, edges:[]}})
});
app.directive('showGraph', function(){
// Create a link function
function linkFunction(scope, element, attrs){
scope.s.addRenderer({container: element[0]})
};
return {
scope: false,
link: linkFunction
}
});
And here is the HTML ...
<!DOCTYPE html>
<html>
<head>
<title>Using AngularJS</title>
<script type="text/javascript" src='lib/sigma/sigma.min.js'></script>
<script type="text/javascript" src='lib/angular/angular.min.js'></script>
<script type="text/javascript" src='lib/sigmaAngular.js'></script>
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body ng-app='sigmaAngular'>
<div>
<div ng-controller='NetworkDataCtrl'>
<input type='text' ng-model='newName' />
<button ng-click='addNodeGraph(newName,newName)'> Add Node </button>
<hr>
<div show-graph id='graph-container' s='s' tempNodes='tempNodes'>
</div>
<hr>
</div>
</div>
</body>
</html>
Of course, I am unable to add a node to the graph.
I had also tried another option of creating an entire graph when I add a node. That doesnt work either. (This is no longer true)
Let me try to explain. Now,
When I refresh the browser, I do not see a graph.
When I resize the browser window The graph suddenly appears.
When I type a random name and hit the Add Node button, the graph doesnt change.
When I resize the browser window, the graph changes to reveal the new node.
So in summary, I have to resize the browser window to see any changes in the graph.
Just a side note: The css is below:
#graph-container {
position: relative;
width: 200px;
height: 200px;
border: 1px solid indianred;
}
I feel now that I am really close to solving the problem. Just a tiny bit off somewhere ...
Any help will be greatly appreciated!!!
I am doing an HTML to pdf conversion with jspdf
Here is my running code...
http://codepen.io/anon/pen/dPZaYN
You can see the output (below) is different from the PDF..There are no borders and alignment.
I am not able to achieve simple layout / alignment , padding/float etc..
This is how it should look (you can also see here my Html code)
http://screencast.com/t/xE6fbJKrA9m
But when i Get the pdf of this from jspdf it looks like this
http://screencast.com/t/z8cizeY9
This is my jspdf Code ..
var doc = $wnd.jsPDF('p', 'pt', 'a4', true);
var source = $('#content').first();
var specialElementHandlers = {
'#bypassme': function (element, renderer) {
return true;
}
};
doc.fromHTML(
htmltest,
{
'elementHandlers': specialElementHandlers
});
doc.save('Test.pdf');
This is my head
<script type="text/javascript" src="jspdf/jspdf.js"></script>
<script type="text/javascript" src="jspdf/FileSaver.js"></script>
<script type="text/javascript" src="jspdf/jspdf.min.js"></script>
<script type="text/javascript" src="jspdf/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="jspdf/libs/adler32cs.js"></script>
<script type="text/javascript" src="jspdf/BlobBuilder.js"></script>
<script type="text/javascript" src="jspdf/jspdf.plugin.addimage.js"></script>
<script type="text/javascript" src="jspdf/jspdf.plugin.standard_fonts_metrics.js"></script>
<script type="text/javascript" src="jspdf/jspdf.plugin.split_text_to_size.js"></script>
<script type="text/javascript" src="jspdf/jspdf.plugin.from_html.js"></script>
jsPDF's html plugin does not support most css. But despair not, here is a work around.
Try it out:
$( 'a' ).hide();
html2canvas( document.body, { onrendered : function( canvas ) { 'use strict';
var pdf = new jsPDF(), border = 10, width = 210-border*2;
pdf.addImage( canvas.toDataURL( 'image/jpeg' , 0.98 ), 'JPEG',
border, border, width, canvas.height*width/canvas.width );
// pdf.save() does not work on StackOverflow because of cross origin restriction
$('a').show()[0].href = pdf.output( 'dataurlstring' );
// IE 11 does not allow datauri pdf, use save() instead
} } );
body{font:12px "Times New Roman",serif;}h1{font-size:24px;line-height:24px;font-weight:bold;margin-top:0;text-align:right;margin-bottom:5px;}#render_me > div > div{float:right}#render_me > div > div > div{border-bottom:1px solid black;border-right:1px solid black;padding:3px; text-align:center}.b_top{border-top:1px solid black;}.f_c_b_left:last-child{border-left:1px solid black;}
PDF<br>(Ctrl+Click me or open me in new window)
<div id="render_me"><div>
<h1>Invoice</h1>
<div><div class="b_top">Invoice #</div><div>00001-2</div></div>
<div class="f_c_b_left"><div class="b_top">Date</div><div>2015-02-05</div></div>
</div></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<script src='http://parall.ax/parallax/js/jspdf.js'></script>
The idea is, renders the HTML onto a canvas using html2canvas, then put the screenshot into PDF.
This is not perfect, but at least the elements will be in correct positions and alignments.
Drawbacks:
Like jsPDF's HTML renderer, html2canvas understand few CSS. The major difference is that html2canvas can access the layout did by the browser.
The image only have 96dpi, causing low quality.
Result PDF will be relatively big.
For now, this is my best HTML to PDF solution.
To get better result, I will manually build the PDF (without HTML).
I cannot get the pdf link in this example to open in new window or download, as long as it is ran in StackOverflow's Code snippet. If you put the code elsewhere you can call pdf.save like this fiddle: http://jsfiddle.net/xwksc4ku/1
I am having trouble creating multiple bars with flot. There is a plugin that can be downloaded here: http://www.benjaminbuffet.com/public/js/jquery.flot.orderBars.js that makes graphs with multiple bars per x category like this: http://www.pikemere.co.uk/blog/tutorial-flot-how-to-create-bar-charts/ (see under the customized bar charts). However, his example is a bit different in that it uses the time function rather than categories.
Here is my code:
<!doctype html>
<head>
<script language="javascript" type="text/javascript" src="/flot/jquery.js"></script>
<script language="javascript" type="text/javascript" src="/flot/jquery.flot.js"> </script>
<script language="javascript" type="text/javascript" src="/flot/jquery.flot.categories.js"></script>
<script language="javascript" type="text/javascript" src="/flot/jquery.flot.orderBars.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var data1 = [
{
label: "Male" ,
data: [["True", 1],["False", 2]] ,
bars: {
show: true,
barWidth: 0.13,
order: 1
}
},
{
label: "Female" ,
data: [["True", 3],["False", 4]],
bars: {
show: true,
barWidth: 0.13,
order: 2
}
}
];
$.plot($("#placeholder"), data1, {
xaxis: {
mode: "categories"
},
});
});
</script>
<title>Test</title>
</head>
<body>
<div id="placeholder" style="width:600px;height:300px"></div>
</body>
</html>
With the above code, the graph displays, but without any bars. If I remove the order:1 and order:2, it displays correctly, except with the bars overlapping each other rather than being offset by each other (I think it just ignores the orderbars plugin).
This is a very simplified example of what I really want to do, but if someone knows how I can get it to do what I want fairly simply, I would be very much appreciative.
To sum up, what I want is to have two sets of two bars. The first set with "True" under them and the second second set with "False" under them. I do not want to use numbers to represent the values, if possible as it will greatly complicate my more complex situation. But if I must, I would still like to know how to do it that way.
change the function getAxeMinMaxValues in orderBars.js
function getAxeMinMaxValues(series, AxeIdx) {
var minMaxValues = new Array();
for (var i = 0; i < series.length; i++) {
series[i].data[series[i].data.length - 1][AxeIdx];
minMaxValues[0] = 0;
minMaxValues[1] = series[i].data.length - 1;
}
return minMaxValues;
}
hope this will help
Good Afternoon!
I am trying to upgrade from version 4.0.7 to 4.1.1 (downloaded as a free 45 days trial) in order to test the version 4.1 in the application we have running at the moment and see how many changes we may need to do before the formal upgrade, the only step I did was pointing my jsp file to the new files in the head of the page as follows:
<link rel="stylesheet" href="3rdParty/ext-4.1.1a/resources/css/ext-all.css"/>
<script type="text/javascript" charset="utf-8" src="3rdParty/ext-4.1.1a/ext-all-debug.js"></script>
And in my jsp page I am doing something very simple, just creating a button, I used this code:
<body>
<script type="text/javascript">
Ext.create('Ext.Button', {
text: 'Test window',
width: 75,
renderTo: Ext.getBody(),
handler: function() {
alert("the button worked"");
}
});
</script>
</body>
but nothing is being displayed when I run this page, when I use the development tool of google chrome, the console is displaying me this message:
Uncaught TypeError: Cannot call method 'createChild' of undefined
When I debugged the code, the error appears in the file ext-all-debug.js:20687
getStyleProxy: function(cls) {
var result = this.styleProxyEl || (Ext.AbstractComponent.prototype.styleProxyEl = Ext.resetElement.createChild({
style: {
position: 'absolute',
top: '-10000px'
}
}, null, true));
result.className = cls;
return result;
},
What step am I missing?, I am pretty new in extjs and as far as I understand, the upgrade from version 4.0.7 to 4.1.1 should not involve many steps different to some different ways of writing the code, can somebody help me please?
Many thanks in advance!
Try to put your code inside an onReady block:
<body>
<script type="text/javascript">
Ext.onReady( function() {
Ext.create('Ext.Button', {
text: 'Test window',
width: 75,
renderTo: Ext.getBody(),
handler: function() {
alert("the button worked");
}
});
});
</script>
</body>
I am trying to implement a simple editable table using SlickGrid using example1_simple (found here http://mleibman.github.com/SlickGrid/examples/example1-simple.html) as a template, but its gone terribly wrong.
My grid has to fit within a tab on the form that is 280 pixels wide and will have 3 columns (id, X, Y). The id will be autoincrementing and x & y will be blank, but for testing I am putting a gradually lengthening string in each cell so on the first row it should read 0, a, b and the second row would contain 1, aa, bb, etc. However each cell is being drawn below the previous, so that row 1 contains '0', row 2 contains '1' and 'a' drawn over each other, and row 3 contains '2', 'aa', and 'b' and so on. I've temporarily put it up on my website http://www.nutanageophysics.com/IFP/test.html so everyone can see. (quick side question - what's best way to preserve live examples such as this?)
Here's my test html file
<!DOCTYPE html>
<html>
<head>
<title>Nutana Project Planner</title>
<link rel="stylesheet" href="css/style.css" type="text/css" media="screen">
<link rel="stylesheet" href="css/jquery-ui-1.8.16.custom.css" type="text/css"/>
<script src="js/jquery-1.7.min.js"></script>
<script src="js/jquery.event.drag-2.0.min.js"></script>
<script src="js/slick.core.js"></script>
<script src="js/slick.grid.js"></script>
<script src="js/xyGrid.js"></script>
<script type="text/javascript">
var xyGrid;
function initialize() {
xyGrid = new Slick.Grid("#xyGrid", data, columns, options);
}
</script>
</head>
<body onload="initialize();">
<div id=xyGrid >
<!-- the grid is going to be placed here by onLoadXML -->
</div>
</body>
</html>
My SlickGrid code is in xyGrid.js, included here:
var data = [];
var columns = [
{id: "id", name: "id", field: "id"},
{id: "x1", name: "X", field: "x1"},
{id: "y1", name: "Y", field: "y1"},
];
var options = {
enableCellNavigation: true,
enableColumnReorder: false,
};
$(function () {
var a='a';
var b='b';
for (var i = 0; i < 10; i++) {
data[i] = {
id: i,
x1: a,
y1: b,
};
a +="a";
b += "b";
}
})
The only other possible relevant thing is i've defined the style for xyGrid in css as
#xyGrid {
width: 280px;
height: 500px;
}
I've tried changing the width to no effect. All of the other relevant css is in the jquery.ui.css which I haven't touched. I've also unsuccessfully tried a bunch of different Grid options, but the two used here are those used in the example. I've also built a table around my div as in the example but they were using the table for other purposes and it isn't relevant.
Please help.
Thanks,
Marc Pelletier
I believe you're missing the stylesheet:
http://mleibman.github.com/SlickGrid/slick.grid.css
I re-created it locally and it looks okay with that included. Double-check you have all the sheets and scripts included in the original example.
(You can use jsfiddle.net for some sample code. Not sure if it could accommodate all this!)