ag-grid with angular typeahead - angularjs

I am trying to use Angular Typeahead (https://angular-ui.github.io/bootstrap/) with ag-grid (https://www.ag-grid.com/). I have set angularCompileRows to true and I have set up a cell editor for the typeahead, and the typeahead dropdown is being activated. However, the drop down list is hidden behind the other rows in the grid. How can I make sure that I can see the typeahead drop down over top of the other grid rows? I tried setting z-index to 9999 on the <ul> element using firebug, but the list was still hidden.
This is my Cell editor:
// function to act as a class
function TypeAheadCellEditor () {}
// gets called once before the renderer is used
TypeAheadCellEditor.prototype.init = function(params) {
// create the cell
this.eInput = document.createElement('input');
this.eInput.setAttribute("typeahead", "cardCode for cardCode in getCardCodes($viewValue)");
this.eInput.setAttribute("typeahead-loading", "loadCardCodes");
this.eInput.setAttribute("typeahead-wait-ms", "300");
this.eInput.setAttribute("ng-model", "selectedItemCode");
this.eInput.value = params.value;
};
// gets called once when grid ready to insert the element
TypeAheadCellEditor.prototype.getGui = function() {
return this.eInput;
};
// focus and select can be done after the gui is attached
TypeAheadCellEditor.prototype.afterGuiAttached = function() {
this.eInput.focus();
};
// returns the new value after editing
TypeAheadCellEditor.prototype.getValue = function() {
return this.eInput.value;
};

Add this to your css:
.ag-cell {
overflow: visible;
}

Did you try following options from uib-typeahead
typeahead-append-to $ (Default: null) - Should the typeahead popup be appended to an element instead of the parent element?
typeahead-append-to-body $ (Default: false) - Should the typeahead popup be appended to $body instead of the parent element?

Related

ExtJS 7 - Column filter issue with locked column

I encountered this bug where the column filter is incorrect if the grid has a locked column
Here's the fiddle: sencha fillde
Steps to reproduce:
(Do not apply any filter)
Open the "Email" column menu
Open "Name" column menu (this is the locked column)
Open "Phone" column menu (notice that the filter menu is incorrect, it is showing the filter for "Email" column).
For grid that has no 'locked' columns the filter menu is working fine, thanks for anyone who can help!
Okay, this one was a bit tricky. It turns out that for a locked grid, the Ext.grid.filters.Filters:onMenuCreate gets hit twice... one for each side of the grid's menu that shows. The problem is that in the onMenuCreate, the framework doesn't account for the 2 menus. It only cares about the last menu that gets created and destroys the previous menu's listeners. In onMenuBeforeShow, the framework does account for each side of the grid, so I extended this idea into an override. I would encourage you to create a Sencha Support ticket for this, and if you don't have access, let me know, so I can submit one. Fiddle here.
Ext.override(Ext.grid.filters.Filters, {
onMenuCreate: function (headerCt, menu) {
var me = this;
// TODO: OLD BAD CODE... this would destroy the first menu's listeners
// if (me.headerMenuListeners) {
// Ext.destroy(me.headerMenuListeners);
// me.headerMenuListeners = null;
// }
// me.headerMenuListeners = menu.on({
// beforeshow: me.onMenuBeforeShow,
// destroyable: true,
// scope: me
// });
// Just like in the onMenuBeforeShow, we need to create a hash of our menus
// and their listeners... if we don't, we remove the 1st menu's listeners
// when the 2nd menu is created
if (!me.headerMenuListeners) {
me.headerMenuListeners = {};
}
var parentTableId = headerCt.ownerCt.id;
var menuListener = me.headerMenuListeners[parentTableId];
if (menuListener) {
Ext.destroy(menuListener);
me.headerMenuListeners[parentTableId] = null;
}
me.headerMenuListeners[parentTableId] = menu.on({
beforeshow: me.onMenuBeforeShow,
destroyable: true,
scope: me
});
},
destroy: function () {
var me = this,
filterMenuItem = me.filterMenuItem,
item;
// TODO: ADDING THIS AND REMOVING FROM THE Ext.destroy on the next line
var headerMenuListeners = this.headerMenuListeners;
Ext.destroy(me.headerCtListeners, me.gridListeners);
me.bindStore(null);
me.sep = Ext.destroy(me.sep);
for (item in filterMenuItem) {
filterMenuItem[item].destroy();
}
// TODO: ADDING THIS AND REMOVING FROM THE Ext.destroy on the next line
for (item in headerMenuListeners) {
headerMenuListeners[item].destroy();
}
this.callParent();
}
});

working on select but not on blur - EXTJS

I am newbie to ExtJS I have the following lines of code that is working fine on select event and now I am planning to add on blur event too.
autoResolve.on("select" || "blur", function (component, record, index) {
var fieldSet = utils.getComponentFromMngr(component.id.split("~")[0]);
if(autoResolveData.CURRSEL){ //Set previous selection property
var xmlElem = fieldSet.DomainXML.documentElement.childNodes[1];
xmlElem.setAttribute("PR_DOMAINTYPE",autoResolveData.FILL_SUBTYP);
xmlElem.setAttribute("PR_DOMAINID", record.get("ITEMID"));
xmlElem.setAttribute("PR_DOMAINVALUE", record.data.TITLE);
fieldSet.DomainObj.push({PRDomainType:autoResolveData.FILL_SUBTYP,PRDomainID:record.get("ITEMID"),PRDomainValue:record.data.TITLE});
}
it is still working fine on select event but not on blur event where am I going wrong please suggest
"select" || "blur" will return select, as you can find out if you type the following in browser console:
console.log("select" || "blur");
Furthermore, "blur" event does not have record as the second parameter. You would have to look how to get record and call the function with a valid record parameter.
What you want to achieve is roughly the following:
var myFunction = function (component, record, index) {
var fieldSet = utils.getComponentFromMngr(component.id.split("~")[0]);
if(autoResolveData.CURRSEL){ //Set previous selection property
var xmlElem = fieldSet.DomainXML.documentElement.childNodes[1];
xmlElem.setAttribute("PR_DOMAINTYPE",autoResolveData.FILL_SUBTYP);
xmlElem.setAttribute("PR_DOMAINID", record.get("ITEMID"));
xmlElem.setAttribute("PR_DOMAINVALUE", record.data.TITLE);
fieldSet.DomainObj.push({PRDomainType:autoResolveData.FILL_SUBTYP,PRDomainID:record.get("ITEMID"),PRDomainValue:record.data.TITLE});
}
};
autoResolve.on({
select:myFunction,
blur:function(component) {
var record = ... // your special magic here
return myFunction(component,record);
}
});

AngularJS Get text selection and append html to start and end of selection

Have little dilemma here. I'm building text editor in angular js. The problem that I have is, when user selects part of text within a paragraph or heading I need to change styling of that part of text to bold / italic etc.
So basically I need to wrap selected text in <strong></strong> or <em></em>.
Plunker
I have a directive
editorApp.directive('watchSelection', function() {
return function(scope, elem) {
elem.on('mouseup', function() {
scope.startPosition = elem[0].selectionStart;
scope.endPosition = elem[0].selectionEnd;
// scope.selected = elem[0].value.substring(start, end);
scope.$apply();
});
};
});
That gets text selection its startposition and endposition. On button click I need to wrap that selection in specific tags, which I'm hoping to accomplish with this function:
$scope.boldText = function(startPosition, endPosition) {
$scope.start = startPosition;
$scope.end = endPosition;
var htmlStart = angular.element('<strong>');
var htmlEnd = angular.element('</strong>');
$scope.start.append(htmlStart);
$scope.end.append(htmlEnd);
};
I relatively new to angular and I might have taken a bigger bite than I can handle :)
Issue is I can't get selection to wrap inside them tags.
You don't need to watch anything.
$scope.boldText = function() {
document.execCommand('bold');
};
This will bold the selected text.

Hide DateField while clicking anywhere in page

I am trying to hide extjs date-field on clicking anywhere on DOM except date-field. while clicking anywhere in dom bodyClick function get called.On basis of page co-ordinates element object get retrieved and then this element object get compared with date-field object.This works fine but problem comes whenever i am clicking on date-picker again "date-field" get hide.
sample code -
bodyClick: function(e){
var me = this, elem, t;
var flag =true;
elem = me.getEl();
for(t = Ext.dom.Element.fromPoint(e.getX(), e.getY()); t && t != null;){
if (Ext.fly(elem ).contains(t)){
flag =false;
}
}
if(flag ){
me.hide();
}
}
Any Suggestions for hiding datefield while clicking anywhere in DOM (extJs).
You can try this in afterRender of the panel or container in which your component is in.
this.mon(Ext.getBody().getEl(), 'click', this.yourFunction, this);
yourFunction:function(e){
var comp = Ext.ComponentQuery.query('datepicker')[0];//Get your datepicker component
if (Ext.fly(e.getTarget()) != comp) { //get the target using Ext.fly
comp.hide(); //Hide the component if the target is not the datepicker
}
}
Hope this helps you.

How do I reset all filters in Extjs Grids?

How do I reset my ExtJS filters in my grids. More specifically, how do I get the header to honour the changes to the filtering.
ie. This works fine :
grid.store.clearFilter();
But the header rendering is all wrong. I need to get into all the menu objects and unselect the checkboxes.
I am getting pretty lost. I am pretty sure this gives me the filterItems :
var filterItems = grid.filters.filters.items;
And from each of these filter items, i can get to menu items like so :
var menuItems = filter.menu.items;
But that's as far as I can get. I am expecting some kind of checkbox object inside menu items, and then I can uncheck that checkbox, and hopefully the header rendering will then change.
UPDATE :
I now have this code. The grid store has its filter cleared. Next I get the filterItems from grid.filters.filters.items and iterate over them. Then I call a function on each of the menu items.
grid.store.clearFilter();
var filterItems = grid.filters.filters.items;
for (var i = 0; i<filterItems.length; i++){
var filter = filterItems[i];
filter.menu.items.each(function(checkbox) {
if (checkbox.setChecked)
checkbox.setChecked(false, true);
});
}
The checkboxes do get called, but still nothing is happening :(
Try this code:
grid.filters.clearFilters();
This should take care of both the grid and its underlying store.
When you do
grid.store.clearFilter();
it can only clear the filters on the store but the grid's view doesn't get updated with that call. Hence to handle it automatically for both the grid's view as well as the grid's store, just use
grid.filters.clearFilters();
Hope it helps!
Cheers!
Your update help me but you forget the case where you have input text instead of checkbox.
So this is my addition of your solution:
grid.filters.clearFilters();
var filterItems = grid.filters.filters.items;
for (var i = 0; i<filterItems.length; i++){
var filter = filterItems[i];
filter.menu.items.each(function(element) {
if (element.setChecked) {
element.setChecked(false, true);
}
if(typeof element.getValue !== "undefined" && element.getValue() !== "") {
element.setValue("");
}
});
}
When you use grid wiht gridfilters plugin
and inovoke
grid.filters.clearFilters();
it reset applyed filters, but it don't clean value in textfield inside menu.
For clean textfield text you can try this:
grid.filters.clearFilters();
const plugin = grid.getPlugin('gridfilters');
let activeFilter;
if('activeFilterMenuItem' in plugin) {
activeFilter = plugin.activeFilterMenuItem.activeFilter
}
if (activeFilter && activeFilter.type === "string") {
activeFilter.setValue("");
}

Resources