targeting oracle apex tabular form columns using javascript - javascript

I have a tabular form which I need to disbale and re-enable some of the columns based on some conditions.
I have the below javascript in my dynamic action which is working. I am referencing the columns by their names (f01_0001, f01_0002, f02_0001, f02_0002....)
$("[name='f01']").each(function(i){
// columns to be disabled
var coltext5 = $("[name='f05']").get(i).id;
var checkbox8 = $("[name='f08']").get(i).id.substring(0,8);
$("#"+coltext5).prop( "disabled", true );
$("#"+checkbox8).prop( "disabled", true );
})
But the issue I have is, if I switch the position of these columns, or add more editable columns to the tabular form, the name of these columns will be changed.
e.g in the above example, if I add one more textbox before coltext5, then coltext5's name will become f06....
Is there any better way to reference the tabular form columns? like ID or class, something that's static and won't be changed even the position of columns are changed?
Thanks

I've hit this issue before, and I've successfully used data attributes to do it - e.g. https://jeffkemponoracle.com/2016/04/05/declarative-tabular-form-dynamic-totals/
For example, you can set Element Attributes on the "Address" column to data-col="address", and refer to them in javascript using $("[data-col='address']").
Of course, you have to add this to each column you need to refer to.

Related

How can I write the code to append all of the items(XPages)?

I have many documents in Notes, all of the documents have a different form, like this picture :
(possibly like pic 1, pic 2, or pic 3)
How can I write the code in Xpages?
use the "computed field"? Or use the "input text"?
I used the "input text".But only for one item, not for all.
var doc = purchase.getDocument();
var A0 = doc.getItemValueString("DAY_A0");
if(A0 != 0){
return "Division processing";
}
If the form not only has one item, like the pics. How can I write the code to append all of the items?
I'm making the following assumptions here:
You have 10 fields in the document with numbers that might or might not be > 0
The 11th value (Total) shall be computed
You want to show one document at a time, not a list
You know how to add a data source to a page
Version 1:
Create a regular XPages form, use the wizard when adding the document data source. It now would show also the field with 0 values
Click on each ROW and change visibility property to computed (make sure you hit the row, not the cell or field) and add a visibility formula based on the field oof that row. Something like doc.DAY_A0 > 0
Add a computed field where you add the values of all 11 fields
done
Version 2:
in the page open event, get a handle on the document and compute a scoped variable that only contains the values you are interested in. Could be messy since you need a label (that is not your field name) and a value
Use a repeat control to render the values
Hope that helps

Dojo 1.6 DataGrid, dojox.grid.cells.Select selection event

I need to implement a hierarchical choice list in my DataGrid. Depending on the value of the first column, the available options for the second column need to change. Is there any way to attach a selection listener to the DataGrid (or all cells?) and modify the options value of the second column (in this specific row) to display values depending on the first columns value?
I haven't tried this but the dojox.grid.DataGrid has among its defined events:
onApplyCellEdit(inValue, inRowIndex, inFieldIndex)
so you can:
dojo.connect(grid, 'onApplyCellEdit',
function(inValue,inRowIndex, inFieldIndex){
var colObj = grid.getCell(2);
var node = colObj.getNode(inRowIndex);
var select = dojo.query(".dojoxGridSelect",node)[0];
console.log(select);
}
);
as long as the field is set alwaysEditing=true
That will give you access to the node and the cell... but if you change the options it rewrites it. There should be a better way of doing it by using the dojo's methods.
http://jsfiddle.net/dacabdi89/2acjt/

Getting the Control inside a table

I'm trying to get the control which is inside of a cell table; in my table I have different controls, labels, checkboxes, etc.
I basically need to get the control which is used in that table
var x = document.getElementById('myTable').rows[0].cells;
alert(x[0].innerText);
//alert(x[3].innerHTML);
if (x.Control == checkbox) {
x.checked = true;
}
This will be in a loop but for now I just need to be able to check the checkbox by grabbing the control and setting that control to true
Any hints/help would be great
I doesn't really understand what you exactly need is it
document.getElementById("checkbox").checked = true;
here checkbox is the id of a particular checkbox
I would put a unique id on the form element instead and use that to grab it. In this way you can change the structure in the future. Example: perhaps you no longer want to use a table grid, but a grid of divs.
When you use innerHTML you will might also grab textnodes and other things you put in the cell.
An alternative - if you really want to find a specific cell in a table - is to give each cell a unique id on the form "cell-4-5" where 4 is the row and 5 is the column.
[EDIT]
If you want to have the cell contents returned as a DOM-object then childNodes can be used:
var x = document.getElementById('myTable').childNodes[0].childNodes[0].childNodes
If you want to have the cell contents returned as a string then innerHTML can be used:
var x = document.getElementById('myTable').childNodes[0].childNodes[0].innerHTML
To check if the checkbox is checked you need to keep it as a DOM element and thus use the first version.

How to update ZK Grid values from jQuery

I have three Tabs and in each tab, I have a Grid.
The data for each Grid is coming from a database, so I am using rowRenderer to populate the Grids. The following code is common for all three Grids:
<grid id="myGrid1" width="950px" sizedByContent="true" rowRenderer="com.example.renderer.MyRowRenderer">
The rows are constructed from Doublebox objects. The data is populated successfully.
The Problem:
I need to handle multiple-cell editing on the client side. The editing is done via mouse-clicking on a particular cell and entering a value.
As example let's say that the user edits first cell on the first row and the value should be
propagated to all other cells on the same row and in all three Grids (so also the two Grids which the user currently does not see, because they are in tabpanes).
I am using jQuery to do this value propagation and it works OK.
I am passing the jQuery as follows:
doublebox.setWidgetListener(Events.ON_CHANGING, jQuerySelectors);
doublebox.setWidgetListener(Events.ON_CHANGE, jQuerySelectors);
This makes it possible to change the value in 1 cell and the change is instantly (visually) seen in all other cells filtered by jQuery selectors.
The problem is that the value is visually distributed to all the cells, but when I try to save the Grid data back to the database, the background values are the old ones.
I am assuming that ZK-Grid component is not aware that jQuery changed all the cell values. Nevertheless if I manually click on a cell that already has the NEW value (enter/leave/change focus) when I save the grid the NEW value is correct in that particular cell. Maybe that's a hint how can I resolve this.
Code of how I extract the Grid values:
Grid tGrid = (Grid) event.getTarget().getFellow("myGrid1");
ListModel model = tGrid.getModel();
MyCustomRow tRow = (MyCustomRow)model.getElementAt(i);
The model for my Grid is a List of MyCustomRow:
myGrid1.setModel(new ListModelList(List<MyCustomRow> populatedList));
I have a couple of assumptions, but whatever I have tried, hasn't worked. I have in mind that jQuery events and ZK-Events are different and probably isolated in different contexts. (Although I have tried to fire events from jQuery and so on..)
Do you have any suggestions? As a whole is my approach correct or there's another way to do this? Thanks for your time in advance!
Your problem is exactly what you are expecting.
Zk has it's own event system and do not care about your jq,
cos it's jq and zk don't observ the DOM.
The ways to solve your problem.
Use the "ZK-Way":
Simply listen at server-side and chage things there.
I am not sure if not selected Tabs
are updateable, but I am sure you could update the Grid
components on the select event of the Tab.
Fire an zk-event your self:
All you need to know, is written in the zk doc.
Basically, you collect your data at client side, send
an Event to the server via zAu.send() extract the
data from the json object at serverside and update your Grids
I would prefer the first one, cos it's less work and there should not be
a notable difference in traffic.
I post the solution we came up with:
This is the javascript attached to each Doublebox in the Z-Grid
//getting the value of the clicked cell
var currVal = jq(this).val();
//getting the next cell (on the right of the clicked cell)
objCells = jq(this).parents('td').next().find('.z-doublebox');
// if there's a next cell (returned array has length) - set the value and
// fire ZK onChange Event
if (objCells.length) {
zk.Widget.$(jq(objCells).attr('id')).setValue(currVal);
zk.Widget.$(jq(objCells).attr('id')).fireOnChange();
} else { //otherwise we assume this is the last cell of the current tab
//So we get the current row, because we want to edit the cells in the same row in the next tabs
var currRow = jq(this).parents('tr').prevAll().length;
//finding the next cell, on the same row in the hidden tab and applying the same logic
objCellsHiddenTabs = jq(this).parents('.z-tabpanel').next().find('.z-row:eq(' + currRow + ')').find('.z-doublebox');
if (objCellsHiddenTabs.length) {
zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).setValue(currVal);
zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).fireOnChange();
}
}
The java code in the RowRenderer class looks something like this:
...
if (someBean != null) {
binder.bindBean("tBean", someBean);
Doublebox box = new Doublebox();
setDefaultStyle(box);
row.appendChild(box);
binder.addBinding(box, "value", "tBean.someSetter");
...
private void setDefaultStyle(Doublebox box) {
box.setFormat("#.00");
box.setConstraint("no negative,no empty");
box.setWidth("50px");
String customJS = ""; //the JS above
//this is used to visually see that you're editing multiple cells at once
String customJSNoFireOnChange = "jq(this).parents('td').nextAll().find('.z-doublebox').val(jq(this).val());";
box.setWidgetListener(Events.ON_CHANGING, customJSNoFireOnChange);
box.setWidgetListener(Events.ON_CHANGE, customJS);
}
What is interesting to notice is that ZK optimizes this fireOnChange Events and send only 1 ajax request to the server containing the updates to the necessary cells.

How to create an OnChange "totaling" function from an unknown number of text fields

I'm having trouble figuring out how to do a simple Javascript task on fields in a table created with Rails 3.
My table has characteristic rows that the user adds using a form below (which updates the database and reloads the table partial).
The number of columns in the table is based on the number of attributes submitted in a different form. No matter how many columns are in a row, there is also a Total column after them. Each cell in the table has a text_field input, with an ID that is based on the row object id and the column object id.
What I'm trying to do is create an OnChange event for each of those cells, so that when a field value changes, the Total column gets updated with the total value in the text_field inputs of all cells in that row.
I don't know how to pass the Rails objects to Javascript (so I can cycle through the IDs), I can't figure out how to get the DOM element names and values if I use an action in the controller, and I don't know how to use RJS to do this either. Can anyone offer any help on how to do this? Thank you!
Sarah
If you use jQuery, you can set a class on the textboxes and listen to the change event on it.
example:
<input type="text" id="WhateverXXX" class="MyValue" />
<script type="text/javascript">
$(function(e) {
$('.MyValue').change(function(e) {
// update the total
});
});
</script>
In jQuery it'd be easy to iterate over all elements with the same class, so proper design of your document will help here.
Maybe something like this:
$('.thing_to_change').live('change', function() { retotal(); });
Your retotal function can be similar:
var total = 0;
$('.thing_to_change').each(function() { total = total + $(this).val() });

Categories

Resources