Get the ID from an Element in BIRT-Designer - javascript

Can someone told me, how i get the value from an Element in BIRT-Report Designer?
I tried the follwing in a dynamic Text Element but it didnĀ“t work
var e = reportContext.getDesignHandle().getElementByID(5514);
if(e > 13)
{
"bigger"
}
else
{
"smaller"
}
(5514) is the ID from a Data report Item.
It count a column in my dataset.
I also tried to get the value from this element by using:
reportContext.getDesignHandle().findElement("myElementId")
But also not working
Thanks for helping me!

Logging in the onFetch event and in fact anywhere in BIRT is definitely possible, we are using it frequently.
Probably your DS does not return any data or an exception occurs.
Add logging statements to the beforeOpen and afterOpen events, that will tell you if the query is executing at all (and you're able to log the actual DS parameter values using this.getInputParamaeterValue("param_Foo").
Quite often, you find that a parameter is null or uses a default value because you forgot to set the DS parameter bindings in the layout.
If the beforeOpen event runs, but not afterOpen, then the DB doesn't like your query.
If the afterOpen event runs, but not the onFetch, then your query returned zero rows.
Also, run your report as HTML to see if there's a JavaScript error (shown in red at the end of the output).

Related

How do I dynamically add one or more text boxes to a region in Oracle Apex 5.1?

I am using Oracle Apex 5.1 to create a sample application. I am trying to create new text boxes based on a number entered into a field. So far, the actors in this play are:
P11_TESTBOX: The text box that contains the amount of necessary new boxes
TEST: The button that, when pressed, fires the necessary dynamic action(s)
Procedure TEST_THIS: PL/SQL procedure that, when triggered by the button, will run and create the necessary boxes
The procedure, as written presently (just trying to test to see if I can get it to work before implementing fully):
CREATE OR REPLACE PROCEDURE TEST_THIS (
HOW_MANY IN NUMBER)
IS
BEGIN
FOR I IN 1..HOW_MANY LOOP
HTP.P('<input class="dynamicBoxes" id="P11_BOX_' || I || '" type="text" value="" />');
HTP.P('<br/>');
END LOOP;
END;
Like normally, I set a dynamic action on TEST: Event is set to 'Click', Selection Type is 'Button', Button is 'TEST', Event Scope is 'Static'. The True action is 'Execute PL/SQL Code', which is a simple call to the procedure HOW_MANY, passing :P11_TESTBOX as the number. I kept getting the error
Ajax call returned server error ORA-06502: PL/SQL: numeric or value
error for Execute PL/SQL Code
Thinking I was going crazy (which, let's be honest, isn't that far from the truth at this point), I added an 'Execute JavaScript Code' function:
alert(document.getElementById('P11_TESTBOX').value);
Not surprisingly, the number entered into the box was returned. Sadly, the error still appeared.
In an effort to ensure I tried everything, I changed the syntax of the PL/SQL procedure:
CREATE OR REPLACE PROCEDURE TEST_THIS (
HOW_MANY IN NUMBER)
IS
BEGIN
FOR I IN 1..HOW_MANY LOOP
HTP.P(
apex_item.text(
p_idx => 'P11_NEWBOX_0' || I,
p_Value => ''
)
);
END LOOP;
END;
Result: The alert still gives me the number; the error still follows.
The idea to try both versions came from this website.
Just to preempt myself, once I am able to sort this issue out, I will need to grab whatever values are entered into the created text boxes and insert them into the database. I'm hoping that's as simple as using whatever the IDs are that get created, but I'm not optimistic after this issue. Any help would be greatly appreciated.
You dont need to write a PL/SQL Procedure. Just hide the boxes on Page Load an when triggered the button the dynamic action shows them ? So you go to Server Side Action and Item = Value and also set this in the DA

Grab input value after send key and console log the value Selenium Webdriver

I am currently working on a project where I need to integrate the use of the Selenium Webdriver. I am using the Chrome implementation of Web Driver and running it via Javascript. I am currently testing a simple quantity input form. I am having trouble with a particular aspect of this project and that is ... I need the test to run through the form and put in different values everytime. I am placing the values via the sendKeys function. Now the trouble starts here... I need to grab the value that the sendKeys function inputs into the field and console.log a message depending on the value.
If the value is over a 100 I need the test to console.log the message "Exceeds 100".
If the value is less than 0 I need it to console.log the message "Below 0".
And if there is no value I need it to console.log the message "No input".
It runs through and puts in new values just fine. But the issue has been grabbing the value and console.logging a message depending on the value. I've tried many different options but there's just so little documentation related to this exact topic. I will link my code below, and I appreciate any input you guys may have... because it has me stumped unfortunately.
Also I am curious if this can be done using assertions in any way...
Test File Below:
https://gist.github.com/anonymous/89a84dbc15ba4088719400be1f359045
There is a method getAttribute(String attrName) it will accept a string parameter, pass attribute name against which value got set.
for example:
WebElement element =driver.findElement("your unique element locator");
String valueText=element.getAttribute("value");
about the answer above me - you should try adding a .getText(), So the attribute value would become a String.
WebElement element = driver.findElement("your unique element locator");
String valueText = element.getAttribute("value").getText();
Please add the full error message, A screenshot of the console would be good.

Slickgrid - how to get the value of edited cells?

I'd like to make my code be able to update database table immediately when the cell is changed. However, I can get the value of the changed cell whereas not the data of those of next cell.
Methods I have tried already without success:
grid.onCellChange.subscribe(
function (e, args) {
//alert(data[args.row][grid.getColumns()[args.cell].field]);
//alert(grid.getColumns()[args.cell].name);
//alert(args);
<%
updateDatabase("UPDATE table1 "+
"SET "+
" col1="+data[args.row][grid.getColumns()[args.cell].field]+" "+
"WHERE "+
" col2="+???)")
%>
}
);
How to get the value of the next column that I can use in the where clause ?
Addressing your problem:
If you check out the official SlickGrid Editing demo, you can try the following to get a basic understanding how grid editing works. Open your JS debugger and subscribe to the grids onCellChange event using the following command:
grid.onCellChange.subscribe(
function (e,args) {
console.log('row: ' + args.row + ' cell: ' + args.cell)
});
The grid's onCellChange events args argument object contains two properties:
row
cell
Now edit any of the cells and leave the just edited cell. It's important since this event will only fire on blur event.
In the console log you will see for instance:
row: 6 cell: 1
Addressing your data object:
The only way I found how could you address your data source is in a hackish way only using eval(). For further information about object property accessing you can check this answer.
A bit from the Javascript jargon:
The actual eval() command to address your data object with the given fieldname or property name is:
eval('data[args.row]'+'.'+columns[args.cell].field)
Simplified it will evaluate the JavaScript code represented as a string, in this SlickGrid Editing example it will become as if you would write:
data[6].title
So the proof of concept code is:
grid.onCellChange.subscribe(
function (e,args) {
console.log(eval('data[args.row]'+'.'+columns[args.cell].field))
});
This will return you the value of the current edited cell. For instance changing args.cell+1 will return you the next cell value from the data source of your grid. Of course you should always check the columns.length property to keep the column index key inside of array bounds.
Regarding your idea about the updateDatabase call: why do you want to update the database after every time this event gets fired? I suggest you to take a look at the official Composite editor demo which has an edit form.
The other thing I would strongly advise is that you not write server side or code behind code directly into the javascript code block. For example, you could make it use an ajax post.
The reason I recommend this is because then you are going to have separated functions with separated responsibilities. Just by adhering to this principle in itself could lead you to have a cleaner code, also you only give one reason to change. Also it may help testing your functions much easier.

Unable to save changes made to entity when calling javascript function through custom ribbon button event

I'm trying to create a simple function which, when ribbon button is pressed, sets entity attribute value to null.
Now the problem I am facing is, that the changes I make to the entity are not saved, form reloads and returns previous value.
To the button event I pass 'Task' activity attribute 'actualend'. 'Actual End' field is disabled by default.
ClearField: function (field) {
if (Xrm.Page.getAttribute(field) == null) return;
Xrm.Page.ui.controls.get(field).setDisabled(false);
Xrm.Page.getAttribute(field).setSubmitMode("always");
Xrm.Page.getAttribute(field).setValue(null);
if (Xrm.Page.data.entity.getIsDirty()) {
Xrm.Page.data.entity.save(); //also tried addOnSave(function)
}
}
Following debugger I was able to track that all changes are made correctly, except that on save() method they are 'discarded', then form reloads with previous value. This code works fine with CRM UR8 yet with CRM UR13 it does not.
Am I missing something?
As Guido mentions in his comment the code looks good which leads me to think that one of your two if statements is failing.
The first one obviously will fail if it is set to null. A little bit less obvious is that it will fail as well as if the field is not actually on the form (even though it may be a valid attribute of the entity). So step 1, ensure that your field exists on the form.
The second one I'm not sure of... I don't think getIsDirty() is keeps track of programmatic changes, so even though your programmatically updating a field and setting it to always submit, it may be returning false. Regardless of how exactly it's working, the if statement really isn't needed. The Xrm.Page.data.entity.save function will only actually save if it has some value that has changed, so I'd remove your dirty check regardless.
Eh, the problem with my issue all this time was that even though the field existed in the form, it never had an entity passed to it, therefore it was unable to save it. I've edited a ribbon button so to pass entity through CrmParameters and the issue was gone. Thank you both for supplying me with possible solutions regardless!

Javascript table on the fly

I've got some issues with javascript. Which causes some problems.
I'm using DevExpress MVC GridView, ASP.Net MVC 3 and javascript.
This my problem:
I've got a gridview, with for example customers.
I want them to select the customers, and show them in a table generated by javascript so we dont get all those refreshes. And they can then add other information so that they can be saved again to another table, but thats not really important.
I perform some calculations before generating the table row from the selected customer. Another problem is, the devexpress gridview has an event that calls on each selection change instead of a nice ~100 ms wait so that the user can multiselect quick without triggering method 3/4 times.
Im keeping track of my own table through an array. And the GridView from DevExpress got his own events that can give me the right information, so no need to worry about that.
So I got a method receiveSelectionFields(Values){ //do something } where I receive that information from the gridview on every selection.
Then I check my array to see if they added or removed a selection, and which.
Then I call addtablerow(customer) or removetablerow(customer). Which removes the customer from my table and then from my array.
Because I make some heavy calculations in between, there is a ~60ms delay before the calculation is done (on mine computer). So if the users makes 2 selections in 60 ms. My array will have the wrong value (not being modified by the first call that adds/removes a customer) and my javascript will cause an error e.g. the table row is not deleted. I check on length of my own array and on the length of the received array to see if something has been added or removed.
So what did I try?
Making my method a recursive method, that when the problem occurs it waites 60 ms and then redo the method. But this isn't working properly.
I tried adding a global variable busy, which is true when the method is still busy. And false when it ends. But my browser just quits when doing that. This was the code:
while (true) {
setTimeout(function () {
if (busy === false) {
break;
}
}, 50);
}
But I got the feeling it just endlessly loops.
And these are all workarounds, there must be a nice way to solve this. Any thoughts?
In short:
I want a way to let the functions go off in synch. even if their being called asynch. by the user so that my array doesn't mess up.
Found the answer why my problem exists:
Since javascript is a synch. language (1 thread). the functions should've triggered at the right time. The problem is the callback from DevExpress Gridview for MVC Extensions. It makes a callback to the server, which responds in for example ~150ms with the selected field values. This will give an error if you quickly trigger the devexpress function twice. The second trigger has a window to return FASTER then the first trigger. Which would mean my coding of the table get ruined since I check if something has been added or removed. So when the first trigger (which returns after the second trigger) and my table gets updated. It shows the table prior to my last selection. Thus missing 1 row or has 1 more row then it should've.
So I got to make a function that retrieves all the events, and then place them in an order ~200 ms after each order. To make sure there is enough time for the callback to retrieve. Though this is ofcourse still not reliable, I think I will just change the requirements on this.
Your while loop condition is true, therefore the loop will just continue endlessly. You may want to try the following:
var int = setInterval(function () {
if(busy === false) {
clearInterval(int);
}
}, 50);
Try this instead of looping through the setTimeout over and over. If I had to guess, the break is breaking the if statement but not the while loop causing your browser to get stuck in an endless loop. With the above code, you can set an interval at which to run the code. In this instance, the code runs every 50ms. Once the condition inside the if statement is true, the setInterval is cleared causing the browser to continue executing its normal functionality.
Hope this helps.

Categories

Resources