Looping over the records of a large cfgrid
I mentioned in the post Adding the values of a cfgrid column that if we need to loop over many rows in the cfgrid, we may receive the "A script in this movie is causing Flash Player to run slowly" alert from the Flash Player. In order to avoid that, we’ll separate the task in frames:
<cfsavecontent variable="changePrice">
var newPrice = Number(amount.text);
var i = 0;
//make the loop with onEnterFrame instead of a "for"
_root.onEnterFrame = function ()
{
if(i < productsGrid.length) {
//do one iteration of the loop
_root.updatePrice(i);
i++;
}
else {
//end the loop
_root.onEnterFrame = undefined;
}
}
//this is the function that does whatever we need in each iteration
_root.updatePrice = function (index){
//edit the row
productsGrid.editField(index, 'price', Number(productsGrid.getItemAt(index)['price']) + newPrice);
//change the color of the edited row
productsGrid.setPropertiesAt(index, {backgroundColor:0xF7FFB7});
}
</cfsavecontent>
<cfform name="myForm" format="flash">
<cfgrid name= "productsGrid" query="products">
<cfgridcolumn name="name" header="Product">
<cfgridcolumn name="price" header="Price" type="numeric">
</cfgrid>
<cfinput type="text" name="amount">
<cfinput type="button" name="updateBtn" value="Update" onclick="#changePrice#">
</cfform>
Webdevotion
First loop over the data, edit it, then
set grid.dataprovider at once.
This is more efficient than editing
1 row at a time.
Eric Snowden
<cfsavecontent variable="uncheck">
_root.onEnterFrame = function() {
if (i < _root.myGrid.length) {
_root.myGrid.editField(i, 'send', false);
i++;
} else {
_root.onEnterFrame = undefined;
}
};
</cfsavecontent>
<cfform format="flash" name="flashForm" width="540" height="580" skin="halosilver">
<cfgrid name="myGrid" Format="flash" query="q_mailingList" selectmode="edit" delete="yes" insert="yes" fontsize="10" rowheight="25" gridlines="yes" colheaders="yes" height="500">
<cfgridcolumn header="id" name="listID" display="no">
<cfgridcolumn header="LAST NAME" name="lastName">
<cfgridcolumn header="FIRST NAME" name="firstName">
<cfgridcolumn header="EMAIL" name="email" width="185">
<cfgridcolumn header="DATE ADDED" name="date" width="80" select ="no">
<cfgridcolumn header="SEND EMAIL" name="send" width="80" type="boolean">
</cfgrid>
<cfformgroup type="horizontal">
<cfinput type="button" name="uncheckAll" value="UNCHECK ALL" onclick="#uncheck#">
</cfformgroup>
<cfformgroup type="horizontal">
<cfinput type="submit" name="gridEntered" value="SAVE">
</cfformgroup>
</cfform>
If you could help me out that would be greatly appreciated. Thanks!
Eric
Laura
yes, you can use dataprovider and it will definitely be faster. I wanted to give the user some kind of visual indication that the something was happening, so that is why I edit each row. In the other case, we could pop an alert when the process was finished.
You can also make a small loop (ie: 5 iterations) inside the onEnterFrame function to edit more than one row each time to make it faster.
Laura
Your code is working for me. I only needed to declare the variable i before using it. Also make sure that the column send in your db (or query) has the same case as in the AS code.
var i = 0;
_root.onEnterFrame = function() {
.......
}
Casey
Casey A
Trying to get a simplified version of this to work...Any help will be appreciated!
<cfquery name="products" datasource="#application.dsn.oiws#">
SELECT *
FROM tbl_List360
ORDER BY lastName
</cfquery>
<cfoutput>
<body>
<cfform name="myForm" format="flash" width="350" height="250">
<cfformgroup type="vBox">
<cfgrid name= "cart" query="products" height="150" rowheaders="false" selectmode="edit">
<cfgridcolumn name="RACF" header="Product" select="true">
</cfgrid>
</cfformgroup>
</cfform>
</body>
</cfoutput>
Casey A
Our back end is SQL Server, in this table are several records. I want to give the user the ability to edit specific fields in this dataset through the cfform. What I've ran into so far is that the dataset is not populating the form. It feels like I'm missing a cfloop, or something to populate the form (at this point the form returns blank).
Casey A
Rick
mafdoc
Anybody come up with something?
If you could tell me what to look for in AS.
Nahuel
If you want to send the items of a grid you should send it like this:
myGrid.dataProvider.items
Mafdoc,
You can unselect the grid with this code:
myGrid.selectedIndex = undefined;
Trevor Orr
mafdoc
I added this
myGrid.selectedIndex = undefined;
and
myfieldnames.text ="";
and when the button is clicked
all the fields and the grid are cleared.
Thanks again.
Ray
My situation is this: I have two cfgrids, both are populated via a query. You can click on a row in the first grid and add it to the second grid. Then I want to be able to save the data the is added to the second grid into the database. Is this possible? I'm sure it's similar to what you guys have written here, but I'm not sure exactly how to use it.
Here is my code of my two grids:
<cfformgroup type="horizontal">
<!---<cfformitem type="text">Existing Users</cfformitem>--->
<!--- Testing how a CFGRID will work ---> <!--- Testing how a CFGRID will work --->
<cfgrid name="user_grid" query="getEmployees" selectmode="row" colheaders="yes"
rowheaders="no" width="250" height="200" format="Flash" onChange="#gridChange#">
<cfgridcolumn name="EmpID" header="Employee ID" display="no">
<cfgridcolumn name="Last_Name" header="Last Name">
<cfgridcolumn name="First_Name" header="First Name">
<cfgridcolumn name="Phone_Number" header="Phone Number" display="no">
<!---<cfgridcolumn name="UserLevel" header="User Level" display="no">--->
<!---<cfgridcolumn name="OffAbbr" header="Office" display="no">--->
</cfgrid>
<!---<cfformitem type="text">Users Assigned to the Project</cfformitem>--->
<!--- Testing 2nd CFGRID --->
<cfgrid name="user2_grid" query="choosenUsers" rowheaders="no" width="400" height="200" format="flash">
<cfgridcolumn name="EmpID" header="Employee ID" display="no">
<cfgridcolumn name="Last_Name" header="Last Name">
<cfgridcolumn name="First_Name" header="First Name">
<cfgridcolumn name="Phone_Number" header="Phone Number" mask="(999)999-9999" display="no">
<cfgridcolumn name="UserLevel" header="User Level">
<cfgridcolumn name="OffAbbr" header="Office">
</cfgrid>
</cfformgroup><!--- End Two Grids --->
Any help is appreciated.
Thanks!!
Michael White
Case
Thanks in advance
Case
Benjamin
My 5 cents :
You can add a "kind of" counter in your form, something like :
<cfinput type="Text"
name="counter"
required="No"
visible="No"
enabled="No"
size="15"
style="text-align:center;borderStyle:none;disabledColor:#000000;background-color:transparent;">
and then, in your cfsavecontent :
var newPrice = Number(amount.text);
var i = 0;
_root.onEnterFrame = function ()
{
_root.counter.visible = true;
if(i < productsGrid.length) {
_root.counter.text = "Processing " + i + " rows ...";
_root.updatePrice(i);
i++;
}
else {
_root.counter.visible = false;
_root.onEnterFrame = undefined;
}
}
Hope this helps !
John
Here is the function call to loop through the datagrid rows:
<cfsavecontent variable="calculateTotal">
var totalAmount = 0;
var item;
var subTotal = 0;
var itemStr:String = "foo";
for(var i = 0; i < cart.length; i++) {
item = cart.getItemAt(i);
//get subtotal
subTotal = number(item['price']) * item['quantity'];
itemStr = itemStr + ':' + item['name'].toString();
//tally up the amount
totalAmount += subTotal;
//change the subtotal column for this row
cart.editField(i, 'amount', subTotal);
}
//show the total
total.text = totalAmount;
names.text = itemStr;
</cfsavecontent>
John
Here is the function call to loop through the datagrid rows:
<cfsavecontent variable="calculateTotal">
var totalAmount = 0;
var item;
var subTotal = 0;
var itemStr:String = "foo";
for(var i = 0; i < cart.length; i++) {
item = cart.getItemAt(i);
//get subtotal
subTotal = number(item['price']) * item['quantity'];
itemStr = itemStr + ':' + item['name'].toString();
//tally up the amount
totalAmount += subTotal;
//change the subtotal column for this row
cart.editField(i, 'amount', subTotal);
}
//show the total
total.text = totalAmount;
names.text = itemStr;
</cfsavecontent>