Slickgrid - how to get the value of edited cells? - javascript

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.

Related

How to copy the value of a yform to an other field

In our (hybris) shop some products have a yform to summarize the parts of the product. Is there an easy way to copy the value of the sum field into an other field (automaticly) like the productquantity (no yForm)?
I guess I need javascript, but the id of the sumfield is generatad, so I don't know how to get the sum. Also my Javascript abilities are quite limited...
UPDATE:
To get the value I use this part of code:
copyYFormValueToProductQuantity : function() {
var copyText = document.querySelector('input[id*="sum"]').value
if (copyText > 0 && copyText != null)
{
//do stuff
}
console.log("Copied value: " + copyText)
},
But this line
document.querySelector('input[id*="sum"]').value
returns null. If I use it in the browserconsole, it also returns null. But after I inspected the element it works and returns the value I want to. So I guess I am missing some JS-basics here and the object isn't ready before?
Btw.: I call this function with a keydown-eventlistener.
This can most likely be done from the jsp files. There you have all the data that is needed, so you most likely need to only copy that field where you need it.
We can also help you more if you add some code examples here (what exactly is that yform?). If you struggle to find where in code is that specific yform created/added, it's always worth giving a try to search for the applied classes of the html (search the entire project and see what you find).
As I understand your question, you are saying that you want to copy the value of a yForm field named sum into a non-yForm field named productquantity, and you are asking specifically about how to access the value of a yForm field from JavaScript. If I understand this correctly, you can do so by calling the following JavaScript API:
ORBEON.xforms.Document.getValue("sum");
You can find more about this and other related API on Client-side JavaScript API.

How to change an attribute of a javascript prototype object

html base
<html>
<head>
</head>
<body>
<input type="text" class="abc"/>
</body>
</html>
So I have my prototype object
function AnArray(){
this.anArray=[];
}
AnArray.prototype.getAnArray=function(val){
return this.anArray[val];
}
AnArray.prototype.setData=function(index,val){
this.anArray[index].data=val;
}
var objAnArray=new AnArray();
the object ends up looking like this
id: 1, pid: "questions-worth-asking", num: 1, data: null
and I'm trying to change an attribute in it like so
objAnArray.setData(0,$(".abc").eq(0).val());
When I've rune console.log messages using getAnArray() before and after the above line, it returns the same value as it has not been changed.
My question is how do you change attributes of a prototype object?
edit: This link led me down the right path http://www.gpickin.com/index.cfm/blog/websql-when-is-a-javascript-object-not-a-javascript-object
You're missing a lot of information from your post that makes it difficult to debug.
From my understanding the problem is that:
You want your jQuery object's value property to be stored in an array that you wrapped in an object.
You want to store this property with the setData function you wrote.
You want to retrieve that object by using the getAnArray function you wrote.
I don't think this is an issue with prototypes, but with the lack of information given to us, it could be any number of things. I wouldn't be surprised if you came back and said "Oh, it was something else completely."
I've made a fiddle that successfully sets and gets data from the anArray objects that you can use as an example.
Here are some problems you want to look at that will help you debug:
You don't set the anArray[index] object in this snippet. So if we are to take this at face value, the setData function should throw a ReferenceError.
You haven't told us if you're calling the setData function inside an event or right when the page loads. If it's the latter, then according to the html you posted at the top, you won't have any data in the input field yet. You need to call the setData function only when there's data in the field.
You might be calling the jQuery object outside of the $(document).ready(function(){ ... }) call so the value you're obtaining with $(".abc") call is undefined.
Give those a try and hopefully those work.
To make your questions easier to debug going forward:
Write all your experimental code in an isolated environment so that all the confidential content content doesn't have to be removed before posting.
Run your code and make sure it runs as expected.
Show us all of that code so that we know where all the data comes from and how each element interacts with the other elements. For example, we currently don't know how the anArray array is populated so I've had to make assumptions. We also don't know how id, pid, or "questions-worth-asking" comes from so there might be side effects from how those are loaded in.
Write your code using some sort of style guide to make it easier to read. This will also help improve debug time for you and will help prevent errors from silly mistakes that you might make.
Edit:
I know you're calling console.log before and after the setData method. Consider putting console.log inside the setData method as well.
AnArray.prototype.setData = function (index, val) {
console.log("Entering setData with: ", index, val, this.anArray[index]);
this.anArray[index].data = val;
console.log("Exiting setData with: ", this.anArray[index]);
};
It seems to me that the problem isn't in your javascript. You're saying that you ran a console.log before and after your setData call on objAnArray. Perhaps it has something to do with your HTML input element not being updated, or the data not coming through in time.
Like Keane said, we need more info about your set up and logic flow.

Get the ID from an Element in BIRT-Designer

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).

how to use jquery or javascript to get the selected VALUE from telerik radcombobox? val() not working

I have a listview that has a nested listview which contain radcomboboxes in the itemtemplate. As such, the IDs (as far as I know) are useless to me.
For example, if I have 30 items, each one of those items is going to generate a new combobox so the names are going to be generated by asp. What I need is to be able to grab the selected value from whichever combobox is being worked by the user. I'm currently using jQuery and some absurd parent().parent().children() type nonsense in order to find the correct combobox in relation to the submit button.
When submit button is clicked, I need it to find the selected value of the it's respective combobox so that I can send that to the post submission handler. The problem is that the .val() jQuery method is not working. When I use that with something like:
$(this).parent().parent().children().children(".statusCbo").val();
I end up getting the text value, not the selected value. I triple checked to make sure that I had the fields bound correctly in the aspx file;
DataTextField = '<%#Eval("name") %>' DataValueField = '<%#Eval("id") %>'
But as I said, I'm ending up with the DataTextField value of the selected item. The best explanation I could get was that it had something to do with how the control is requesting the content (via ajax).
So at any rate, could anyone offer some suggestions on how to accurately get the selected value from the combobox?
UPDATE:
I was able to gain reference to the object through a different means:
$(".submitTag").click(
function () {
var topLevel = $(this).closest(".CommentTopLevel");
var status = topLevel.find(".StatusTag").get_value();
//stub to test value
alert(status);
return false;
});
from here, if use status.val(), it will give me the text instead of the value (same issue as before). The documentation implies that I should use status.get_value(); but this is blowing up saying that the method is not supported from the object. Any ideas?
UPDATE:
nevermind, I found that it is a jquery object being returned, so the method isn't included. Continuing to dig.
SOLUTION:
There was just an extra step i needed to do to use traditional methods. I don't know what it took so long for it to click with me:
$(".submitTag").click(
function(){
var topLevel = $(this).closest(".CommentTopLevelTag"); //gets the parent container
var comboBoxID = topLevel.find(".StatusTag").attr("ID"); //gets the clientID of the jQuery object
var comboBoxRef = $find(comboBoxID); //finds the control by id and brings back a non-jQuery object (useable)
var comboBoxSelectedValue = comboBoxRef.get_value(); //uses the Telerik method to get the selected value
});
Its been a little while since I've dealt with Telerik controls, but what you're doing is bypassing the apis Telerik has made for you to use, and that strikes me as a very bad thing. The next release of Telerik Controls could easily break your code.
Look, it shouldn't be that hard to pass the client id from the listview. There's several methods I'd tackle but I'll let you figure that on your own for now. Once you DO have the ClientID for the control, follow the example on telerik's site:
http://demos.telerik.com/aspnet-ajax/combobox/examples/programming/addremovedisableitemsclientside/defaultcs.aspx
Once you have that id do some
var combo = $find(someVarReferencingTheId);
Now you have a reference to the combobox in its clientside form. Now find some function that gets what you want from here:
http://www.telerik.com/help/aspnet-ajax/combobox-client-side-radcombobox.html
...
PROFIT!
EDIT: that first link to demos.telerik.com isn't really even needed, I just showed that because that's what I used to get that line of code (I could never remember if it's $get or $find I needed to use, unless I was doing a lot of Telerik clientside stuff at the time.).
EDIT 2: $get and $find are ASP.NET constructs, not Telerik's.

Javascript: Event when DOM manupulation is done

We have a table that is populated via an Ajax call. In our Watin tests, we want to check the contents of this table. We already managed to find out when the javascript populating the table has stopped running, so that part works fine.
However, in IE there seems to be a delay between the moment javascript populating the DOM is finished and the moment the DOM is complely updated for Watin to detect the changes.
Right now we have a Thread.Sleep(500) to make this work, but I don't like this. Is there an event or something to catch the moment the DOM is completely updated?
EDIT: Example code
var tbody = $("#myID tbody");
tbody.empty();
$.each(item.Producten, function (i, item) {
var row = "<tr><td>" + item.Property + "</td></tr>";
tbody.append(row);
});
I don't think that there is such an event. If it were, WatiN would have use it. But when WatiN waits for something, eg. when you use WaitUntil methods (sometimes you could use it indirectly, for example when reading Exists property), WatiN is just making the Thread.Sleep call in a loop (see TryFuncUntilTimeOut class).
Almost everything you need can be achieved by using WaitUntil methods, but sometimes it is really tricky. If I were you, I would try a little bit more with this approach (especially if you are new to WatiN), but if it takes too much times I would just use Thread.Sleep(500) and forget about it.
I would like to add, that if there is a possibility to add some javascript code for test purposes to the end of your example code, you could set some kind of flag, like loadingCompleted = 1, and use TryFuncUntilTimeOut (I can't remember if there is appropriate WaitUntil method) to wait until loadingCompleted is set to 1. You can of course use WatiN to read this variable - see Document.Eval method.
Did you try the Method .WaitUntilExist ?
EDIT: add sample code
In your JS you can add a class:
var tbody = $("#myID tbody");
tbody.empty();
$.each(item.Producten, function (i, item) {
var row = "<tr class='newRow'><td>" + item.Property + "</td></tr>";
tbody.append(row);
});
In WatiN side:
Table table = Browser.Table("myID");
table.OwnTableRow(Find.ByClass("newRow")).WaitUntilExists();
Remarks:
If your table is empty, you can use Find.Any in the constraints
If Find.ByClass doesn't work (I know it has some problems), use another specific constraint : Find.ByIndex, Find.ById, etc.
This is an answer along the same line as prostynick suggests.
Why not give the tbody an attribute like data-uniqueId and give that a different value everytime at the end of your javascript code. It might be as simple as being the current datetime, as long as it is different from previous values.
Now that you have this attribute and value you can use that in WatiN:
var currentUniqueId = browser.Table("myID").TableBody.GetAttributeValue("data-uniqueId");
.... do something to trigger the AJAX call
browser.Table("myID").TableBody.WaitUntil(!Find.By("data-uniqueId", currentUniqueId);
In the first line we retrieve the value for data-uniqueId. In the last line WatiN waits until there is no tbody with this attribute having that value (because the data-uniqueId value was changed by your javascript code). Now we can proceed.
HTH,
Jeroen

Categories

Resources