How to customize Ext JS tree nodes properly? - model-view-controller

Ext JS 4. I have a tree.Panel where I want to display custom HTML in each node, generated from that node’s model data. I can do this by setting the node’s text when loading the store, but it is not the model’s job to do markup. So I created a custom Column that renders my HTML.
My problem is: unless I derive from Ext.tree.Column, it doesn’t show up properly (no outline, plus/minus icons etc.). If I do, everything is fine, but Ext.tree.Column is marked as private to Ext JS.
Is there some officially supported API to do what I want?

I have written a blog post about how to customize ExtJS 4 tree panel, I hope it will help:
http://hardtouse.com/blog/?p=24
The idea is to use renderer combined with A LOT OF css magic:
columns : [{
xtype : 'treecolumn',
dataIndex : 'name',
renderer : function(value, record){
return Ext.String.format('<div class="tree-font">{0}</div>', value);
}]

Thanks for your answer above. Here is another example showing a few more options for formatting:
columns: [{
xtype: 'treecolumn',
dataIndex: 'text',
flex: 1,
renderer: function (value, metaData, record, rowIndex, colIndex, store, view) {
// see http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.tree.Column-cfg-renderer
var tooltipString = "Hello";
metaData.tdAttr = 'data-qtip="' + tooltipString + '"';
return Ext.String.format('{0} <span style="color:red;">{1}</span>', value, record.data.personname);
}
}]
You might also want to add
hideHeaders : true,
to your tree panel config to remove the "grid" header that appears as a result of using a treecolumn.
Murray

Related

jQuery autocomplete styling on only certain results

Is it possible to add styling to only some of the results returned in an autocomplete dropdown?
The code below works fine, however, I would like to style the individual results based on the value of data[x].restricted. When it is true, I still want to display those items but disable or grey them out within the autocomplete dropdown list. If data[x].restricted is false then I do not want to apply any additional styling to those items.
source: function (request, response) {
$.ajax({
url: $("#AutoCompleteCustomerNameUrl").val(),
type: "POST",
dataType: "json",
data: {
srchCus: request.term
},
success: function (data) {
var x, array = [];
for (x in data) {
array.push({
label: (data[x].restricted ? 'Restricted Access - ' : '') + data[x].customerName,
name: data[x].customerFullName
});
}
}
});
}
Any assistance on how to accomplish this would be much appreciated.
Approach 1 (feels hacky)
This doesn't feel like a great option, but you could probably do this by using jQuery to target elements based on their text content. Autocomplete suggestions are generated as <li>s, so something like this might work:
$('li:contains("Restricted Access")').addClass('grey');
The question is then when to run that? Those elements are added dynamically of course, after page load, so that would have to run after they've been created - you'd have to run it based on some autocomplete event. Looking through the list in the docs, maybe the open event would be best. A handler for that event will run whenever the menu is opened, so it could add a CSS class to all the just-created suggestions matching that selector. Eg (untested):
$("#selector").autocomplete({
// ... your normal autocomplete code ...
open: function(event, ui) {
// Add a CSS class to those suggestions matching the text
$('li:contains("Restricted Access")').addClass('grey');
}
});
I haven't tested this, as it doesn't feel like the right approach. Below is a much better, tested and working option.
Approach 2 (feels good)
You can also do this using the _renderItem extension point. If you check the example they give there you can see it is the function which actually generates the HTML which shows up as your autocomplete suggestion. If we can customise that, we could do anything - eg check details of the item, add specific CSS classes, etc.
I don't find those docs super clear, but it isn't hard to find examples of it in use, eg the Custom Data example (that #Simon-K linked to in the comments above) shows how to use it:
$("#selector").autocomplete({
// ... your normal autocomplete code ...
}).autocomplete("instance")._renderItem = function(ul, item) {
// Here we have complete control of what is returned, and access to
// the items!
return $("<li>").append("<div>" + item.label ...).appendTo(ul);
};
So with your requirements, we could do something like this:
$("#selector").autocomplete({
// ... your normal autocomplete code ...
}).autocomplete("instance")._renderItem = function(ul, item) {
var style = (item.restricted) ? 'grey' : '';
return $("<li>")
.append("<div class='" + style + "'>" + item.label + "</div>")
.appendTo(ul);
};
And then of course add a CSS class to style those items:
.grey {
color: #ccc;
}
Working JSFiddle.

How to wire Kendo UI Angular Chart to a datasource?

I have a Kendo UI chart with some series data. When I update the series, the chart data does not change. I see from the documentation that it needs to be wired to a datasource. But the datasource property is not available in Angular tag.
HTML
<kendo-chart
[series]="chartConfig.series"
[valueAxis] ="chartConfig.valueAxes"
[legend]="chartConfig.legend"
[title]="chartConfig.title"
[tooltip]="chartConfig.tooltip"
(seriesClick)="onSeriesClick($event)"
(drag)="onDrag($event)"
(dragStart)="dragStart($event)"
(dragEnd)="dragEnd($event)">
</kendo-chart>
Typescript
public chartConfig = {
title: {
text: 'Insight'
},
legend: {
position: 'bottom'
},
series: [], //Some data
valueAxes: [], //Some data
categoryAxis: {
categories: [],
axisCrossingValues: [24, 24, 0],
justified: true
},
tooltip: {
visible: true,
format: '{0}',
template: '#= category #/03: #= value #'
}
};
When I have an updated value, then I update the series like this.
this.chartConfig.series[seriesIndex].data[xAxisIndex] = parseInt(updatedValue.Value);
But the Chart doesn't get updated.
There is no datasource directive, you don't need anything like that. The problem is Angular not picking up changes to this.chartConfig.series.
Angular change detection checks for reference changes, not simply value changes. The simplest solution for this problem is after whatever updates you perform, change the reference of this.chartConfig.series like so:
this.chartConfig.series[seriesIndex].data[xAxisIndex] = parseInt(updatedValue.Value);
this.chartConfig.series = [...this.chartConfig.series];
That final line basically creates a new array with the same elements as the original and changes the reference of this.chartConfig.series to point to the newly created array. This makes it more likely to be picked up by Angular's change detection.

Button in jqgrid

I have been using ng-grid for displaying data and now migrating to jqgrid. I'm a newbie to this tech and I have tried creating a button which performs some other action like validating and opening a new form. I could invoke my Angular JS variable in that button. Can someone help me?
function ActionitmGridformatter(cellvalue, options, rowObject) {
var itmgrid= "";
return itmgrid;
}
$scope.itmgrid= function(row){
alert("hii");
...
};
Also the above itmgrid variable is inside the controller. Can someone post useful links for jqgrid docs and any other inputs will be helpful for me. Kindly ignore if the question is repeated and also share the relevant link.
Thanks
I recently needed to do the same thing, I had a grid of ordered products and I needed to create a link in each row that pertained to that order, here is how I went about that:
Create a function:
function orderLinkFormatter (cellvalue, options, rowObject) {
var base = window.location.origin;
return '' + rowObject.OrderNumber + '';
}
In your grid change you colModel to look like this:
{ name: 'OrderId', index: 'OrderId', width: 100, search: false, formatter:orderLinkFormatter, align: 'center'},
You will end up with something like in this DEMO.
Or this DEMO
I would also suggest that you try using free-jqgrid, it is a free fork of jqgrid that is updated almost daily and the author: Oleg provides really good support on this site.

jqgrid group header not showing ampersand character in IE 7/8

I am using jqgrid to show dynamic data in it, my sql stored procedure returns some data as "T & E". I am displaying this data in group header, i can only see "T" in the group header the rest of the data is trimmed down in IE 7/8. The same thing when i run it in Firefox it show correctly as "T & E". Please tell me the solution for this problem, any help would be appreciated.
I have tried the autoencode property setting it to true, but it did not work,
I have kept the meta tag character encoding utf-8 in the aspx file.
I had similar issue while editing . This link helped me to attain what i wanted with some tweaks.
My system config.
Win 7 with IE8
While editing, the text after the '&' was lost. Eg: If we had text like 'a&a' only 'a' used to show up in the grid and get saved eventually.
The custom formatter how ever did the trick for me.
//In col Model
//Assuming description is one of your column in the jqGrid
//Note the formatter , this is the custom formatter which does the magic for us in this case.
{ name: 'Description', index: 'Description', align: "center", sorttype: 'text', sortable: true, resizable: false, editable: editGrids, formatter: formatTextDisplay,unformat:unformatTextDisplay}
//Formatter code
var formatTextDisplay = function (cellval, opts, action) {
if (cellval) {
return $.jgrid.htmlEncode(cellval);
};
return "";
}
//Un formatter code, in case you want to read through the text in its original state from the grid for processing in the javascript file.
var unformatTextDisplay = function (cellval, opts, action) {
if (cellval) {
return $.jgrid.htmlDecode(cellval);
};
return "";
}

jqGrid 4.2 Custom search with non-grid fields

I'm using jqGrid 4.2 with the filterToolbar, which works great. I'd like to add some type of custom search to query (server-side) fields that are not part of the colModel.
Prior to 4.0 I would have used filterGrid along the lines of this:
$('#keyword').jqGrid('filterGrid', '#ticket-grid',
{
gridModel: false,
filterModel: [
{ label: 'Keyword', name: 'keyword', stype: 'text'},
{ label: 'Inclued Closed?',name : 'includeClosed', stype: 'checkbox'}
]
});
I understand that this is no longer supported, and an stype: 'checkbox' doesn't work anyway.
How do I do this with the new search module/mechanism?
If I understand you correct you have already on the page, for example above the grid, some controls (text input, selects, chechboxes) which allow the user to define additional criteria of the results which the user want see in the grid. In the case you can use postData with methods (functions) in the way described in the old answer.
If any kind of grid refreshing: request to filter the data from the searching toolbar, changing of the page or the page size, changing of sorting and so on will always follow to the Ajax request to the server. In the case the properties from postData option of jqGrid will be added like other standard parameters (sidx, sord, page, ...). If one from the properties of the postData is defined as function (if a method of postData) then the function will be called to construct the parameter which will be sent to the server. So the current information from you custom searching controls (text input, selects, chechboxes) will be send to the server. In the way you need only use the parameters on the backend to filter the results.
So you have to define fields yourself. For example the text input with id="keyword-input" and checkbos with id="includeClosed" and then use postData in about the following form:
$('#keyword').jqGrid(
// ... other jqGrid options
postData: {
keyword: function () { return $('#keyword-input').val(); },
includeClosed: function () { return $('#includeClosed')is(':checked'); },
}
});

Resources