Custom control - data binding not working - javascript

I am currently trying to extend a sap.m.Input field to be able to style and extend the label placement.
The rendering works fine, but somehow the data-binding gets lost in the process and i am unsure why that is. This is my control:
sap.ui.define([
'sap/m/Input',
], function(Input) {
'use strict';
return Input.extend('one.sj.control.BhTextInput', {
metadata: {
properties: {
label: {
type: 'string',
},
},
aggregations: {
icon: {
type: 'sap.ui.core.Icon',
multiple: false,
visibility: 'public',
},
},
},
renderer: function(oRM, oControl) {
oRM.write('<div class="formControl">');
oRM.write('<input placeholder="'+oControl.getPlaceholder()+'"');
oRM.write('type="'+oControl.getType()+'"');
oRM.write('value="'+oControl.getValue()+'"');
oRM.writeClasses();
oRM.writeControlData(oControl);
oRM.write('/>');
oRM.write('<label class="inputLabel" for="'+oControl.getId()+'"');
oRM.write('>');
oRM.renderControl(oControl.getIcon());
oRM.write('<span class="inputLabelContent">');
oRM.write(oControl.getLabel());
oRM.write('</span>');
oRM.write('</label>');
oRM.write('</div>');
},
});
});
As you can see it is quite simple.
This is how i use it:
<sj:BhTextInput
id="username" class="input textInput"
placeholder="{i18n>HINT_USERNAME}" value="{creds>/username}"
type="Text">
<sj:icon>
<core:Icon src="sap-icon://email" class="inputIcon" />
</sj:icon>
</sj:BhTextInput>
I confirmed that is not a problem of my model, as it works fine when i replace the manual <input/> construction in the renderer method above with:
sap.m.InputRenderer.render(oRM, oControl);
Can you spot anything wrong? Thanks!
EDIT: To clarify a bit on what i mean by "data-binding gets lost". I am only getting an empty string when accessing the value bound to the Input field inside my controller like this: getModel('creds').getProperty('/username');. This does work when replacing the manual construction as written above.

I'm not sure if this is what causing your problem but I believe oRM.write doesn't add spaces to your rendered HTML. It is better to use oRM.writeAttribute for writing attributes. Also class should be added using oRM.addClass.

Ok. There are couple of changes that are required to get it working.
Note 1: The InputBase API ( parent of sap.m.Input) needs your <input> tag to have an id containing "inner" to fetch its value properly. This is from INputBase API:
/**
* Returns the DOM value respect to maxLength
* When parameter is set chops the given parameter
*
* TODO: write two different functions for two different behaviour
*/
InputBase.prototype._getInputValue = function(sValue) {
sValue = (sValue === undefined) ? this.$("inner").val() || "" : sValue.toString();
if (this.getMaxLength && this.getMaxLength() > 0) {
sValue = sValue.substring(0, this.getMaxLength());
}
return sValue;
};
So, on every change, it reads the DOM value and then updates the control metadata.
/**
* Handles the change event.
*
* #protected
* #param {object} oEvent
* #returns {true|undefined} true when change event is fired
*/
InputBase.prototype.onChange = function(oEvent) {
// check the control is editable or not
if (!this.getEditable() || !this.getEnabled()) {
return;
}
// get the dom value respect to max length
var sValue = this._getInputValue();
// compare with the old known value
if (sValue !== this._lastValue) {
// save the value on change
this.setValue(sValue);
if (oEvent) {
//IE10+ fires Input event when Non-ASCII characters are used. As this is a real change
// event shouldn't be ignored.
this._bIgnoreNextInputEventNonASCII = false;
}
// get the value back maybe formatted
sValue = this.getValue();
// remember the last value on change
this._lastValue = sValue;
// fire change event
this.fireChangeEvent(sValue);
// inform change detection
return true;
} else {
// same value as before --> ignore Dom update
this._bCheckDomValue = false;
}
};
So, I changed your renderer method of the control like this:
renderer: function(oRM, oControl) {
oRM.write('<div class=formControl');
oRM.writeClasses();
oRM.writeControlData(oControl); // let div handle control metadata such as id.
oRM.write(">")
oRM.write('<input placeholder="'+oControl.getPlaceholder()+'"');
oRM.write('id="'+oControl.getId()+'-inner"'); // set id with 'inner'
// oRM.write('type="'+oControl.getType()+'"'); dont know why type is throwing error s=, so had to comment it.
oRM.write('value="'+oControl.getMyValue()+'"');
// oRM.writeClasses();
// oRM.writeControlData(oControl);
oRM.write('/>');
oRM.write('<label class="inputLabel" for="'+oControl.getId()+'"');
oRM.write('>');
oRM.renderControl(oControl.getIcon());
oRM.write('<span class="inputLabelContent">');
oRM.write(oControl.getLabel());
oRM.write('</span>');
oRM.write('</label>');
oRM.write('</div>');
}
Let me know if this works for you. :)

Related

Dynamic default value for Kendo Grid

I want an auto increment column in my Kendo Grid. This field isn't server side auto increment, because I want the user to see the value and be able to change it.
My current solution is to add a click attribute to Create button and loop over rows to find the highest value and increment it.
But how can I insert this value inside the newly created row? Click event happens before the new row is created.
So there is two possible solution:
Have a variable as default value and update it in my JS code.
Access the newly created row somehow, and update the value.
This is my JS code:
function createClick(id) {
var grid = $("#" + id).data('kendoGrid');
var highestRadif = 0;
grid.tbody.find('>tr').each(function () {
var dataItem = grid.dataItem(this);
var radif = dataItem.SRadifReqR;
highestRadif = highestRadif < radif ? radif : highestRadif;
})
alert(++highestRadif);
}
You can use Grid's edit event to add your new generatedId value to new Grid's model.
This is some explanation from their documentation:
Edit
fired when the user edits or creates a data item.
e.container jQuery, jQuery object of the edit container element, which wraps the editing UI.
e.model kendo.data.Model, The data item which is going to be edited. Use its isNew method to check if the data item is new
(created) or not (edited).
e.sender kendo.ui.Grid, The widget instance which fired the event.
I suppose your click have something like this
//generate id code
vm.newId = ++highestRadif; // we need to store generated Id
grid.addRow();
then on edit event
edit: function(e) {
var model = e.model; // access edited/newly added model
// model is observable object, use set method to trigger change event
model.set("id", vm.newId);
}
Note: Your schema model's field must set property editable: true, due to enable us to change model field value using set method. Also if your field schema have validation required, you need to remove it.
model: {
id: "ProductID",
fields: {
ProductID: { editable: true, nullable: true },
}
}
Sample
I was able to put a function in the datasource schema for this.
schema: {
model: {
id: "id",
fields: {
currencyType: { defaultValue: getDefaultCurrency },
invoiceDate: { type: "date" }
}
}
}
function getDefaultCurrency() {
return _.find(vm.currencyTypes, { id: vm.currencyId });
};

jQuery settings for form validation

I'm building a basic jQuery form validator. The code below is just to validate the name. I have several functions to validate mail, password, credit card, date etc. I want the user to be able to easily edit the error messages and classes. Let's say the user want to change the name of the class "error" or "success". Now the user needs to search and replace everywhere in the code where it says "error" or "success".
Is there any way to use an array or object at the top of the code to edit the error messages for each if-statement, and apply the classes?
Something like what's shown here: http://learn.jquery.com/plugins/basic-plugin-creation/#accepting-options (but at the top of the code, outside the function). Or could I use the same method but type like this (outside the function, at the top of the file)?
var settings = $.extend({
color: "#556b2f",
errorClass: "error"
}, options );
I also want the user to be able to add ID's and classes directly to the form element and type "true" in the setting "required" so the form element will be required. Is there some good way to do this?
var name = $("[data-name]");
var nameMsg = $("#nameMsg");
name.on("blur", function() { $(this).validateName() });
$.fn.validateName = function() {
if(name.val().length < 5) {
name.removeClass("success")
.addClass("error");
nameMsg.removeClass("success")
.addClass("error")
.text("Not that short, at least 5 characters.");
return false;
} else {
name.removeClass("error")
.addClass("success");
nameMsg.removeClass("error")
.addClass("success")
.html("Correct");
return true;
}
}
Solution
var defaults = {
errorClass: "error",
successClass: "success",
successMessage: "<i class='fa fa-check-circle'></i>",
errorMessageName: "Not that short, at least 5 characters.",
};
var settings = $.extend({}, defaults);
Special thanks to Martin Adámek for his help!
$.extend just creates new object merged with values from both arguments, you can use it to extend default options object with user given (anywhere you want).
I'm not sure if I understand you correctly, is this what you want?
var defaults = { // maybe you do not need extend at all?
errorClass: "error",
successClass: "success",
messageError: "Not that short, at least 5 characters.",
messageCorrect: "Correct"
};
var name = $("[data-name]");
var nameMsg = $("#nameMsg");
name.on("blur", function() { $(this).validateName() });
$.fn.validateName = function() {
var userOpts = {...}; // you can store it eg in data attribute on the element
// extend options with user given values
options = $.extend(defauts, userOpts);
if(name.val().length < 5) {
name.removeClass(options.successClass)
.addClass(options.errorClass);
nameMsg.removeClass(options.successClass)
.addClass(options.errorClass)
.text(options.messageError);
return false;
} else {
name.removeClass(options.errorClass)
.addClass(options.successClass);
nameMsg.removeClass(options.errorClass)
.addClass(options.successClass)
.html(options.messageCorrect);
return true;
}
}
The user given options would be stored as a JSON string (to allow merging with default options), so you would need to call JSON.parse() on in first.
EDIT:
Example of options JSON object in data attribute:
HTML:
<input type="text" data-options='{"messageCorrect": "Bingo! That is the right choice!", "errorClass": "my-error-class"}' ...>
and then in $.fn.validateName() you will do simply:
var userOpts = JSON.parse($(this).data('options'));

Function is not defined, parameter formatting

I'm trying to create my own lightbox script where I can pass the variables (title, description, itemtype, itemid, etc.) in clean formatting like this (inspired by fancybox):
myFunction({
title: "My title",
description: "My description"
});
Clicking on a certain element prepends some HTML to a div with jQuery.
I have adapted a piece of code I found on Stackoverflow and "kind of" understand the code. The top function has not been changed and worked before I edited the bottom code, to that I added click(function() { } because in the example the code was executed on pageload.
However, when I click my H1 element the firebug console tells me ReferenceError: popup is not defined
This is my Javascript:
$(document).ready(function() {
(function ($) {
$.fn.popup = function (options) {
var settings = $.extend({
title: function (someData) {
return someData;
},
description: function (someData) {
return someData;
},
}, options);
$("#content").prepend(
"<div style=\"position:fixed;top:0;left:0;width:100%;height:100%;background:#FFFFFF;\">\
<h1>"+ settings.title +"</h1>\
<p>" + settings.description +"</p>\
</div>"
);
};
}(jQuery));
$(".openbox1").click(function() {
popup({
title: "Title 1",
description: "Description 1"
});
}));
$(".openbox2").click(function() {
popup({
title: "Title 2",
description: "Description 2"
});
}));
});
This is my HTML
<div id="content">
<h1 class="openbox1">open box 1</h1>
<h1 class="openbox2">open box 2</h1>
</div>
A. Wolff commented that I need to execute the function like this:
$(".openbox1").click(function() {
$(this).popup({
...
});
});
This fixed it, thanks!
First off, what you did, and I hope this helps:
// This, of course is same as "document.onload"
// Don't confuse it with "window.onload"
// wich will wait till WHOLE dom is loaded to run any script
$(document).ready(function() {
(function ($) {
// This is, in essence, the start of a jQuery plugin
// This is often referred to as the "quick and dirty setup"
// as it's a direct call to add a method to jQuery's
// element object. Meaning it can be recalled as
// $(element).popup().
// This should not be confused with $.popup = function
// which would just add a method to jQuery's core object
$.fn.popup = function (options) {
var settings = $.extend({
...
}(jQuery));
$(".openbox1").click(function() {
// here is where your issue comes in
// as previously noted, you did not create a
// method named "popup".
// you added a method to jQuery's Element Object
// called "popup".
// This is why `$(this).popup` works and
// plain `popup` does not.
// You're inside an "event" asigned to any element
// having class name `openbox1`. Thus, any call
// in here to `this`, will reference that element
popup({
Secondly, a different example of how to write it. I won't say better because, even if I say my way is better, it wouldn't make your "corrected" way wrong. In Javascript, as the old saying goes, There's more than one way to skin a cat.
My Example:
// Notice I'm adding this plugin BEFORE the document load.
// This means, you could easily add this to a file and load it
// in script tags like any other Javascript,
// as long as it's loaded AFTER jquery.
(function($) {
// this ensures that your plugin name is available and not previously added to jQuery library
if (!$.popup) {
// this also provides us "variable scope" within to work in
// here begin adding the plugin to jQuery
// I started with $.extend, so it can be added to the jQuery library and used in traditional format
// $.popup('element selector', { options })
// as well as the element.action format we'll add later
// $.(element selector).popup({ options })
// This should help give you a good idea of the whole of what all is going on
$.extend({
popup: function() {
var ele = arguments[0], // this is our jQuery element
args = Array.prototype.slice.call(arguments, 1); // this gets the rest of the arguments
// this next step is useful if you make the traditional call `$.popup(this, { options })`
if (!(ele instanceof jQuery)) ele = $(ele);
// now we have total control! Bwahahha!
// Fun aside, here is where it's good to check if you've already asigned this plugin
// if not, then make some "marker", so you can recall the element plugin and comment an
// action instead of reinitializing it
if (!ele.data('popup')) $.popup.init(ele, args);
else {
// at this point, you would know the element already has this plugin initialized
// so here you could change an initial options
// like how with jQueryUI, you might would call:
// $(element).popup('option', 'optionName', value)
}
return ele;
}
});
// here is where we add the $(element selector).popup method
// this simply adds the method to the element object
// If you don't fully understand what's going on inside (as I explain below),
// just know that it's some "fancy footwork" to pass the method onto our initial
// method creation, $.popup
$.fn.extend({
popup: function(/*no need for parameter names here as arguments are evaluated inside and passed on to initial method*/) {
// set this element as first argument to fit with initial plugin method
var args = [$(this)];
// if there are arguments/params/options/commands too be set, add them
if (arguments.length) for (x in arguments) args.push(arguments[x]);
// pass through jquery and our arguments, end result provides same arguments as if the call was:
// $.popup($(element), options)
return $.popup.apply($, args);
}
});
// This next part is not seen in many plugins but useful depending on what you're creating
$.popup.init = function(ele, opt) {
// here is where we'll handle the "heavy work" of establishing a plugin on this element
// Start with setting the options for this plugin.
// This means extending the default options to use any passed in options
// In the most simple of cases, options are passed in as an Oject.
// However, that's not always the case, thus the reason for this being
// a continued array of our arguments from earlier.
// We'll stick with the simplest case for now, your case, that the only options are an
// Object that was passed in.
// using the extend method, with true, with a blank object,
// allows us to added the new options "on top" of the default ones, without changing the default ones
// oh and the "true" part just tells extend to "dig deep" basically (multideminsional)
if (opt && typeof opt[0] == 'object') opt = $.extend(true, {}, $.popup.defaults, opt[0]);
var par = opt.parent instanceof jQuery ? opt.parent : $('body'),
tit = opt.title,
des = opt.description,
// this last one will be the wrapper element we put everything in
// you have this in yours, but it's written in a very long way
// this is jQuery simplified
wrap = $('<div />', { style: 'position:fixed;top:0;left:0;width:100%;height:100%;background:#FFFFFF;' }),
// much like the previous element, cept this is where our title goes
head = $('<h1 />', { text: tit }).appendTo(wrap),
content = $('<p />', { text: des }).appendTo(wrap);
$(par).append(wrap);
// finally, add our marker i mentioned earlier
ele.data('popup', opt);
// just adding the following cause i noticed there is no close
// fyi, i would change this plugin a little and make an actial "open" command, but that's another tutorial
var closer = $('<span />', { text: '[x]', style: 'cursor:pointer;position:absolute;bottom:1em;right:1em;' });
wrap.append(closer);
closer.click(function(e) { ele.data('popup', false); wrap.remove(); });
};
$.popup.defaults = { // establish base properties here that can be over-written via .props, but their values should never truly change
'parent': undefined, // added this to keep it dynamic, instead of always looking for an element ID'd as content
title: '',
description: ''
};
}
})(jQuery);
// the following is basically jQuery shorthand for document.ready
$(function() {
// i think you get the rest
$(".openbox1").on('click', function(e) {
$(this).popup({
title: "Title 1",
description: "Description 1",
parent: $("#content")
});
})
$(".openbox2").on('click', function(e) {
$(this).popup({
title: "Title 2",
description: "Description 2",
parent: $("#content")
});
})
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div id="content">
<h1 class="openbox1">open box 1</h1>
<h1 class="openbox2">open box 2</h1>
</div>

label inside combobox and conditional multiselect

I am building a pretty combobox with checkboxes and conditional entries. Everything works out alright, except for two features that I cannot figure out how to implement.
1) I would like to move the label inside the combobox, make it shift the values to the right, and appear in a slightly gray color.
2) I would like the value to ignore certain entries (group headers) selected. Those entries are there for functionality only - to select/unselect groups of other entries.
The entire project is in the zip file. You don't need a server, it's a client base app. Just download the archive, unpack, and launch app.html in your browser.
http://filesave.me/file/30586/project-zip.html
And here's a snapshot of what I would like to achieve.
Regarding your second issue, the best way I see is to override combobox onListSelectionChange to filter the values you don't want:
onListSelectionChange: function(list, selectedRecords) {
//Add the following line
selectedRecords = Ext.Array.filter(selectedRecords, function(rec){
return rec.data.parent!=0;
});
//Original code unchanged from here
var me = this,
isMulti = me.multiSelect,
hasRecords = selectedRecords.length > 0;
// Only react to selection if it is not called from setValue, and if our list is
// expanded (ignores changes to the selection model triggered elsewhere)
if (!me.ignoreSelection && me.isExpanded) {
if (!isMulti) {
Ext.defer(me.collapse, 1, me);
}
/*
* Only set the value here if we're in multi selection mode or we have
* a selection. Otherwise setValue will be called with an empty value
* which will cause the change event to fire twice.
*/
if (isMulti || hasRecords) {
me.setValue(selectedRecords, false);
}
if (hasRecords) {
me.fireEvent('select', me, selectedRecords);
}
me.inputEl.focus();
}
},
And change your onBoundlistItemClick to only select and deselect items in the boundlist not to setValue of the combo:
onBoundlistItemClick: function(dataview, record, item, index, e, eOpts) {
var chk = item.className.toString().indexOf('x-boundlist-selected') == -1;
if ( ! record.data.parent) {
var d = dataview.dataSource.data.items;
for (var i in d) {
var s = d[i].data;
if (s.parent == record.data.id) {
if (chk) { // select
dataview.getSelectionModel().select(d[i],true);
} else { // deselect
dataview.getSelectionModel().deselect(d[i]);
}
}
}
}
},
Regarding your first issue, it is easy to add the label using the displayTpl config option. But this will only add the text you need, without any style (grey color, etc). The combo is using a text input, which does not accept html tags. If you don't need the user to type text, than you may want to change the combo basic behavior and use another element instead of the text input.

ExtJS display RowExpander on condition only

I currently have a rather big Grid and am successfully using the RowExpander plugin to display complementary informations on certain rows. My problem is that it's not all rows that contain the aforementioned complementary informations and I do not wish the RowExpander to be active nor to show it's "+" icon if a particular data store's entry is empty. I tried using the conventional "renderer" property on the RowExpander object, but it did not work.
So basically, how can you have the RowExpander's icon and double click shown and activated only if a certain data store's field != ""?
Thanks in advance! =)
EDIT: I found a solution
As e-zinc stated it, part of the solution (for me at least) was to provide a custom renderer that would check my conditional field. Here is my RowExpander:
this.rowExpander = new Ext.ux.grid.RowExpander({
tpl: ...
renderer: function(v, p, record) {
if (record.get('listeRetourChaqueJour') != "") {
p.cellAttr = 'rowspan="2"';
return '<div class="x-grid3-row-expander"></div>';
} else {
p.id = '';
return ' ';
}
},
expandOnEnter: false,
expandOnDblClick: false
});
Now, the trick here is that for this particular Grid, I chose not to allow the expandOnEnter and expanOnDblClick since the RowExpander will sometimes not be rendered. Also, the CSS class of the grid cell that will hold the "+" icon is 'x-grid3-td-expander'. This is caused by the fact that the CSS class is automatically set to x-grid3-td-[id-of-column]. So, by setting the id to '' only when I'm not rendering the rowExpander, I'm also removing the gray background of the un-rendered cells. So, no double click, no enter, no icon, no gray-background. It really becomes as if there is strictly no RowExpander involved for the columns where my data store field is empty (when I want no RowExpander).
That did the trick for me. For someone that wishes to preserve the ID of the cell, or that wishes to keep the double click and enter events working, there is nothing else to do other than extending the class I guess. Hope this can help other people stuck in the position I was!
As e-zinc stated it, part of the solution (for me at least) was to provide a custom renderer that would check my conditional field. Here is my RowExpander:
this.rowExpander = new Ext.ux.grid.RowExpander({
tpl: ...
renderer: function(v, p, record) {
if (record.get('listeRetourChaqueJour') != "") {
p.cellAttr = 'rowspan="2"';
return '<div class="x-grid3-row-expander"></div>';
} else {
p.id = '';
return ' ';
}
},
expandOnEnter: false,
expandOnDblClick: false
});
Now, the trick here is that for this particular Grid, I chose not to allow the expandOnEnter and expandOnDblClick specifically since the RowExpander will sometimes not be rendered. Also, the CSS class of the grid cell that will hold the "+" icon is 'x-grid3-td-expander'. This is caused by the fact that the CSS class is automatically set to x-grid3-td-[id-of-column]. So, by setting the id to an empty string only when I'm not rendering the rowExpander, I'm also removing the gray background of the cells that won't offer any expanding. So, no double click, no enter, no icon, no gray-background. It really becomes as if there is strictly no RowExpander involved for the columns where my data store field is empty (when I want no RowExpander).
That did the trick for me. For someone that wishes to preserve the ID of the cell, or that wishes to keep the double click and enter events working, there is nothing else to do other than extending the RowExpander class in my opinion. Of course, one could also use Ext.override(), but then all instances of RowExpander would be hit by the override.
I have the same task, there is my solution
var rowExpander = new Ext.ux.grid.RowExpander({
renderer : function(v, p, record){
return record.get('relatedPageCount') > 0 ? '<div class="x-grid3-row-expander"> </div>' : ' ';
}
});
I have overridden render method which test relatedPageCount field in store and render + or white space.
I think I've found a cleaner solution.Give me a feedback pls :)
I extend the toggleRow method of RowExpander and if I match a condition avoid to toggle the row.Otherwise the standard flow continues
Ext.create('customplugins.grid.plugin.ClickRowExpander',{
pluginId : 'rowexpander',
rowBodyTpl : new Ext.XTemplate(
'<p><b>Last Modified By:</b> {usermodify}</p>',
'<p><b>User data:</b> {userdata}</p>',
'<p><b>Correlation ID:</b> {correlationid}</p>',
'<p><b>Description:</b> {descr}</p>'
),
toggleRow : function(rowIdx, record) {
if(record.get('directory')) return false;
customplugins.grid.plugin.ClickRowExpander.prototype.toggleRow.apply(this, arguments);
}
})
This version works in Ext JS 5 and 6 (classic)
One thing is to remove the +/- icon, which can be done via grid viewConfig:
getRowClass: function (record, rowIndex, rowParams, store) {
var yourFieldofChoice = record.get('yourFieldofChoice');
if (yourFieldofChoice == null) {
return 'hide-row-expander';
}
},
Define css for hide-row-expander:
.hide-row-expander .x-grid-row-expander {
visibility: hidden;
}
Now you disable expanding on enter key ('expandOnEnter' config is no longer supported in Ext JS 6) or double click by overriding toggleRow, or if you do not wish the override you create your custom rowexpander built on existing plugin:
Ext.define('RowExpander', {
extend: 'Ext.grid.plugin.RowExpander',
alias: 'plugin.myExpander',
init: function (grid) {
var me = this;
me.grid = grid;
me.callParent(arguments);
},
requiredFields: ['yourFieldofChoice'],
hasRequiredFields: function (rec) {
var valid = false;
Ext.each(this.requiredFields, function (field) {
if (!Ext.isEmpty(rec.get(field))) {
valid = true;
}
});
return valid;
},
toggleRow: function (rowIdx, record) {
var me = this, rec;
rec = Ext.isNumeric(rowIdx)? me.view.getStore().getAt(rowIdx) : me.view.getRecord(rowIdx);
if (me.hasRequiredFields(rec)) {
me.callParent(arguments);
}
}
});
I have handled the beforeexpand event inside the listeners of Ext.ux.grid.RowExpander. beforeexpand method got the whole row data injected. Checking the data conditionally we can return true or false. If we return false it wont expand otherwise it will do.
var expander = new Ext.ux.grid.RowExpander({
tpl: '<div class="ux-row-expander"></div>',
listeners: {
beforeexpand : function(expander, record, body, rowIndex){
var gpdata = record.data.GROUP_VALUES[1].COLUMN_VALUE
if(gpdata == null){
return false;
}
else{
return true;
}
}
}
});

Categories