I have an <ag-grid> using Angular and one thing I'm trying to do is when you click a button to add a row to the grid, I want to be able to focus and start editing the input for that row and that column
In the documentation, I have been able to get this working with various columns in various ag-grids in my app by using code like this:
this.gridApi.startEditingCell({
rowIndex: 0,
colKey: 'description'
});
However in one special case in one of my grids, I'm using the tree and autoGroupColumnDef like this:
<ag-grid-angular
#agGrid
style="width: 100%; height: 100%;"
id="myGrid"
class="ag-theme-balham"
[modules]="modules"
[columnDefs]="columnDefs"
[rowData]="rowData"
[treeData]="true"
[getDataPath]="getDataPath"
[defaultColDef]="defaultColDef"
[frameworkComponents]="frameworkComponents"
[groupDefaultExpanded]="groupDefaultExpanded"
[autoGroupColumnDef]="autoGroupColumnDef"
(gridReady)="onGridReady($event)"
(cellValueChanged)="handleChanges($event)"
(columnMoved)="handleColumnChanges($event)"
[getRowNodeId]="getRowNodeId"
[context]="this"
></ag-grid-angular>
And then in my typescript, I have my autoGroupColumnDef defined in my constructor like this:
this.autoGroupColumnDef = {
editable: true,
headerName: "Account #",
field: "accountNum",
filter: "agGroupCellRenderer",
cellRendererParams: {
suppressCount: true,
innerRenderer: 'AccountNameColumnDisplayer',
},
};
The problem is when I try to run the code like this:
this.gridApi.startEditingCell({
rowIndex: 0,
colKey: 'accountNum'
});
I get a warning that says ag-grid-community.cjs.js:27041 ag-Grid: no column found for accountNum
For the record, the data that I supply to this.rowData includes a property called accountNum
Is there something simple here that I'm not noticing or something I'm doing incorrectly? I have looked all over the ag-grid documentation and can't figure out how to solve this. Thanks in advance!
First off, lets be clear about the colKey. The colKey actually isn't directly tied to the field property. From the docs:
Some of the API methods take Column Key (named colKey) which has type
Column | string. This means you can pass either a Column object (that
you receive from calling one of the other methods) or you pass in the
Column ID (which is a string). The Column ID is a property of the
column definition. If you do not provide the Column ID, the grid will
create one for you (first by trying to use the field if it is unique,
otherwise it will generate an ID).
So, the colKey is either the column object itself, or, the colId you set in the column definition, the field property, or a random string (in that order).
Your first instinct may be to go and set the colId property of your autoGroupColumnDef column. But alas! In my experience, agGrid throws another curve ball at you and this will not work either...why?
This is because agGrid always makes the autoGroupColumnDef colId: ag-Grid-AutoColumn
TLDR: use the colKey "ag-Grid-AutoColumn" for autoGroupColumnDef column!
Cheers!
From what I can guess, I don't think your accountNum field is a part of columnDefs.
You need not provide field in autoColumnGroupDef, instead provide accountNum to actual columnDefs something like this -
{
field: 'accountNum',
hide: true,
}
Behind the scenes autoGroupColumnDefs is nothing but ag-grid group cell renderer on the column denoted with rowGroup=true.
Since your data is already in tree format, ag-grid takes care of grouping.
From the docs -
When the grid is working with Tree Data there is no need to explicitly
specify a Column Group as the grid will use the Auto Column Group.
The auto columns generated by the grid use the ag-Grid provided group
cell renderer. This means that gridOptions.autoGroupColumnDef can also
be used to pass additional properties to further customise how your
groups are displayed.
More details here
Related
I have a ice:selectOneMenu with a list of cars. I need that, when I select a car, an optionals table with many selectOneMenu is updated and default values are automatically selected.
So:
Cars: <select>
Optionals Table
-----------------------
Colors: <select>
Engines: <select>
Seats: <select>
Interior Color: <select>
...
...
The problem is thatI change the Cars value but the table is not updated and its values are not selected
So I want that:
if I select a Ferrari car, in the optionals table: the red color is automatically selected, the 3902CC engine is automatically selected, etc.
if I select a Porche car, the white color is automatically selected, the 616/16 engine is automatically selected,etc.
I'm using icefaces 1.8.2 and probably I can not use an ajax tag.
How can I do?
Thanks!!
I've found a workaround solution. Using:
JavascriptContext.addJavascriptCall(FacesContext.getCurrentInstance(),javascriptCodeString);
to add Javascript code to the page.
The string javascriptCodeString must contain a Javascript code that use CSS classes to bind a click event to an hidden <ice:commandButton styleClass="updateFieldsCommandButton" ... > that will call an action (for updating fields values):
function updateFields() {
document.getElementsByClassName('updateFieldsCommandButton')[0].click();
}
var listOfFields=document.getElementsByClassName('fieldToBeUpdated');
for(var i=0,len=listOfFields.length;i<len;i++) {
listOfFields[i].addEventListener('change', updateFields);
}
This works with icefaces 1.8.2 without needing an ajax tag.
Just asked another question but i think I need a much simpler solution.
Therefore i have made this JSFiddle:
http://jsfiddle.net/4EVBL/18/
<select name="selection" class="box1" style="width: 200px; height: 100px;" multiple>
<option>0</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
Is it possible to have the values (1 and 2) selected in the selected "box" on load, so it is possible to see which ones are selected. And is it possible to have the values of the input field divided by comma, so if one add "3" the value in the input fild will be 1,2,3. Can it also be done so that if you remove the value "2" in the select field the input field will say 1,3 ?
Any tips or help is much appreciated :)
You only need to make a couple of changes to your existing code. To populate the select on load, the following will suffice:
$(".box1").val($(".box2").val().split(","));
which populates .box1 with an array of values.
Meanwhile, to populate the textbox when the select box changes, use the .val() method instead of complicating it with :selected selectors and .text() methods:
$(".box1").change(function () {
$(".box2").val($(this).val());
});
JavaScript will automatically do a .toString() of the array into a comma-separated list of selected values.
When using a data aggregation on sap.m.Select, the first entry is always selected. Here's a link to the SDK's preview.
Example code from my app
new sap.m.Select("id-names", {
width: '100%',
}).bindAggregation("items", "data>/trip/names", new sap.ui.core.Item({
text: "{data>Name}"
}));
There is a parameter called selectedKey on the constructor to change this to another index. What I want is the select to be blank, because I want to force my users to make a choice, not blandly accept the first entry in the list.
I could force an blank entry in my aggregation data>/trip/names but that would pollute my list.
Is there a better way to achieve this?
Since the OpenUI5 version 1.34, you can set the forceSelection property to false.
The forceSelection property indicates whether the selection is restricted to one of the items in the list. The default value is true (which means, if the selection is not set, the first item in the dropdown list is selected).
When to set it to false?
If you do not want a default item to be pre selected.
Additional information
https://github.com/SAP/openui5/commit/b2191fd50e2115f8f9d2db7604a75fb50c57591f
Currently, no. There seems to be no better way.
There is a ticket for that on GitHub.
It's also my opinion to avoid messing with the dataset and much liked the idea of adding an additional item aggregate. However my improvement on this is to use a formatter on the control itself so it is clearly visible and executed at the right time.
I make use of a formatter with fully qualified controller to get the control as 'this' parameter. In the formatter function I add a ListItem, as proposed by #Victor S
In XML view
<Select forceSelection="false" selectedKey="{model>/key}" items="{path: 'model>/Items'}" icon="{path: '', formatter: 'mynamespace.Utils.addDeselectOption'}">
In the Utils controller:
addDeselectOption: function() {
var that = this;
this.getBinding("items").attachDataReceived(function(){
that.insertItem(new sap.ui.core.ListItem({text: '', key: undefined}), 0);
});
}
Works form me in UI5 1.52
Even though this solution is not great, I managed to get the empty field stick by adding both, the forceSelection=false property, and also in the controller's onInit function (I used the Select element):
var codeField = this.getView().byId("codeField");
setTimeout(function() {
codeField.insertItem(new sap.ui.core.ListItem({text: '', key: undefined}), 0);
}, 1000);
If the forceSelection=false is left out, the field will load either too early or too late to the drop down, which will cause the wrong selection to be visible. Hope it helps someone.
You can also extend the control and build you own select with e.g. an additional parameter add empty choice...I am actually also thinking about that...
I am learning to create reports using spotfire. Could you please help me to understand the feasibility.
Is it possible to change the filters based on the previous selection(filters has to be altered based on the previous section)
For Example:
I have a following table, with three columns.
Filter1 Filter2 Data
Name Name1 test1
Age Age1 test2
Location Location1 test3
I am planning to have filter options based on the column Filter1 and Filter2.
Is it possible to create a drop down with the values "Filter1" and "Filter2"?
Is it possible to modify the list of filter options, based on the first drop down selection.
For example. if "Filter1" is selected in the drop down. The list of filter options should be "Name","Age", "Location".
if "Filter2" is selected in the drop down. The list of filter options should be "Name1","Age1", "Location1".
Thank you
We can also create a cascading drop down list through the following steps.
Create a “property Control – Drop down list” myDropDownList
Select the “Unique Column Value ” to populate the drop down list (values).
Go to “Insert -> Calculated Column”
Use a simple conditional statement something like If([Value1] = ‘${myDropDownList}’, [Value 2], NULL)
Use the newly created column in the text area filter. This will be updated based on the previous section.
Thanks.
I have a solution utilizing JavaScript to effectively toggle between hidden DIVs. I'm not aware of a way to manipulate the filter object and which column it points to in the Text Area through the API. If someone does know a way I'd love to hear it!
Here is my solution with JS:
Set up your Text Area with a Drop Down for your selection as a column selector (with columns of interest chosen through the "Select Columns..." dialogue), a label displaying that selection (we will hide this, I realize it seems redundant), and 2 filters for your 2 columns.
Right click your text area and click Edit HMTL. Utilizing the HTML below, modify your HTML to match. You will want to have the 1st DIV as your drop down, the SPAN as your label which displays that drop down's property, and then the last 2 DIVS (LETTER and NUMBER in my case) as your two filters. Make sure the DIV id name matches your column name exactly.
<DIV><SpotfireControl id="8dc9d8974bde445cab4c97d38e7908d6" /></DIV>
<SPAN id=docProp style="DISPLAY: none"><SpotfireControl id="1311015997cd476384527d91cb10eb52" /></SPAN>
<DIV id=LETTER style="DISPLAY: none"><SpotfireControl id="760ae9ffd71a4f079b792fb5f70ac8b4" /></DIV>
<DIV id=NUMBER style="DISPLAY: none"><SpotfireControl id="488ef4b1289440d5be24b0dd8cfc3896" /></DIV>
Next we will implement the JS. To do so, click the +JS button in your Edit HTML. The JS itself is below. You'll want to change my inputs of LETTER and NUMBER in the first 2 getElementById references where we set them to display:none.
filter = function(){
input = $("#docProp").text().trim() //Take the text from our hidden label and trim it from any white space.
document.getElementById("LETTER").style.display = 'none'; //Reset DIV
document.getElementById("NUMBER").style.display = 'none'; //Reset DIV
document.getElementById(input).style.display = 'block'; //Set new display
}
//Run this function every 333ms or other length of time desired to update your filters.
setInterval(filter,333)
//Larger numbers mean slower response and better performance vs. faster response and worse performance. Tune as necessary.
Alternatively instead of scanning every X milliseconds (can cause some performance drag), you can make a JS button to run it manually. e.g. $("#divIdForButtonPlacement").button().bind('click',filter)
A few images of my setup for testing are shown below. Let me know if you have any questions regarding this.
I need to create dynamic filter that adds/removes rows dynamically.
It contains a drop-down box. Depending upon the drop-down box value selected, I create a dynamic <TD> that may have a text field or drop-down list.
If it's a text field, then I have to add date picker for that text field.
I have done this, except date picker for dynamically generated text field.
If you're creating 100 rows, the text fields' names should be same for all rows.
How to add datepicker for dynamically generated text field?
I had the same issue.
You would need to rebind the DatePicker to the dynamically added row.
The date picker associates a hadDatePicker Class to the dynamic row.
So you would need to remove that and rebind.
Something like this -
jQuery('.date-pick').removeClass('hasDatepicker').datepicker({
dateFormat: 'mm-dd-yy'
});
Regards,
Tina Agrawal
Actually i did use the solution provided by #Tina Agrawal But since now, when i select a date from the calendar, i click again and re-select. If i click on next month, it will go to 1900-01-01.
Well it was so strange...
After two hours of trial and errors and research.
i simply did:
$('.date-pick').live('click', function(){
$('.date-pick').datepicker();
});
Well it works.
I had the same issue and solved it in a different way. Although I am not very sure why is it working as I am very new to jquery. I wrote the following and it iterates the entire set of controls having the class "class_date" and rebinds the datepicker control to it.
$(".class_date").removeClass('hasDatepicker').datepicker();
Tirst add a class attribute as "date" to your input or div.
After dynamically add a text input to have to recall $('.date').datePicker() again to bind datePicker to new inputs or div.
I had a similar problem in that when dynamically adding new rows to my table the Date Picker fields in the new rows (any row added to the DOM dynamically) were all updating my initial rows Date Picker fields.
Removing the hasDatepicker class as suggested above was not enough to solve my issue, probably as I was using .clone() to create my dynamically added rows.
The solution when cloning rows was to remove the cloned input fields, re-create them, add them to my newly cloned table row and THEN re-initiate the Date Picker
For example:
//Remove exisiting cloned input fields
new_row.find("td.date input").remove();
//Create new input fields and append to table td
var date_tds = new_row.find("td.date");
$('<input />', {"name":"gStartDates["+n_array_pos+"]","type":"text"}).appendTo(date_tds[0]);
$('<input />', {"name":"gEndDates["+n_array_pos+"]","type":"text"}).appendTo(date_tds[1]);
//Re-initiate datepicker on the input fields
new_row.find("td.date input").datepicker({
dateFormat:"dd-mm-yy",
minDate:StartDate,
maxDate:EndDate
});
Use JQuery Live to access the dynamically created DOM.
http://api.jquery.com/live/
The you can attached the picker.
http://jqueryui.com/demos/datepicker/
one should use ".on" instead of live - see
http://api.jquery.com/on/