PDA

View Full Version : Grid RecordForm Plugin



Pages : [1] 2 3

jsakalos
3 Apr 2008, 6:18 AM
Hi community.

Would you be interested in a grid plugin that would open a form to edit/add grid records? If yes, checkout the preview at:

http://recordform.extjs.eu

and let me know what do you think. If should I finish it, what should be configurable, etc...

Thank you.

escalade
3 Apr 2008, 7:24 AM
Saki,

It's looking great!

The project I am working on is using that kind of editor grid panel with add,delete,edit buttons.
Also, I have at least 30 of those grids. It would be possible to combine with DynamicJsonReader and DynamicColumnModel, so that I don't need to rewrite the codes 30 times?

I think I am asking too much. :D

Thanks for the plugin.

jsakalos
3 Apr 2008, 7:30 AM
I was also thinking about dynamic grids, I'm using 'em too. I only wanted to turn out some code that is able to generate a form from store/cm. I guess I'll add some reconfigure stuff.

escalade
3 Apr 2008, 8:31 AM
I was also thinking about dynamic grids, I'm using 'em too. I only wanted to turn out some code that is able to generate a form from store/cm. I guess I'll add some reconfigure stuff.

I would be checking out this thread every minute or so.

Thank you.

jsakalos
3 Apr 2008, 12:08 PM
I would be checking out this thread every minute or so.

Thank you.
It's not going to be that fast... ;) Anyway, thanks for interest. I may come out with something later today... Latest after weekend.

jsakalos
3 Apr 2008, 12:44 PM
Check it now, I've quickly put together the reconfigure stuff.

jsakalos
3 Apr 2008, 1:59 PM
Beta 1 (http://recordform.extjs.eu) is out.

It does everything I think it should. Give it a try and torture it please...

Thank you.

franklt69
3 Apr 2008, 2:05 PM
Saki some remarks, I thing will be good to have a toolbar with buttons Save, Save and Close, Delete, Cancel, Next(go to next record), Previous(go to previous record) ect I mean using toolbar you have more options, other thing will be good to get the difference (I mean only fields modified) from the original records, with its fields modified when the user click save, I can do a xml and send it to server, parser it and updatedatabase.

Other, trouble I think when the form need Fieldset, (I think it will be good to simple form) when the layout is complicate (column, fieldset ect could be hard)

regards and thanks again for share this wonderful ux

regards
Frank

jsakalos
3 Apr 2008, 2:21 PM
Frank, I'm not sure if I'm willing to go in the direction of adding features. Because: 1) it just complicates code and makes it more bug prone and, more important, 2) I do not want to throw to user tons of buttons and toolbars he may never need (like e.g. M$ Word).

I'm neither planning to go in the direction of some custom layouts (e.g. Fieldsets). If users needs them they have to design their own forms with all the bells and whistles they want.

This should stay simple and straightforward: Plug it into an any grid, even auto-configured and get form access to fields both from column model (displayed in the grid) and store (not in column model).

I've meant it to be K.I.S.S.

Anyway, thank you for your interest and ideas.

violinista
3 Apr 2008, 10:50 PM
Wonderful, thanks Saki!

Cheers

sinma
3 Apr 2008, 11:38 PM
Saki,

You are my idol! I love your extensions!

This extension could be very useful!!

But, at the moment, does it show any form? I have tried to click to 'add' button and it doesn't show nothing.

Thanks for your contribution!

Wolfgang
4 Apr 2008, 12:19 AM
Click the Edit Icon :-)

JamesC
4 Apr 2008, 12:25 AM
As Wolfgang says I also get a problem that the edit button does nothing in IE7...

sinma
4 Apr 2008, 2:21 AM
Yes, it works ok with FF, but when you click the edit button in IE7 does nothing.

mjlecomte
4 Apr 2008, 3:30 AM
Yes, it works ok with FF, but when you click the edit button in IE7 does nothing.

Saki already stated he doesn't like Micro$oft. ;) :))

jsakalos
4 Apr 2008, 3:45 AM
Yes, it was IE specific bug in RowActions that is now fixed.

Thank you for pointing out.

mjlecomte
4 Apr 2008, 3:46 AM
I played with it, looks good. A couple of remarks for information, not requests.

I tried the add record and it didn't do anything, maybe it's disabled or something, didn't inspect (firefox).

Probably just your implementation, but you have action, qtip which can be updated, however nothing to indicate user of dirty records to save. If you did use this on an application I'd wonder about somehow displaying that a record is modified if editable information is not displayed in the grid (only available via the form or column is hidden). Probably not the intent of your demo, I just mention as observation.

Again, probably just your example, but I looked to see how action/qtip would be affected out of curiosity, but maybe they're not activated/used. I obviously didn't spend too much time inspecting the code.

As a suggestion, you might save yourself some headaches to post summary responses to questions in your first post to avoid repeats. Some of your extensions get popular with comments and user X may not read page Y of Z of the thread to find out whatever and ask you again, etc.

jsakalos
4 Apr 2008, 3:47 AM
Saki already stated he doesn't like Micro$oft. ;) :))

Well, I like Micro$oft as it produces perfect hardware products. I use no other mouse or keyboard but this brand.

They should stick with what they are doing well. ;)

jsakalos
4 Apr 2008, 3:55 AM
I played with it, looks good. A couple of remarks for information, not requests.

I tried the add record and it didn't do anything, maybe it's disabled or something, didn't inspect (firefox).

Not implemented yet. You see it is the matter of the application and I haven't implemented it there.



Probably just your implementation, but you have action, qtip which can be updated, however nothing to indicate user of dirty records to save. If you did use this on an application I'd wonder about somehow displaying that a record is modified if editable information is not displayed in the grid (only available via the form or column is hidden). Probably not the intent of your demo, I just mention as observation.
True, I'll think about adding a "dirty" css class to the whole record so user can visualize the dirtiness to his liking.


Again, probably just your example, but I looked to see how action/qtip would be affected out of curiosity, but maybe they're not activated/used. I obviously didn't spend too much time inspecting the code.
RowActions are not bound to the store in this app. I just use the same store as for RowActions demo so fields are there so I used them. Changing neither action nor qtip has an visual effect.


As a suggestion, you might save yourself some headaches to post summary responses to questions in your first post to avoid repeats. Some of your extensions get popular with comments and user X may not read page Y of Z of the thread to find out whatever and ask you again, etc.You're right. Or I'll put 'em in a FAQ section on the demo page.

JamesC
4 Apr 2008, 3:59 AM
Well, I like Micro$oft as it produces perfect hardware products. I use no other mouse or keyboard but this brand.

They should stick with what they are doing well. ;)

Funny you should say that I just bought a new microsoft wireless keyboard and mouse combo and as you say they certainly can make mice/keyboards.

jsakalos
4 Apr 2008, 4:03 AM
Funny you should say that I just bought a new microsoft wireless keyboard and mouse combo and as you say they certainly can make mice/keyboards.
Yeah, I liked these combos/sets most. Especially good was that "ergonomic" keyboard. I don't know if they still produce it - I use notebook now. (HP/Compaq is my favorite brand.)

mjlecomte
5 Apr 2008, 9:07 AM
Saki, I went exploring a bit for educational purposes and have a couple of questions, although my questions appear unrelated to the actual plugin, more about your grid extension implementation. Hopefully ok to post in this thread for these questions. :)



Example.Grid1 = Ext.extend(Ext.grid.EditorGridPanel, {
layout:'fit'
,border:false
,stateful:false
,url:'process-request.php'
,objName:'company'
,idName:'compID'
What are you doing with objName and idName?

It looks like you're going to use objName server side.


,baseParams:{cmd:'getData', objName:this.objName}

So I gather you've sent directions to route you to the appropriate controller ('cmd') but then I couldn't guess what you're going to do with the objName.

As for idName, I didn't really understand much for that one:

switch(options.params.cmd) {
case 'saveData':
var records = this.store.getModifiedRecords();
Ext.each(records, function(r, i) {
if(o.insertIds && o.insertIds[i]) {
r.set(this.idName, o.insertIds[i]);
delete(r.data.newRecord);
}
});
this.store.commitChanges();
break;
I gather you've sent back from server side a json property insertIds, but I don't quite get the set and delete parts. :-?

jsakalos
5 Apr 2008, 9:19 AM
Here you are MJ,

cmd stands, as you already understand, for a command to execute. It can be something like: getData, saveData, deleteRecord, or any command your server script understands.

objName stands for an "object" that we want to execute the command with. There is also server-side script included in the download so you can study it in full, but here is an excerpt:


$objects = array(
// {{{
// company
"company"=>array(
"table"=>"company"
,"idName"=>"compID"
,"fields"=>array(
"compID"
,"company"
,"price"
,"change"
,"pctChange"
,"lastChange"
,"industry"
,"action1"
,"qtip1"
,"action2"
,"qtip2"
,"action3"
,"qtip3"
,"note"
)
)
// }}}
);
In a multi-table environment we should know which fields we have, what is the table name, etc. Therefore, if I send objName:'company' server looks in the above table and has all necessary data available.

idName is forgotten in client sources in fact as a remain of devel process and it is name of the field in a table that holds primary key. In our case it would be compID. This is important as if you send {cmd:'deleteRecord', objName:'company', id:33} we need to create an sql so we need id-to-primary-key mapping.

Should you have more questions, just post here, no problem.

jsakalos
5 Apr 2008, 9:26 AM
Aaah, one more,

my server-side script can insert new records or update old ones in one request. You can edit grid records, add new ones and the click save and all works.

It is done such a way, that new records get property newRecord:true so server knows where to use update sql and where to use insert sql.

insertIds is array of primary key values of newly inserted records that client receives as the response from server so it can update underlying records in the store by removing newRecord property and setting correct ids for them. Otherwise you wouldn't be able to delete newly inserted records jus after clicking Save (Submit) as you wouldn't have ids to send to server for the delete command. Also update would fail or, better to say, it wouldn't update as id would be null (for those new records) so update sql wouldn't find any matching records.

mjlecomte
5 Apr 2008, 9:44 AM
My mistake, I didn't realize (or forgot probably because I think you mentioned somewhere) that php script was included. I'll look further at the php file in the zip (I was just poking around the js in firebug initially).

I'm with you on the explanation. I had already been using a primaryKey property similar to your idName, so I'm with you there. I had also been passing a table property as well, but I think your method may be a more powerful way to approach it, I'll dig around some more.... ;)



Aaah, one more,

my server-side script can insert new records or update old ones in one request. You can edit grid records, add new ones and the click save and all works.

It is done such a way, that new records get property newRecord:true so server knows where to use update sql and where to use insert sql.

I'm going to review this bit further. At the moment I'm playing with having a save button on the toolbar. There is also a preferences menu button on the toolbar where you can select the save mode preference (instant, manual or when leaving a row). The save button enables/disables depending on the save mode. Anyway, batching up the client side data to send to the server depends a bit on the saveMode.

I was originally using a similar newRecord property. But I have changed that to sending the recordID. In the config I set newKey: -1. When a new record is added client side it is assigned the current value of newKey and then then newKey is decremented by one in case another record is added. Server side, I check if the value of the recordID is less than 1, if it is I do an insert, otherwise I use the update sql. I have this complexity in there because a user can add multiple records before "saving". So this way each added record has a unique record id.
Similar to what you mention below, once the server returns the response I can update new records to have the actual database primaryKey value instead of the negative number it got initially.



insertIds is array of primary key values of newly inserted records that client receives as the response from server so it can update underlying records in the store by removing newRecord property and setting correct ids for them. Otherwise you wouldn't be able to delete newly inserted records jus after clicking Save (Submit) as you wouldn't have ids to send to server for the delete command. Also update would fail or, better to say, it wouldn't update as id would be null (for those new records) so update sql wouldn't find any matching records.
I'm not sure if I have a problem like you elude to here. So far I haven't been able to break it. But I'm not sure if I'm in "save instantly" saveMode if someone can modify a newly created record fast enough where there may be some moment when there's a cross in communication before the new record gets it's "real primary key" assigned.

jsakalos
5 Apr 2008, 12:44 PM
Yeah, these are 2 workable approaches to one problem. I usually don't use instant save so returning real insertIds is vital.

I like your "fake negative" id as you can identify records safely. I rely on the order assuming that submitted records have some order and insertIds have same order. This method works reliably too though.

oracio
6 Apr 2008, 12:57 AM
hello Saki,

This extension is exactly what i was looking for, so thanks a lot!
I understand that it is still in an early beta version, but just for you knowledge, it doesnt work well on IE7: the Add Recrod doesnt work and when i open the edit record and save it, the page stucks.

Anyways, i just wanted to inform you about those issues and for your question if you should keep working on this extantion, in my opinion. Y-E-S! ;)

jsakalos
6 Apr 2008, 2:08 AM
Add button is not a part of the extension, it's part of the demo application. I haven't had time to implement it yet. I'll take a look at the another issue in IE7.

jsakalos
6 Apr 2008, 3:02 AM
I've done add record - check it out now.

wm003
6 Apr 2008, 3:27 AM
That's awesome and very useful! Thanks for sharing, saki ;)

AlxH
6 Apr 2008, 7:22 AM
Very nice Plugin, indeed!
Thank you for sharing!

I think if it is to be used in Autogrid too, the following lines has to be removed from the createFormConfig Method:



// run only once
if(this.form) {
return;
}

jsakalos
6 Apr 2008, 9:33 AM
No, reconfigure destroys old form. Take a look.

AlxH
6 Apr 2008, 1:09 PM
No, reconfigure destroys old form. Take a look.


Ok, i see... But there seems to be a small hole: when reconfigure happens before the window has been rendered. In your onDestroy the form is nulled only if there was already a window.
Unluckyly that was the case in my app.

josephf
6 Apr 2008, 7:42 PM
This is perfect: exactly what I desperately (and urgently) need. Sadly, I can't get it to work becasuse of the process-request.php with PDO and sqlite. I've revised the process-request.php script to query a mssql database and removed the PDO. I successfully construct the array object to return to recordform.js but don't know how to return it. No matter what I try firebug shows the return is simply "Array"

This is actually a Php question, of course: how do I return the query result object to recordform.js? I'm asking it here in the hope that someone has already done such a revision to process-request.php and has a working script using a mysql or mssql database and without PDO...


$result = mssql_query("$sql",$dbh);
if(!$result) { ShowError("query $sql failed"); }
while ($row_object = mssql_fetch_object($result))
{
$count++;
$response[] = $row_object;
}

$retval = array();
if ($count >= 1)
{
$retval['success'] = 1;
$retval['totalCount'] = $count;
$retval[rows] = $response;
}

A print_r of the return value saved to logfile looks perfect:

Array
(
[success] => 1
[totalCount] => 21
[rows] => Array
(
[0] => stdClass Object
(
[config_id] => 1
[config_name] => test one
[company_include] => QRTT
[company_exclude] =>
[callstatus] =>
[delay_repeatcall] => 90
[max_calls] => 3
[stale_date] => 5
[active] => 1
)

[1] => stdClass Object
(
[config_id] => 2
[config_name] => test two
[company_include] => RFTP
[company_exclude] =>
[callstatus] => 2
[delay_repeatcall] => 120
[max_calls] => 5
[stale_date] => 5
[active] => 1
)

etc...

jsakalos
7 Apr 2008, 1:17 AM
For PHP 5.x it's easy: json_encode([Object|Array]). If you're on PHP 4.x then you need to google for some JSON coding/decoding routine...

jsakalos
7 Apr 2008, 1:21 AM
Ok, i see... But there seems to be a small hole: when reconfigure happens before the window has been rendered. In your onDestroy the form is nulled only if there was already a window.
Unluckyly that was the case in my app.
I haven't tested it in fact, but it shouldn't matter. Grid's reconfigure takes cm and store as arguments to new cm and new store have to be known when it runs. Just after grid's reconfigure runs plugin's reconfigure that creates new config object for form; it does instantiate neither form nor window. They are instantiated on the first show.

Theoretically, the above should just work, please test it in real app if you can.

jsakalos
7 Apr 2008, 1:25 AM
I haven't tested it in fact, but it shouldn't matter. Grid's reconfigure takes cm and store as arguments to new cm and new store have to be known when it runs. Just after grid's reconfigure runs plugin's reconfigure that creates new config object for form; it does instantiate neither form nor window. They are instantiated on the first show.

Theoretically, the above should just work, please test it in real app if you can.
You're right about onDestroy routine; I've added checking and destroying form too.

jsakalos
7 Apr 2008, 1:36 AM
josephf,

BTW, if you can, use PDO to access databases. It simplifies that many things...

mjlecomte
7 Apr 2008, 3:34 AM
For PHP 5.x it's easy: json_encode([Object|Array]). If you're on PHP 4.x then you need to google for some JSON coding/decoding routine...
There's actually a stickied thread (http://extjs.com/forum/showthread.php?t=2362) on this.

AlxH
7 Apr 2008, 8:58 AM
Hello Josef,
Im playing around with your plugin in my app. Works pretty nice now.

You might also want to display the header if no editor is defined:



,createFormConfig:function() {
[...]

if(c && c.editor && c.editor.field) {
[...]
}

// use this.mapping to get field xtype
else {
Ext.apply(o, {
fieldLabel:(c && c.header ? c.header:f.name)
,xtype:this.mapping[f.type] || 'textfield'
});
if('date' === f.type && f.dateFormat) {
o.dateFormat = f.dateFormat;
}
}
[...]
}

AlxH
7 Apr 2008, 9:23 AM
One more thing :-))
If working with autogrids it may be useful to pass the editor with metadata also in 'xtype' notation like:
{ name:'someColumn', header:'my first column', type: 'string', editor:{'xtype'
: 'textfield', name:'someColumn'}}

To do that, one could do something like that:



if(c && c.editor && c.editor.field) {
if (c.editor.field.getXType){ // dont know if there is a better way to check for an instance
Ext.apply(o, {
xtype:c.editor.field.getXType()
,fieldLabel:c.header
}, c.editor.field.initialConfig);
} else {
Ext.apply(o,c.editor);
o.fieldLabel=c.header;
}
}



What do you think?

greetings,
Alex

jsakalos
7 Apr 2008, 12:44 PM
Well, the current logic is: You configure your column model (either statically from javascript or by receiving metaData from server) with some highly customized inputs (validation, decimal precision, combos with stores, etc.). Now, the plugin init runs and if it finds a column model editor then it uses it so all features and config options of original column editor are available in the form.

If it doesn't find a column model editor it uses a "default" one (see mapping config option) depending on field type in the store. If I understand well you want some customized editors for fields that do not have column model editor and are not visible it the grid, right?

If so, you can configure cm for such fields, so plugin can take their editors, but hide them from users so they don't see columns in the grid but can edit them in the form.

I want to keep it simple as it is best way to have it bug free and easily configured.

Or, am I missing the point?

jsakalos
7 Apr 2008, 12:48 PM
Hello Josef,
Im playing around with your plugin in my app. Works pretty nice now.

You might also want to display the header if no editor is defined:



,createFormConfig:function() {
[...]

if(c && c.editor && c.editor.field) {
[...]
}

// use this.mapping to get field xtype
else {
Ext.apply(o, {
fieldLabel:(c && c.header ? c.header:f.name)
,xtype:this.mapping[f.type] || 'textfield'
});
if('date' === f.type && f.dateFormat) {
o.dateFormat = f.dateFormat;
}
}
[...]
}

Yes, good idea. Implemented.

Thank you.

jahong
7 Apr 2008, 7:33 PM
hi JS, i`m a very very noobie...
in your editor grid, why the edit button can delete the data ?? and also the search feature won`t work for my case...
thank you

indrajit_bin_rahwana
7 Apr 2008, 11:09 PM
Hallo Josef,

I have downloaded RecordForm and set it all but Search Menu and Save Menu aren't working, could I have some help on this problem ?

Thanks

Indrajit

AlxH
8 Apr 2008, 12:36 AM
Well, the current logic is: You configure your column model (either statically from javascript or by receiving metaData from server) with some highly customized inputs (validation, decimal precision, combos with stores, etc.). Now, the plugin init runs and if it finds a column model editor then it uses it so all features and config options of original column editor are available in the form.

If it doesn't find a column model editor it uses a "default" one (see mapping config option) depending on field type in the store. If I understand well you want some customized editors for fields that do not have column model editor and are not visible it the grid, right?

If so, you can configure cm for such fields, so plugin can take their editors, but hide them from users so they don't see columns in the grid but can edit them in the form.

I want to keep it simple as it is best way to have it bug free and easily configured.

Or, am I missing the point?

Of course, you are right.
Its just in my implementation of the autogrid in which the editors are not automatically instanciated for the columnmodel, so at time of plugin-init the editor is plain json.
So forget my remark.8)

jsakalos
8 Apr 2008, 3:17 AM
Your remarks are very valuable as they give me another viewpoints. Go on with them if you have any... ;)

mjlecomte
8 Apr 2008, 4:12 AM
hi JS, i`m a very very noobie...
in your editor grid, why the edit button can delete the data ?? and also the search feature won`t work for my case...
thank you
There are two buttons in the far right column, one for editing, one for deleting. Did you hit the delete button by accident? See below for second problem.


Hallo Josef,

I have downloaded RecordForm and set it all but Search Menu and Save Menu aren't working, could I have some help on this problem ?

Thanks

Indrajit

won't or aren't working are pretty vague. You guys are not very specific in describing what the problem is. Sounds like a server side issue perhaps? What does firebug show for the post and response when you try saving/searching?

jsakalos
8 Apr 2008, 4:26 AM
What is Search Menu? What is Save Menu? What means "aren't working"?

jahong
8 Apr 2008, 4:37 AM
the firebugs is shows nothing when i`m try to save the data, and after i edit the data in the grid and try to save it, there`s a error message like this

{"success":false,"error":"Table, data or idName is missing"}firebugs (post):

cmd=saveData&objName=company&data=%5B%7B%22compID%22%3A15%2C%22company%22%3A%22Honeywell%20Intl%20Inc2%22%7D%5Dand when try search data, firebugs (post) shows this :

start=0&limit=15&cmd=getData&objName=company&sort=compID&dir=ASC&fields=%5B%22compID%22%2C%22company%22%5D&query=exx
and the response is :


{"success":true,"totalCount":31,"rows":[{"compID":"1","company":"3m Co"},{"compID":"2","company":"Alcoa Inc"},{"compID":"3","company":"Altria Group, Inc."},{"compID":"4","company":"American Express Company"},{"compID":"5","company":"American International Group, Inc."},{"compID":"6","company":"AT&T Inc."},{"compID":"7","company":"Boeing Co."},{"compID":"8","company":"Caterpillar Inc."},{"compID":"9","company":"Citigroup, Inc."},{"compID":"10","company":"E.I. du Pont de Nemours and Company"},{"compID":"11","company":"Exxon Mobil Corp"},{"compID":"12","company":"General Electric Company"},{"compID":"13","company":"General Motors Corporation"},{"compID":"14","company":"Hewlett-Packard Co."},{"compID":"15","company":"Honeywell Intl Inc"}]}
sorry for my poor english....

jsakalos
8 Apr 2008, 4:48 AM
You need to adjust downloaded sources for your local installation. Such options like url or similar that changed with moving to your host. Also, you may need to change permissions to db.sqlite as server process (httpd) has to have write access to it.

Generally, if it works on demo site (http://recordform.extjs.eu) and not at your host, then look what is different.

jahong
8 Apr 2008, 5:05 AM
thankz JS, at your demo site, i`m try to search the data, and the Firebugs (Post) is like this:

start=0&limit=10&cmd=getData&objName=company&sort=company&dir=ASC&fields=%5B%22company%22%2C%22price%22%2C%22change%22%2C%22lastChange%22%2C%22industry%22%2C%22note%22%5D&query=boeingand the Firebugs (response) like this :


{"success":true,"totalCount":1,"rows":[{"compID":"7","company":"Boeing Co.","price":"75.43","change":"0.53","pctChange":"0.71","lastChange":"","industry":"Computer","action1":"icon-disk","qtip1":"Click to Save","action2":"icon-open","qtip2":"Click to Open","action3":"icon-key","qtip3":"Click to Unlock","note":"Big planes...and cool stuff\n"}]}
At my localhost, the firebugs (post) is same, but response is shows all the data....(total count still 53)
it looks like the search feature won`t work at my localhost...
thank you

jsakalos
8 Apr 2008, 7:13 AM
Your server-side script has to take care about filtering data out. It also depends on PHP configuration on your host. Take a look at the server script.

jahong
8 Apr 2008, 9:58 AM
Your server-side script has to take care about filtering data out. It also depends on PHP configuration on your host. Take a look at the server script.

thankz JS, ...
it`s all work at my host, you`re right, i`ve set my php.ini to :


; default magic_quotes_gpc = ON
magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off

jsakalos
8 Apr 2008, 11:43 AM
Perfect! I'm glad you found the solution.

indrajit_bin_rahwana
8 Apr 2008, 11:49 AM
Search Menu and Save Menu work well after I set php.ini with the following config. :

magic_quotes_gpc = Off
magic_quotes_runtime = Off
magic_quotes_sybase = Off



Thanks anyway Josef :-)

loic
8 Apr 2008, 11:52 AM
Saki,

Thanks a lot for another wonderful "K.I.S.S. plugin".
I can make it run smoothly with firefox but have a small problem with the form when using IE6/7.

When clicking on OK, IE returns an unspecified error on line 1063 and the debugger seems to indicate a problem in ext-base.js on :

b = el.getBoundingClientRect();

I give a try on recordform.extjs.eu and have got the same problem with the 2 versions of IE.

edited: The problem only exist with "edit record". "Add record" is OK

Can you confirm the problem ?

Loic

PS: sorry for the approximative english, french is my mother language.

jsakalos
8 Apr 2008, 12:17 PM
Fixed. It was not a problem in the plugin itself but in the example application. It was related to window show animation target.

loic
8 Apr 2008, 11:59 PM
Thanks for the quick reply Saki but it seems the problem is not solved.
I still get the error on recordform.extjs.eu when the onOK function of the plugin is invoked in "edit record" mode.

I saw the last modification you've made in the example application :

click:{scope:this, buffer:200, fn:function(btn) {
this.recordForm.show(this.addRecord(), btn.getEl());

but can't figure out how to use it to correct the problem with "editor mode".

jsakalos
9 Apr 2008, 5:22 AM
OK, I've disabled hide animation globally - I'm not willing to hunt for this non-plugin IE/Ext bug. I also like it more as it works faster.

loic
9 Apr 2008, 9:31 AM
Thanks a lot. Everything is ok now.
Your plugin is really helpful and I learn slowly but surely reading your code.

indrajit_bin_rahwana
9 Apr 2008, 5:29 PM
Hallo everyone,

I am adding oci engine into getOdb function.
Do I have to make a custom function to mimick
$odb->sqliteCreateFunction("regexp", "regexp", 2) ?
Does oci has it's own function similar to sqliteCreateFunction ?

Thanks

jsakalos
9 Apr 2008, 6:22 PM
I don't know... ;) I just needed to simulate mySQL's rlike functionality.

josephf
9 Apr 2008, 7:44 PM
Thanks, Saki: I was able to get my mssql version to properly return the data. It doesn't do me any good, though, as I'm taking your advice and trying to use PDO rather then re-write the whole csql.php (although I'd still jump on it if someone else did ;)

indrajit_bin_rahwana: I'm looking for non-sqlite variations of CreateFunction, also, and will post if I work something out.

jahong
10 Apr 2008, 11:30 PM
hi SAKI,
please help me, i`m tryin` to call the "this.commitChanges" which resides in recordform.js from SIMPAN button on Record Form dialog window (1) as shown in picture, so that i can directly save data to the database without click the SIMPAN button on the grid panel (2). This is because i`m trying not to use the SIMPAN button on the grid panel. I am going to omit them (SIMPAN and RESET buttons) from grid panel. What should i do ???
The ilustration below :

http://img239.imageshack.us/img239/39/recformtestnb7.gif

i haven`t experienced yet....
thnkz before.

jsakalos
11 Apr 2008, 2:40 AM
Are you calling it in the right scope?

See: What is that Scope all about (http://extjs.com/forum/../learn/Tutorial:What_is_that_Scope_all_about)

winnel
11 Apr 2008, 4:37 AM
Wonderful, grat work,thanks Saki!

AlxH
13 Apr 2008, 7:56 AM
Its not specifically related to this plugin, but I ran into the following:
If you change data in a paged grids store and then switch to next page in the pagingtoolbar, one would like to notify the user that data would be lost if he is continuing.
So I have implemented a confirmation message in the "beforeload"-event of the grids store.
But if you return false to cancel the stores load, the loading icon of the pagingtoolbar stays active, because neither onLoad nor onLoadError gets called.
Since there is no loadcancel event its not easy to catch this one.
Or am i missing something here?


Greets,
Alex

jsakalos
13 Apr 2008, 8:37 AM
Resetting the busy indicator is job to be done in the event handler when returning false. I've chosen another approach: I've extended paging toolbar adding enable/disable methods that mask/unmask it and disable controls. Whenever there are dirty records on the page I disable paging toolbar so user has either to submit or reset.

AlxH
13 Apr 2008, 9:26 AM
Resetting the busy indicator is job to be done in the event handler when returning false. I've chosen another approach: I've extended paging toolbar adding enable/disable methods that mask/unmask it and disable controls. Whenever there are dirty records on the page I disable paging toolbar so user has either to submit or reset.

Thank you, Jozef!
Ill try that too.
Seems to be a valuable feature of the pagingtoolbar. Should also be incorporated the ext release, i think.

jsakalos
13 Apr 2008, 10:10 AM
Here is my override, you don't need to re-invent the wheel. However, please check the code, I've written it long ago, you may find some bugs or improvements:


// additional methods of paging toolbar
// {{{
Ext.override(Ext.PagingToolbar, {

// enable toolbar elements
enable: function(disable) {
// setup variables
disable = disable ? true : false;
var d = this.getPageData();
var ap = d.activePage;
var ps = d.pages;

// mask/unmask
if(disable) {
this.getEl().mask();
}
else {
this.getEl().unmask();
}

this.first.setDisabled(!disable ? ap === 1 : disable);
this.prev.setDisabled(!disable ? ap === 1 : disable);
this.next.setDisabled(!disable ? ap === ps : disable);
this.last.setDisabled(!disable ? ap === ps : disable);
this.field.dom.disabled = disable;
this.loading.disabled = disable;
this.loading.el.disabled = disable;

// an optional filter field
if(this.filter) {
this.filter.dom.disabled = disable;
}
if(this.plugins instanceof Array) {
Ext.each(this.plugins, function(p) {
p.setDisabled(disable);
});
}
}

// disable toolbar components
, disable: function() {
this.enable(true);
}

, reload: function() {
this.store.load({params: {start: this.cursor, limit: this.pageSize}});
}

});
// }}}

indrajit_bin_rahwana
13 Apr 2008, 6:03 PM
Hai Jozef,
Is there something about scoping in callback ?


// original
case 'saveData':
var records = this.store.getModifiedRecords();
Ext.each(records, function(r, i) {
if(o.insertIds && o.insertIds[i]) {
r.set(this.idName, o.insertIds[i]); // this.idName = 'undefined'
delete(r.data.newRecord);
}
});
this.store.commitChanges();
break;

// modified
case 'saveData':
var records = this.store.getModifiedRecords();
var idname = this.idName;
Ext.each(records, function(r, i) {
if(o.insertIds && o.insertIds[i]) {
r.set(idname, o.insertIds[i]); // idname works fine
delete(r.data.newRecord);
}
});
this.store.commitChanges();
break;

regards,

Indrajit

jsakalos
14 Apr 2008, 2:28 AM
Bug. But it has already been corrected (on April 11). It reads now:


,commitChanges:function() {
var records = this.store.getModifiedRecords();
if(!records.length) {
return;
}
var data = [];
Ext.each(records, function(r, i) {
var o = r.getChanges();
if(r.data.newRecord) {
o.newRecord = true;
}
o[this.idName] = r.get(this.idName);
data.push(o);
}, this);
var o = {
url:this.url
,method:'post'
,callback:this.requestCallback
,scope:this
,params:{
cmd:'saveData'
,objName:this.objName
,data:Ext.encode(data)
}
};
Ext.Ajax.request(o);
} // eo function commitChanges

concep86
14 Apr 2008, 4:04 AM
Risking seriously bodily injury... :D:D

Can I ask you Saki to post an example using a simple data store... like one of the extjs examples.... :">:">

I have been looking at your example and just cant get it to work...


P.S. i love your plugins....

jsakalos
14 Apr 2008, 5:37 AM
http://recordform.extjs.eu/source.php?file=recordform.js

around line 148

jsakalos
15 Apr 2008, 4:07 PM
Hi all!

RecordForm Beta (http://recordform.extjs.eu) 2 is out.

The new feature added is row highlighting for new records and dirty (edited) records.

Don't forget to hard reload the page, caching is set to 3 days.

Cheers,
Saki

cobnet
15 Apr 2008, 4:48 PM
Resetting the busy indicator is job to be done in the event handler when returning false. I've chosen another approach: I've extended paging toolbar adding enable/disable methods that mask/unmask it and disable controls. Whenever there are dirty records on the page I disable paging toolbar so user has either to submit or reset.

This does not seem to work in latest Beta2? Using IE7. I changed the Industry field on the last record of the first page. It does highlite as dirty record, however paging toolbar is not disabled?

jsakalos
15 Apr 2008, 5:01 PM
Disabling paging toolbar is not part of this plugin.

cobnet
15 Apr 2008, 11:23 PM
Disabling paging toolbar is not part of this plugin.

Thanks for the reply! I will dig-in and see what else is not part of the plugin. I definitely understand the KISS idea and think that all plugins need to follow this logic, but if a plugin needs added features it would be nice to know this from the download page?

On another note: if a user is to edit a record by clicking an edit button, one would think when they are finished editing and click the appropriate "SAVE", "FINISH" or whatever button that their editing would be saved?

I can see where a developer would know the many different options available for saving a record, however sometimes our applications are working with not so knowledgeable users. The KISS idea is to "SAVE" when finished editing, right or wrong?

I am not giving you trouble with your work, I definitely appreciate you taking the time to show how this idea of editing a record with an auto-generated form can be done. Great idea, there are many situations where one wants to have fields that are not part of the current grid to be available on an "ADD NEW RECORD" or "EDIT" form. But trying to explain to an end-user why their 10 minutes of editing was not saved can be fun!

I know this is just a base-code example and the developer should modify the coding to serve their appropriate application. We are all looking for something that does not require us to do anything but cut and paste the code and it works from there on, lol. This is a dream world after all.

After all this typing, a new idea came up, maybe a simple "HELP", "ABOUT" or "FAQ" button could help the end-user understand why their editing was not saved, or what additional steps are needed for the record to be saved? Maybe this new button could be standard for all plugins. Something for the EXT team to ponder about?

First off it could give credit where credit is due, to the author of the plugin. Next it could detail the version of the plug: "ALPHA", "BETA", whatever. Where to goto for help, details, etc. This last part probably should not be posted directly at your plugin, but I am just throwing up ideas.

Please don't take this wrong, I would not waste may time if I did not think that this plugin was worth the effort. B)

jsakalos
16 Apr 2008, 2:35 AM
Thanks for the reply! I will dig-in and see what else is not part of the plugin. I definitely understand the KISS idea and think that all plugins need to follow this logic, but if a plugin needs added features it would be nice to know this from the download page?

On another note: if a user is to edit a record by clicking an edit button, one would think when they are finished editing and click the appropriate "SAVE", "FINISH" or whatever button that their editing would be saved?

I can see where a developer would know the many different options available for saving a record, however sometimes our applications are working with not so knowledgeable users. The KISS idea is to "SAVE" when finished editing, right or wrong?

Record is saved. To store. Plugin cannot save it to server. You can listen to store datachange event and send it to server yourself.



I am not giving you trouble with your work, I definitely appreciate you taking the time to show how this idea of editing a record with an auto-generated form can be done. Great idea, there are many situations where one wants to have fields that are not part of the current grid to be available on an "ADD NEW RECORD" or "EDIT" form. But trying to explain to an end-user why their 10 minutes of editing was not saved can be fun!

I know this is just a base-code example and the developer should modify the coding to serve their appropriate application. We are all looking for something that does not require us to do anything but cut and paste the code and it works from there on, lol. This is a dream world after all.

After all this typing, a new idea came up, maybe a simple "HELP", "ABOUT" or "FAQ" button could help the end-user understand why their editing was not saved, or what additional steps are needed for the record to be saved? Maybe this new button could be standard for all plugins. Something for the EXT team to ponder about?

First off it could give credit where credit is due, to the author of the plugin. Next it could detail the version of the plug: "ALPHA", "BETA", whatever. Where to goto for help, details, etc. This last part probably should not be posted directly at your plugin, but I am just throwing up ideas.

Please don't take this wrong, I would not waste may time if I did not think that this plugin was worth the effort. B)You see, I won't add any more user-visible controls to this plugin. If you need them you need to add them yourself.

mjlecomte
16 Apr 2008, 3:57 AM
After all this typing, a new idea came up, maybe a simple "HELP", "ABOUT" or "FAQ" button could help the end-user understand why their editing was not saved, or what additional steps are needed for the record to be saved? Maybe this new button could be standard for all plugins. Something for the EXT team to ponder about?

First off it could give credit where credit is due, to the author of the plugin. Next it could detail the version of the plug: "ALPHA", "BETA", whatever. Where to goto for help, details, etc. This last part probably should not be posted directly at your plugin, but I am just throwing up ideas.

Please don't take this wrong, I would not waste may time if I did not think that this plugin was worth the effort. B)

Your thoughts are appreciated, but as you stated, the KISS is the basic premise. Only put what is the bare minimum for the plugin to function. The other stuff you talk about may be nice depending on what a developer wants.

What you could do is post your modifications to the examples forum and post a link back here. That way you could showcase your version for others to get ideas or cut/paste as they want.

jahong
16 Apr 2008, 11:20 AM
I`ve made some modification to recordform.js, Ext.ux.grid.RecordForm.js, process-request.php, csql.php.
The modification of delete, add, and edit is in one click, so no need to click save button on the bottom right (that`s what i asked into this forum).

File is in zip, and sorry for rough modification JS...:">

jsakalos
16 Apr 2008, 12:55 PM
Thank you for your modifications, however, I'll keep record form as it is. Why?

Saving data to server doesn't belong to this plugin as it assumes some server backend (idName, url, objName). The server save logic should be executed in store datachanged event if the immediate server save is required by user. http://extjs.com/deploy/dev/docs/?class=Ext.data.Store&member=datachanged For example, immediate data save is inappropriate in my case where I want to retain possibility of "Reset" entered data to original values.

Therefore, the plugins must end with updating record of the grid's store where the data is left for further user processing.

I understand that you may have different requirements, I also see that your code is fine and clean, the only problem is that it is at the wrong place.

jahong
16 Apr 2008, 1:23 PM
...I understand that you may have different requirements, I also see that your code is fine and clean, the only problem is that it is at the wrong place....

Sorry for the wrong place...:">

BTW, i`m really really really thank you to your Plug-In....;)

jsakalos
16 Apr 2008, 1:29 PM
No problem for me, but if you keep it there, what you sure can despite of my advices ;), it can create some application structure problems for you as your application will grow.

robin30
17 Apr 2008, 11:30 PM
i have an editorgrid.

after i edit a cell everthing is updated in my database
through a function save.


function save(oGrid_event){
Ext.Ajax.request({
waitMsg: 'Please wait...',
url: 'php/database.php',
params: {
task: "UPDATEBILL",
id: oGrid_event.record.data.id,
name: oGrid_event.record.data.name,
due: oGrid_event.record.data.due,
amount: oGrid_event.record.data.amount,
paid: oGrid_event.record.data.paid,
paid_when: oGrid_event.record.data.paid_when,
amount_paid: oGrid_event.record.data.amount_paid
},
success: function(response){
var result=eval(response.responseText);
switch(result){
case 1:
store.commitChanges();
store.reload();
break;
default:
Ext.MessageBox.alert('Uh uh...','We couldn\'t save him...');
break;
}
},
failure: function(response){
var result=response.responseText;
Ext.MessageBox.alert('error','could not connect to the database. retry later');
}
});
}

i managed to use your plugin. using the rowaction plugin too.
when i click on the icon, the window opens and i can change things after i press ok little red triangle on top but i can't seem to make the save button work.

correct me if i'm wrong but i do believe it has something to do with the cmd saveData.

so i was wondering if it is possible that as soon as i press the ok button in the window that the function save will get called?

sorry about my english hope you understand what i'm asking.

regards, Sincerely,

Robin30

robin30
18 Apr 2008, 12:21 AM
hi all,

to come back at my question, i found the answer.

in case someone is interest.

in Ext.ux.grid.RecordForm.js i changed this:


onOK:function() {
this.updateRecord();
this.window.hide(null);
}

into


onOK:function() {
this.updateRecord();
commitChanges();
this.window.hide(null);
store.reload();
}

in my main js i added a function commitChanges


commitChanges = function() {
var records = store.getModifiedRecords();
if(!records.length) {
return;
}
var data = [];
Ext.each(records, function(r, i) {
var o = r.getChanges();
if(r.data.newRecord) {
o.newRecord = true;
}
o[this.idName] = r.get(this.idName);
data.push(o);
}, this);
var o = {
url:'php/database.php'
,method:'post'
,callback:this.requestCallback
,scope:this
,params:{
task:'UPDATEPRES'
,id:recordForm.record.data.id
,name:recordForm.record.data.name
}
};
Ext.Ajax.request(o);
} // eo function commitChanges

now if i change the name in the recordForm and i click on ok, the name will be automatically changed in my database and the store will be refreshed so the changes are visible.

thanks for the great plugin

regards,

robin30

robin30
18 Apr 2008, 12:47 AM
in recordForm is it possible to hide a certain field?

now all the fields are shown but 1 field is automatically calculated when i click on ok.
i rather have people no the oppertunity the be able to change that field.

thanks

Sincerely,

Robin30

jsakalos
18 Apr 2008, 2:11 AM
ignoreFields:{compID:true} - I guess this way it is configured on the demo page.

jsakalos
18 Apr 2008, 2:15 AM
To your previous post: I recommend against saving data from plugin. This way 1) you create branch - you will need to apply your changes whenever you update the plugin and 2) more important, saving shouldn't be the job for plugin. Listen to datachanged event of grid's store and do whatever is necessary from the event handler.

robin30
18 Apr 2008, 2:57 AM
thank you for your quick reply, really appreciate it.

i understand what you mean. Gonna try to figure out how the save button works.

Keep up the good work, thanks for taking your time helping me. really appreciate it.

robin30
18 Apr 2008, 5:17 AM
hi all,

i'm trying to do the save button but i can't seem to get it to work.

i can change fields, press ok, little red triangle appears but as soon as i click on save a little window shows up and it says "Unknown Error".

i have apache server + mysql
objName = bills (i assume this is the table name in my database)
idName = id (i assume this is the primairy key in my table)
url='php/database.php'
cmd='update'

in my database.php i do have a function called 'update' this is what it looks like:

function update()
{
$id = $_GET['id'];
$name = $_POST['name'];
$due = $_POST['due'];
$amount = $_POST['amount'];
$paid = $_POST['paid'];
$paid_when = $_POST['paid_when'];
$amount_paid = $_POST['amount_paid'];
if ($paid == 'true'){
$paid = '1';
} else {
$paid = '0';
}
$result="SELECT * FROM bills where id='$id'";
$result1=mysql_query($result);
$rows = mysql_fetch_array($result1);
$amount = $rows['amount'];
$difference = $amount_paid - $amount;

$query = "UPDATE bills SET name = '$name', due='$due', amount='$amount', paid='$paid', paid_when='$paid_when', amount_paid='$amount_paid', difference='$difference' WHERE id=$id";
$result3 = mysql_query($query);
echo '1';
}

i'm pretty sure here's where i go wrong. can someone please tell me what i'm doing wrong and give a kick in my rearend to the right direction i have to go to make this work?

thanks,

regards,

Robin30

robin30
18 Apr 2008, 5:54 AM
firebug is giving me at least something,lol


cmd update
data [{"name":"Penele","id":"53"}]
objName bills

i changed the name of id # 53 so that is correct, but still don't know how to get it changed in my database.

regards,
robin30

jsakalos
18 Apr 2008, 6:03 AM
Take php from demo page and adjust it. In each step test when it stops to work. BTW, I'd use PDO if possible - saves a lot of headaches.

robin30
18 Apr 2008, 7:52 AM
i looked at the php file,

i'm using the same files as you do, Saki, now i get a message date or idname missing.

i'm loosing really sleep over this, (:| ;).

i do have a different setup for the grid as you, if i use for example this.idName firefox goes ballastic.

so i made var out if it all.

this is my code for the grid:

var grid = new Ext.grid.EditorGridPanel({
id:'lol',
enableColLock:false,
url:'php/database.php',
objName:'bills',
idName:'id',
// sm: new Ext.grid.RowSelectionModel({singlerow:true}),
width:700,
height:500,
ds: store,
cm: cm,
sm:sm,
plugins: [summary, action, new Ext.ux.grid.Search({
iconCls:'icon-zoom'
,readonlyIndexes:['all']
,disableIndexes:['amount'],
mode:'local',
position:'top',
align:'right'
}), recordForm],
trackMouseOver:false,
loadMask: true,
frame:false,
viewConfig: {
forceFit:true
},

bbar: new Ext.PagingToolbar({
pageSize: 15,
store: store,
displayInfo: true
}),
buttons:[{
text:'Save'
,iconCls:'icon-disk'
,scope:this
,handler: commitChanges
},{
text:'Reset'
,iconCls:'icon-undo'
,scope:this
,handler:function() {
this.store.rejectChanges();
}
}],
tbar:[{
text: 'Add Bill',
iconCls:'add',
tooltip: 'Add Bill',
handler: addbillform
},'-',{
text: 'Delete Bill(s)',
iconCls:'remove',
tooltip: 'Delete Selected Bill',
handler: deleteContextMenu
}
//,'-',{
// text: 'Pay Bill',
// iconCls:'money',
//tooltip: 'Pay Selected Bill',
// handler: paidbillform
//}
,'-']
});


ListingContextMenu = new Ext.menu.Menu({
id: 'ListingEditorGridContextMenu',
items: [
{ text: 'Pay Bill', iconCls:'money', handler: paidbillform },
{ text: 'Add Bill', iconCls:'add', handler: addbillform },
{ text: 'Delete Bill', iconCls:'remove', handler: deleteContextMenu }
// ,'-',
// { text: 'Print this grid', iconCls:'printer', handler: printListingContextMenu }
]
});
grid.addListener('rowcontextmenu', onListingEditorGridContextMenu);

the commitChanges i did put in a var too:


var commitChanges = function() {
var records = store.getModifiedRecords();
if(!records.length) {
return;
}
var data = [];
Ext.each(records, function(r, i) {
var o = r.getChanges();
if(r.data.newRecord) {
o.newRecord = true;
}
o[idName] = r.get('id');
data.push(o);
});
var o = {
url:'php/modified.php'
,method:'post'
,callback:requestCallback
,params:{
cmd:'saveData'
,objName:'bills'
,data:Ext.encode(data)
}
};
Ext.Ajax.request(o);
} // eo function commitChanges

var requestCallback = function(options, success, response) {
if(true !== success) {
this.showError(response.responseText);
return;
}
try {
var o = Ext.decode(response.responseText);
}
catch(e) {
this.showError(response.responseText, 'Cannot decode JSON object');
return;
}
if(true !== o.success) {
this.showError(o.error || 'Unknown error');
return;
}

switch(options.params.cmd) {
case 'saveData':
var records = store.getModifiedRecords();
Ext.each(records, function(r, i) {
if(o.insertIds && o.insertIds[i]) {
r.set('id', o.insertIds[i]);
delete(r.data.newRecord);
}
});
store.commitChanges();
break;

case 'deleteData':
break;
}
} // eo function requestCallback

var showError = function(msg, title) {
Ext.Msg.show({
title:title || 'Error'
,msg:Ext.util.Format.ellipsis(msg, 2000)
,icon:Ext.Msg.ERROR
,buttons:Ext.Msg.OK
,minWidth:1200 > String(msg).length ? 360 : 600
});
}

because this.idName and this.objName didn't/doesn't work with me i please it all with

'id' and 'bills'


this is my php file:
[PHP]<?
// vim: ts=4:sw=4:nu:fdc=4:nospell

require("csql.php");

if(!isset($_POST["cmd"])) {
return;
}

$objects = array(
// {{{
// company
"bills"=>array(
"table"=>"bills"
,"idName"=>"id"
,"fields"=>array(
"id"
,"name"
,"due"
,"amount"
,"paid"
,"paid_when"
,"amount_paid"
,"difference"

)
)
// }}}
);

// create PDO object and execute command
$osql = new csql();
$_POST["cmd"]($osql);

// command processors
// {{{
/**
* getData: Outputs data to client
*
* @author Ing. Jozef Sak

joku
18 Apr 2008, 8:15 AM
I just played with the demo @ http://recordform.extjs.eu/ .
It looks good!

When I added a record via the regular add and then tried to delete it without entering any data into it, I couldn't delete it.

jsakalos
18 Apr 2008, 8:27 AM
Delete is not implemented, anyway it is not part of the plugin.

AlxH
22 Apr 2008, 11:17 AM
I had a small issue when destroying and recreating the recordform object.
It took me hours to find out what is causing it. The following seems to fix it:
Replace


var config = Ext.apply(this.defaultWindowConfig, this.windowConfig);

With


var config={};
Ext.apply(config,this.defaultWindowConfig);
Ext.apply(config, this.windowConfig);


in the show-function.

jsakalos
22 Apr 2008, 12:02 PM
What could be the reason? Any references to defaultWindow config that get overridden? Or you supply defaultWindowConfig? Or you re-use defaultWindowConfig?

AlxH
22 Apr 2008, 12:49 PM
What could be the reason? Any references to defaultWindow config that get overridden? Or you supply defaultWindowConfig? Or you re-use defaultWindowConfig?

Im not that deep into javascript. Could it be possible, that the defaultWindowConfig property is treated as class-property so that it is reused in the following instanciations? That would explain the strange behaviour, because you use an "applyIf" to assign the form item and listeners.
The effect I observed, was that on the second instance in the listeners the form and window properties where null.

jsakalos
22 Apr 2008, 1:15 PM
Cannot say anything before I see it. Do you have a showcase? ... must be some stupid simple thing...

boonkerz
22 Apr 2008, 3:15 PM
Hello

have Problems with using 2 grids with forms in one tab panel item:

this is my test code:
as no paste: http://nopaste.php-quake.net/26357
and here:


grid1 = Ext.extend(Ext.grid.EditorGridPanel, {
url:'/admin/account/?config=2'
,id: 'accountv'
,objName:'account'
,idName:'id'
,frame: true
,autoHeight: true
,initComponent:function() {
this.recordForm = new Ext.ux.grid.RecordForm({
title:'Account'
,id:'accountform'
,iconCls:'icon-edit-record'
,columnCount:1
,ignoreFields:{id:true}
,formConfig:{
labelWidth:80
,buttonAlign:'right'
,bodyStyle:'padding-top:10px'
}
});

// create row actions
this.rowActions = new Ext.ux.grid.RowActions({
actions:[{
iconCls:'icon-minus'
,qtip:'Delete Record'
},{
iconCls:'icon-edit-record'
,qtip:'Edit Record'
}]
,widthIntercept:Ext.isSafari ? 4 : 2
,id:'actionsaccount'
});
this.rowActions.on('action', this.onRowAction, this);

Ext.apply(this, {
// {{{
store:new Ext.data.Store({
reader:new Ext.data.JsonReader({
id:'id'
,totalProperty:'totalCount'
,root:'rows'
,fields:[
{name:'id', type:'int'}
,{name:'company', type:'string'}

]
})
,proxy:new Ext.data.HttpProxy({url:this.url})
,baseParams:{cmd:'getData', objName:this.objName}
,sortInfo:{field:'company', direction:'ASC'}
,remoteSort:true
})
// }}}
// {{{
,columns:[{
header:'Name'
,id:'company'
,dataIndex:'company'
,width:160
,sortable:true
,editor:new Ext.form.TextField({
allowBlank:false
})
}, this.rowActions]
// }}}
,plugins:[new Ext.ux.grid.Search({
iconCls:'icon-zoom'
,readonlyIndexes:['note']
,disableIndexes:['pctChange']
}), this.rowActions, this.recordForm]
,viewConfig:{forceFit:true}
,buttons:[{
text:'Save'
,iconCls:'icon-disk'
,scope:this
,handler:this.commitChanges
},{
text:'Reset'
,iconCls:'icon-undo'
,scope:this
,handler:function() {
this.store.rejectChanges();
}
}]
,tbar:[{
text:'Add Record'
,iconCls:'icon-plus'
,listeners:{
click:{scope:this, fn:this.addRecord,buffer:200}
}
},{
text:'Add Record'
,iconCls:'icon-form-add'
,listeners:{
click:{scope:this, buffer:200, fn:function(btn) {
this.recordForm.show(this.addRecord(), btn.getEl());
}}
}
}]
}); // eo apply

this.bbar = new Ext.PagingToolbar({
store:this.store
,displayInfo:true
,pageSize:10
});

// call parent
grid1.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
// {{{
,onRender:function() {
// call parent
grid1.superclass.onRender.apply(this, arguments);

// load store
this.store.load({params:{start:0,limit:10}});

} // eo function onRender
// }}}

,addRecord:function() {
var store = this.store;
if(store.recordType) {
var rec = new store.recordType({newRecord:true});
rec.fields.each(function(f) {
rec.data[f.name] = f.defaultValue || null;
});
rec.commit();
store.add(rec);
return rec;
}
return false;
} // eo function addRecord

,onRowAction:function(grid, record, action, row, col) {
switch(action) {
case 'icon-minus':
this.deleteRecord(record);
break;

case 'icon-edit-record':
this.recordForm.show(record, grid.getView().getCell(row, col));
break;
}
} // eo onRowAction

,commitChanges:function() {
var records = this.store.getModifiedRecords();
if(!records.length) {
return;
}
var data = [];
Ext.each(records, function(r, i) {
var o = r.getChanges();
if(r.data.newRecord) {
o.newRecord = true;
}
o[this.idName] = r.get(this.idName);
data.push(o);
}, this);
var o = {
url:this.url
,method:'post'
,callback:this.requestCallback
,scope:this
,params:{
cmd:'saveData'
,objName:this.objName
,data:Ext.encode(data)
}
};
Ext.Ajax.request(o);
} // eo function commitChanges

,requestCallback:function(options, success, response) {
if(true !== success) {
this.showError(response.responseText);
return;
}
try {
var o = Ext.decode(response.responseText);
}
catch(e) {
this.showError(response.responseText, 'Cannot decode JSON object');
return;
}
if(true !== o.success) {
this.showError(o.error || 'Unknown error');
return;
}

switch(options.params.cmd) {
case 'saveData':
var records = this.store.getModifiedRecords();
Ext.each(records, function(r, i) {
if(o.insertIds && o.insertIds[i]) {
r.set(this.idName, o.insertIds[i]);
delete(r.data.newRecord);
}
});
this.store.commitChanges();
break;

case 'deleteData':
break;
}
} // eo function requestCallback

,showError:function(msg, title) {
Ext.Msg.show({
title:title || 'Error'
,msg:Ext.util.Format.ellipsis(msg, 2000)
,icon:Ext.Msg.ERROR
,buttons:Ext.Msg.OK
,minWidth:1200 > String(msg).length ? 360 : 600
});
} // eo function showError

,deleteRecord:function(record) {
Ext.Msg.show({
title:'Delete record?'
,msg:'Do you really want to delete <b>' + record.get('company') + '</b><br/>There is no undo.'
,icon:Ext.Msg.QUESTION
,buttons:Ext.Msg.YESNO
,scope:this
,fn:function(response) {
if('yes' !== response) {
return;
}
// console.info('Deleting record');
}
});
} // eo function deleteRecord

}); // eo extend

grid2 = Ext.extend(Ext.grid.EditorGridPanel, {
url:'/admin/account/?config=3'
,id:'contactv'
,objName:'account'
,idName:'id'
,frame: true
,autoHeight: true
,title: 'Contacts'
,initComponent:function() {
this.recordForm2 = new Ext.ux.grid.RecordForm({
title:'Contact'
,id:'contactform'
,iconCls:'icon-edit-record'
,columnCount:1
,ignoreFields:{id:true}
,formConfig:{
labelWidth:80
,buttonAlign:'right'
,bodyStyle:'padding-top:10px'
}
});

// create row actions
this.rowActions2 = new Ext.ux.grid.RowActions({
actions:[{
iconCls:'icon-minus'
,qtip:'Delete Record'
},{
iconCls:'icon-edit-record'
,qtip:'Edit Record'
}]
,widthIntercept:Ext.isSafari ? 4 : 2
,id:'actionscontact'
});
this.rowActions2.on('action', this.onRowAction2, this);

Ext.apply(this, {
// {{{
store:new Ext.data.Store({
reader:new Ext.data.JsonReader({
id:'id'
,totalProperty:'totalCount'
,root:'rows'
,fields:[
{name:'id', type:'int'}
,{name:'name', type:'string'}

]
})
,proxy:new Ext.data.HttpProxy({url:this.url})
,baseParams:{cmd:'getData', objName:this.objName}
,sortInfo:{field:'company', direction:'ASC'}
,remoteSort:true
})
// }}}
// {{{
,columns:[{
header:'Name'
,id:'name'
,dataIndex:'name'
,width:160
,sortable:true
,editor:new Ext.form.TextField({
allowBlank:false
})
}, this.rowActions2]
// }}}
,plugins:[new Ext.ux.grid.Search({
iconCls:'icon-zoom'
,readonlyIndexes:['note']
,disableIndexes:['pctChange']
}), this.rowActions2, this.recordForm2]
,viewConfig:{forceFit:true}
,buttons:[{
text:'Save'
,iconCls:'icon-disk'
,scope:this
,handler:this.commitChanges
},{
text:'Reset'
,iconCls:'icon-undo'
,scope:this
,handler:function() {
this.store.rejectChanges();
}
}]
,tbar:[{
text:'Add Record'
,iconCls:'icon-plus'
,listeners:{
click:{scope:this, fn:this.addRecord2,buffer:200}
}
},{
text:'Add Record'
,iconCls:'icon-form-add'
,listeners:{
click:{scope:this, buffer:200, fn:function(btn) {
this.recordForm2.show(this.addRecord2(), btn.getEl());
}}
}
}]
}); // eo apply

this.bbar = new Ext.PagingToolbar({
store:this.store
,displayInfo:true
,pageSize:10
});

// call parent
grid2.superclass.initComponent.apply(this, arguments);
} // eo function initComponent
// {{{
,onRender:function() {
// call parent
grid2.superclass.onRender.apply(this, arguments);

// load store
this.store.load({params:{start:0,limit:10}});

} // eo function onRender
// }}}

,addRecord2:function() {
var store = this.store;
if(store.recordType) {
var rec = new store.recordType({newRecord:true});
rec.fields.each(function(f) {
rec.data[f.name] = f.defaultValue || null;
});
rec.commit();
store.add(rec);
return rec;
}
return false;
} // eo function addRecord

,onRowAction2:function(grid, record, action, row, col) {
switch(action) {
case 'icon-minus':
this.deleteRecord(record);
break;

case 'icon-edit-record':
this.recordForm2.show(record, grid.getView().getCell(row, col));
break;
}
} // eo onRowAction

,commitChanges:function() {
var records = this.store.getModifiedRecords();
if(!records.length) {
return;
}
var data = [];
Ext.each(records, function(r, i) {
var o = r.getChanges();
if(r.data.newRecord) {
o.newRecord = true;
}
o[this.idName] = r.get(this.idName);
data.push(o);
}, this);
var o = {
url:this.url
,method:'post'
,callback:this.requestCallback
,scope:this
,params:{
cmd:'saveData'
,objName:this.objName
,data:Ext.encode(data)
}
};
Ext.Ajax.request(o);
} // eo function commitChanges

,requestCallback:function(options, success, response) {
if(true !== success) {
this.showError(response.responseText);
return;
}
try {
var o = Ext.decode(response.responseText);
}
catch(e) {
this.showError(response.responseText, 'Cannot decode JSON object');
return;
}
if(true !== o.success) {
this.showError(o.error || 'Unknown error');
return;
}

switch(options.params.cmd) {
case 'saveData':
var records = this.store.getModifiedRecords();
Ext.each(records, function(r, i) {
if(o.insertIds && o.insertIds[i]) {
r.set(this.idName, o.insertIds[i]);
delete(r.data.newRecord);
}
});
this.store.commitChanges();
break;

case 'deleteData':
break;
}
} // eo function requestCallback

,showError:function(msg, title) {
Ext.Msg.show({
title:title || 'Error'
,msg:Ext.util.Format.ellipsis(msg, 2000)
,icon:Ext.Msg.ERROR
,buttons:Ext.Msg.OK
,minWidth:1200 > String(msg).length ? 360 : 600
});
} // eo function showError

,deleteRecord:function(record) {
Ext.Msg.show({
title:'Delete record?'
,msg:'Do you really want to delete <b>' + record.get('company') + '</b><br/>There is no undo.'
,icon:Ext.Msg.QUESTION
,buttons:Ext.Msg.YESNO
,scope:this
,fn:function(response) {
if('yes' !== response) {
return;
}
// console.info('Deleting record');
}
});
} // eo function deleteRecord

});
// register xtype
Ext.reg('grid1', grid1);
Ext.reg('grid2', grid2);
// app entry point
Ext.QuickTips.init();
var accountpan = new Ext.Panel({
labelWidth:80,
url:'login',
frame:true,
autoHeight: true,
height: 200,
renderTo: 'accountindex',
title:'Accounts',
// Specific attributes for the text fields for username / password.
// The "name" attribute defines the name of variables sent to the server.
items:[{xtype:'grid1', id:'grid1'}]
});
accountpan.show();
var contactpan = new Ext.Panel({
labelWidth:80,
url:'login',
frame:true,
autoHeight: true,
height: 200,
renderTo: 'accountindex2',
title:'Accounts',
// Specific attributes for the text fields for username / password.
// The "name" attribute defines the name of variables sent to the server.
items:[{xtype:'grid2', id:'grid2'}]
});
contactpan.show();


When i click on edit row in first grid it works.
when i click on edit row in the second grid it will display the form from the first grid.

Thanks for Help

jsakalos
22 Apr 2008, 3:29 PM
I was trying to run your code but I do not see any onReady function. If you don't have it add it, if you have it post please the complete code that I can copy&paste&run.

Thanks.

boonkerz
22 Apr 2008, 3:36 PM
Hi

I Load the code into an tabpanel.

the app.js looks like:

[CODE]
DocPanel = Ext.extend(Ext.Panel, {
closable: true,
autoScroll:true,

initComponent : function(){
var ps = this.cclass.split('.');
this.title = ps[ps.length-1];

DocPanel.superclass.initComponent.call(this);
},

scrollToMember : function(member){
var el = Ext.fly(this.cclass + '-' + member);
if(el){
var top = (el.getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
this.body.scrollTo('top', top-25, {duration:.75, callback: this.hlMember.createDelegate(this, [member])});
}
},

scrollToSection : function(id){
var el = Ext.getDom(id);
if(el){
var top = (Ext.fly(el).getOffsetsTo(this.body)[1]) + this.body.dom.scrollTop;
this.body.scrollTo('top', top-25, {duration:.5, callback: function(){
Ext.fly(el).next('h2').pause(.2).highlight('#8DB2E3', {attr:'color'});
}});
}
},

hlMember : function(member){
var el = Ext.fly(this.cclass + '-' + member);
if(el){
el.up('tr').highlight('#cadaf9');
}
}
});

MainPanel = function(){



MainPanel.superclass.constructor.call(this, {
id:'doc-body',
region:'center',
margins:'0 5 5 0',
resizeTabs: true,
minTabWidth: 135,
tabWidth: 135,
plugins: new Ext.ux.TabCloseMenu(),
enableTabScroll: true,
activeTab: 0,

items: {
id:'welcome-panel',
title: '

jsakalos
22 Apr 2008, 3:44 PM
Doesn't work copy & pasted:

1) TabCloseMeny I've commented out, but
2) POST http://extjseu.localhost/admin/app/tree 404
3) GET http://extjseu.localhost/admin/app/overview 404
4) this.el has no properties

boonkerz
22 Apr 2008, 3:47 PM
yes because it is an php app the tree becomse date from an php script.

i will zip an example app. :)

jsakalos
22 Apr 2008, 3:47 PM
BTW, your last code doesn't reference RecordForm.... ???

jsakalos
22 Apr 2008, 3:48 PM
Well, but unless I can run the code I cannot debug it....

boonkerz
22 Apr 2008, 4:48 PM
Hello,

I have edit you example code to see the problem:

[CODE]
// vim: sw=4:ts=4:nu:nospell:fdc=4
/**
* Ext.ux.grid.RecordForm Plugin Example Application
*
* @author Ing. Jozef Sak

amit.shukld
22 Apr 2008, 9:56 PM
hi friend i am empressed alot with the way you solve the problems can you let me know how we can add element in a grid dependeing upon two values in the main form, let me tell you my requirement, i have to add that many months in the grid column as many as the difference between start date and duration.
Suppose i have start date 4/23/2008 and duration 20 months so how i can add from april to 20 months ahead like april, may, june..............

AlxH
22 Apr 2008, 10:30 PM
Hello,

When you click on add record on the first grid and the form is showing and then you click close and open the form of the secound grid you see the form from the first grid. and the buttons are not working.

in my version i have also rename all vars eg this.recordform to make a difference from grid1 to grid2 but it will not work :)

Tanks

Sounds a lot like the problem I found in my previous post.
Maybe you can try what helped me:
http://extjs.com/forum/showthread.php?p=157186#post157186
So we can find out if it is the same.

jsakalos
22 Apr 2008, 11:00 PM
boonkerz,

try it now. BTW, the way you put 2 grids in window is wrong. Put them in border layout, each region 'fit' layout. Grid has to have a kind of dimensions and autoHeight/autoWidth doesn't work with grids.

boonkerz
23 Apr 2008, 2:37 AM
Hello

It works thanks for work and help.

jsakalos have say it is an patch in this thread but i could it not found.

Thanks a lot

jsakalos
23 Apr 2008, 2:43 AM
The "patch" is already applied.

cobnet
23 Apr 2008, 9:10 PM
... Record is saved. To store. Plugin cannot save it to server. You can listen to store datachange event and send it to server yourself.

Ok I can see why you would not always want to save the data immediately. There may be more changes needed and why waste a server call if there is more to be edited. I can also see why you may want the option to RESET the data, if you change your mind about editing a record. Sure the data is saved to the store, however as soon as you click the paging toolbar for the next or previous page of the grid, those changes are now gone from the store, correct?

It may be just me, but I would like a warning that my editing will be lost if I continue to the next page, right?

Ok following your instructions above, "Listen to the store datachange event and send it to the server yourself". Can you give an example on how this may be accomplished? If I listen to the datachange event, this event should fire on all editing? So the changes are saved to the store so I then wait for the paging click or the store reload event to fire off the database save?

It just seems like a warning window, ex: "Your changes will be lost if you do not save now" would be much easier. Of course you do have the knowledge of how to tie this all into a big app, how would you recommend, or should I say when would you recommend saving this data to the database the right way?

I am not looking for the server side coding on this save feature, only your suggested timing to fire it off. Thanks again for your time, I see alot of folks are repeating this same query over and over.

cobnet
23 Apr 2008, 9:16 PM
Your thoughts are appreciated, but as you stated, the KISS is the basic premise. Only put what is the bare minimum for the plugin to function. The other stuff you talk about may be nice depending on what a developer wants.

What you could do is post your modifications to the examples forum and post a link back here. That way you could showcase your version for others to get ideas or cut/paste as they want.

Sorry, I was not looking at modifying this plugin, just throwing ideas up! I thought that this was Beta coding and was still in development. I also thought he was looking for ideas, suggestions, bugs etc. I simply thought this was a bug, however I see now that it is not.

loic
24 Apr 2008, 12:18 AM
Hello,

I have performance problems using the plugin with Internet Explorer 6/7.
I personally use Firefox but a lot of users must use IE, so...

I use a border layout with a treePanel menu in the west and a tabPanel inthe center region.
A new grid takes about 10 s to render (once the tab is created). So is the first invocation of the form (7s)

With Firefox, everything is OK (1 or 2s for the first render).

The form performance problem is the same on recordform.extjs.eu

Any suggestion is welcomed.

Thanks,

Loic

jsakalos
24 Apr 2008, 12:36 AM
Ok I can see why you would not always want to save the data immediately. There may be more changes needed and why waste a server call if there is more to be edited. I can also see why you may want the option to RESET the data, if you change your mind about editing a record. Sure the data is saved to the store, however as soon as you click the paging toolbar for the next or previous page of the grid, those changes are now gone from the store, correct?

Exactly. When to save data is solely developer/customer decision. I've seen application that save (to server) on field blur (not even per-record change but per-field change), I have seen saving on per-record basis and I personally use per-page saving. You can edit many records seen on one page and then you save (or reset) them in one shot.



It may be just me, but I would like a warning that my editing will be lost if I continue to the next page, right?I disable paging toolbar if data is dirty in real application; I've already posted code of that somewhere here. You can also listen to beforeload event of store where you would test if data is dirty, you would display message box and depending on answer you would continue with load, cancel the load or save-and-then-continue with load.



Ok following your instructions above, "Listen to the store datachange event and send it to the server yourself". Can you give an example on how this may be accomplished? If I listen to the datachange event, this event should fire on all editing? So the changes are saved to the store so I then wait for the paging click or the store reload event to fire off the database save?
You would do this if you wanted per-record saving.



It just seems like a warning window, ex: "Your changes will be lost if you do not save now" would be much easier. Of course you do have the knowledge of how to tie this all into a big app, how would you recommend, or should I say when would you recommend saving this data to the database the right way?
See above.



I am not looking for the server side coding on this save feature, only your suggested timing to fire it off. Thanks again for your time, I see alot of folks are repeating this same query over and over.Server side: Go to http://extjs.eu and find linke "I want Saki's FileTree backend".

jsakalos
24 Apr 2008, 12:37 AM
Hello,

I have performance problems using the plugin with Internet Explorer 6/7.
I personally use Firefox but a lot of users must use IE, so...

I use a border layout with a treePanel menu in the west and a tabPanel inthe center region.
A new grid takes about 10 s to render (once the tab is created). So is the first invocation of the form (7s)

With Firefox, everything is OK (1 or 2s for the first render).

The form performance problem is the same on recordform.extjs.eu

Any suggestion is welcomed.

Thanks,

Loic
First time the form is displayed it is created in fact. All subsequent show/hide cycles should be faster

loic
24 Apr 2008, 1:56 AM
First time the form is displayed it is created in fact. All subsequent show/hide cycles should be faster

It works as you say. But do you have an idea on what can explain the difference between IE et Firefox ? As I say in the previous post, it takes 10s to load a grid from the click on the west panel where Firefox takes only 1s. And 7s for the form vs 1s.

If it can help, I can put online an example application...

jsakalos
24 Apr 2008, 2:13 AM
I really don't know... :( Is there any other thread on forums that deals with grid@IE performance? (I don't use IE so I don't pay attention to such subjects....)

loic
24 Apr 2008, 2:35 AM
OK, I understand.
Unfortunately, I did'n't find anything relevant in the forums. And as I'm a near ExtJS beginner, I don't know where to look in the code.
This IE is really a pity. I switch to ExtJS partially to get rid of these browsers problems but I see it's not so evident as I first believed.
Perhaps, I'll try to do a small application that shows the problem an try to ask for some help in another thread...
Is it the way to do ?

jsakalos
24 Apr 2008, 2:49 AM
I've just tested IE7 with http://recordform.extjs.eu and it's pretty fast. Full page reload is about 5s, normal reload 3- s.

Could you test on another machine if it is not a local IE installation problem?

loic
24 Apr 2008, 4:18 AM
I've just tested IE7 with http://recordform.extjs.eu and it's pretty fast. Full page reload is about 5s, normal reload 3- s.

Could you test on another machine if it is not a local IE installation problem?

Saki,

You're right... one more time.
On a brand new Windows XP/IE7, it's perfect. I think I will not try to understand what's happening on the faulty one ;).
Thanks a lot for your help and sorry for the noise.

jsakalos
24 Apr 2008, 5:18 PM
I think I will not try to understand what's happening on the faulty one.

I wouldn't even try to understand what's going on in the new one... ;)

Anyway, I'm glad that the problem is neither in Ext nor in my plugin... :)

kai5263499
25 Apr 2008, 1:51 PM
I've made a dynamic DB table editor using your excellent code but I'm having problems when using multiple instances of the editorgrid, specifically when I try to use the edit rowaction to bring up a record editor.

If I load two grids and click the edit row action on the second grid it brings up the window just fine, but if I close it and then click on the row edit icon on the first grid it brings up the same window with blank values (which I assume is because its using the wrong index).

If I load two grids and click the edit row action on the first grid, it gives me an error of:
c has no properties
http://dev.fuzebox/js/ext-all-debug.js
Line 13926

Any ideas on what I'm doing wrong?

jsakalos
25 Apr 2008, 1:55 PM
Get devel version. It has been fixed there (hopefully it is same bug).

kai5263499
25 Apr 2008, 8:42 PM
Thanks, that seemed to do the trick!

robin30
26 Apr 2008, 1:17 PM
hi all,

question if you guys don't mind.

i use RecordForm and it works perfect.

but now i have a question about the title of with window.

this is my code:

var recordForm = new Ext.ux.grid.RecordForm({
title:'Modify'
,iconCls:'icon-edit-record'
,columnCount:2
,ignoreFields:{id:true, difference:true, name:true }
,formConfig:{
labelWidth:80
,buttonAlign:'right'
,bodyStyle:'padding-top:10px'
}
});

the title is "Modify",
one of the ignored Fields is "name",
how can the put the value of the field "name" as a title?

for example if the value of the field "name" = hallo, then how can i get the title to be
"Modify hallo".

hope someone can help me with this.

regards,

Robin30

jsakalos
27 Apr 2008, 4:58 AM
There is no built-in way how to translate field names into window title. Anyway, there is windowConfig object. Have you tried that?

nojutsu
27 Apr 2008, 11:27 PM
Hi all,
First of all, thanks to Saki for all, with your plugins,
my apps is progressing well ^^:)

I have a question : could I set in a Grid, a specific field into a specific state ?

I develop : in your exemple, the column compagny, line 2 (group by id or another thing),
is there a function to say : THIS field, you can ONLY read it, not change it ?

I have looking for this sort of function in the API, in your plugin, but i have no found it (am I no wake up ?)

A little precision, I don't want to set all the specific column in my grid, just ONE field in a specific line/column.

Thanks for ALL response

jsakalos
28 Apr 2008, 2:05 AM
Hmm, I've never needed it, so only a hint: Override function startEditing. This function receives col and row as arguments you can use to decide if you allow editing or not.

nojutsu
28 Apr 2008, 5:16 AM
thanks but the problem is : in my database, I have an array where there is for each field, for each column, a boolean which said "yes/no this field is/isn't editable".
so I reseach a function to modify to say the same thing, when I insert my data in the grid.

I tried to insert a row number with the function rownumberer(), so I can select a specific line, in a specific column, but, I tried to use the startEditing function but I didn't know where using it.

cobnet
28 Apr 2008, 8:16 AM
Exactly. When to save data is solely developer/customer decision. I've seen application that save (to server) on field blur (not even per-record change but per-field change), I have seen saving on per-record basis and I personally use per-page saving. You can edit many records seen on one page and then you save (or reset) them in one shot.
I disable paging toolbar if data is dirty in real application; I've already posted code of that somewhere here. You can also listen to beforeload event of store where you would test if data is dirty, you would display message box and depending on answer you would continue with load, cancel the load or save-and-then-continue with load.
You would do this if you wanted per-record saving.
See above.
Server side: Go to http://extjs.eu and find linke "I want Saki's FileTree backend".

Perfect! Exactly what I was looking for, thanks for taking the time here.
Mark

cobnet
28 Apr 2008, 8:28 AM
How to change the value of objName or similar?:

If you wanted to change the value of the "objName" or the "wb" variable below how would this be done?

I have tried from your example:


.... (missing code here, but it matches your download code)

Example.Grid1 = Ext.extend(Ext.grid.EditorGridPanel, {
layout:'fit'
,border:false
,stateful:false
,url:'system/modules/webBase/wbNameSearch/wbNameSearch2.php'
,objName:'fname'
,idName:'mainid'
,wb:'Crawford'

.... (missing code here, but it matches your download code)

Ext.apply(this, {
// {{{
store:new Ext.data.Store({
id: 'nameStore'
,reader:new Ext.data.JsonReader({
id:'mainid'
,totalProperty:'totalCount'
,root:'rows'
,fields:[
{name:'mainid', type:'int'}
,{name:'treeid', type:'string'}
,{name:'parentsid', type:'string'}
,{name:'title', type:'string'}
,{name:'fname', type:'string'}
,{name:'mname', type:'string'}
,{name:'surname', type:'string'}
,{name:'suffix', type:'string'}
,{name:'aka', type:'string'}
,{name:'gender', type:'string'}

,{name:'date', type:'string'}
]
})
,proxy:new Ext.data.HttpProxy({url:this.url})
,baseParams:{cmd:'getData', objName:this.objName, wb:this.wb}
,sortInfo:{field:'fname', direction:'ASC'}
,remoteSort:true
})

.... (missing code here, but it matches your download code)

this sets up the store's baseParams.

I have added a combo box to the toolbar:


.... (missing code here, but it matches your download code)

,tbar:[{
text:'Add Record'
,iconCls:'icon-form-add'
,listeners:{
click:{scope:this, buffer:200, fn:function(btn) {
this.recordForm.show(this.addRecord(), btn.getEl());
}}
}
},{
text:'-'
},
new Ext.form.ComboBox({
id: 'wbSelect'
,store:new Ext.data.SimpleStore({
id:'wbStore'
,fields:['surname','wbName']
,data:[
['Cochrane','Cochrane']
,['Crawford','Crawford']
,['Forlong', 'Forlong']
,['Gordon', 'Gordon']
,['Patterson', 'Patterson']
,['Wallace','Wallace']
]
})
,displayField:'surname'
,valueField:'wbName'
,value: 'Crawford'
,triggerAction:'all'
,mode:'local'
,forceSelection:true
,listeners: {
select:{scope:this, buffer:200, fn:function() {
this.changeWB();
}}
}
})
]

.... (missing code here, but it matches your download code)

,changeWB:function() {
this.wb = Ext.getCmp('wbSelect').getValue();
alert(this.wb + " - this is not working yet and it is driving me crazy?");
this.store.load({params:{start:0, limit:10, wb:this.wb}});

} // eo function changeWB
.... (missing code here, but it matches your download code)


Now when I run to the code I can see from the alert that this.wb does indeed have the new chosen value from the combo box, however when the store loads, it does not pass along this new value, it goes back to the original setting? It seems to ignore my:

"this.store.load({params:{start:0, limit:10, wb: this.wb}})" line? or at least the wb parameter???

I did make some progress when I took the wb setting out of the baseParams in the nameStore and my combo box setting was passed along correctly, however I need this param passed along on every request to reload the store.

Any help on where I am going wrong here would be greatly appreciated!

jsakalos
28 Apr 2008, 9:35 AM
I think the route you've chosen is the right one; just add wb to baseParams - they are sent with each request.

cobnet
28 Apr 2008, 9:51 AM
I think the route you've chosen is the right one; just add wb to baseParams - they are sent with each request.

This makes me feel alittle better, ;)

but I do have wb in the baseParams as you can see in the above coding. Is this value a "READ-ONLY" value and cannot be changed?

jsakalos
28 Apr 2008, 9:54 AM
baseParams is primitive thing: object with name/value pairs that are sent with each ajax request. Nothing more, nothing less. Also, you can change baseParams at any time; before the request of course.

concep86
28 Apr 2008, 2:48 PM
the page loads, but the grid is empty...

can anyone post the json for this page "process-request.php"

thanks

concep86

mjlecomte
28 Apr 2008, 3:56 PM
You'll see the json if you inspect the response in firebug, no?

cobnet
28 Apr 2008, 5:16 PM
baseParams is primitive thing: object with name/value pairs that are sent with each ajax request. Nothing more, nothing less. Also, you can change baseParams at any time; before the request of course.

Yes this can be a challenge but I figured out a way for it to work:


,changeWB:function() {
this.wb = Ext.getCmp('wbSelect').getValue();
// alert(this.wb + " - this is not working yet and it is driving me crazy?");

this.store.baseParams['wb'] = this.wb;

this.store.load({params:{start:0, limit:10}});
} // eo function getWB



of course not if you hadn't lead me there, B)

This was a 3 day puzzle for me, now on to the next piece! Thanks for your time.

jsakalos
29 Apr 2008, 3:03 AM
Yeah, it is that simple. ;)

lkasdorf
1 May 2008, 8:37 AM
Hi Saki- thanks for this great plugin as well as all your other great code. You are a huge asset to this community.

I've created a pre-configured class with a grid editor and I'm using your rowactions and recordform plugins. All is well except when it comes to capturing and saving data changes from the form.

I set up a listener on the grid's store for the datachanged event. I see this event getting fired when the store is loaded, but not after I enter changes in your form and click OK. I set up an event watcher on the store to see what's happening, and I see an update event for every time your code does a record set. But I do not see a datachanged event when it is all done. Does this only happen after a commit?

Here is where I set the listener- I do it in the onrender of the preconfigured class:



,onRender:function() {
this.store.on("datachanged", this.updateRecord, this);
Ext.util.Observable.capture(this.store, function(e){console.info(e)}); // watch store events
Ext.ux.ClientGrid.superclass.onRender.apply(this, arguments);
this.loadStore();
} // eo function onRender


Here is my updateRecord handler:


,updateRecord: function (oGrid_Event, theRecord, theOp){
console.log("updateRecord");

if (oGrid_Event.record) // this is to determine if this is the result of loadStore
{
var theParams = new cloneObject(theRecord.data);
theParams.recordId = theRecord.id;

Ext.Ajax.request(
{
scope:this
,method: "POST"
,waitMsg: 'Saving changes...'
,url: 'scripts/updateClientRecord.php'
,params:theParams
,failure:function(response,options){
Ext.MessageBox.alert('Warning','Trouble writing changes to database. Refresh and try again.');
this.store.rejectChanges();//undo any changes
} //end failure block
,success:function(response,options){
var responseData = Ext.util.JSON.decode(response.responseText);//passed back from server
this.store.commitChanges();
//refreshClientGrid();
}//end success block
}); //end request
}
}


Sure enough, I see the datachanged event and my updateRecord being called when the store is loaded. But not after editing the record with recordform.

What I DO see is update events that happen for every field that you set in your updateRecord function:



// this is from Ext.ux.grid.RecordForm.js
,updateRecord:function() {
// loop through form fields and update underlying record
this.form.getForm().items.each(function(item, i) {
this.record.set(item.name, item.getValue()); // this triggers an update event
}, this);
} // eo function updateRecord


I tried adding a commit on the record to your updateRecord function, but that still didn't do it.

If I call my updateRecord on the update event, it will be called for each field change in the record- not what I want!

What am I missing here?

Thanks!

jsakalos
1 May 2008, 10:03 AM
Yes, you're right, datachanged event doesn't fire. I was wrong when I was somewhere talking about it.

The event that does fire is store's update event. Listen to that.

lkasdorf
1 May 2008, 12:14 PM
Yes, you're right, datachanged event doesn't fire. I was wrong when I was somewhere talking about it.

The event that does fire is store's update event. Listen to that.

Saki-
Thanks for the reply. The problem with listening to the update event is that it is fired for every single field in the record that is updated. I want my function to be called only after all of the fields in the record have been set.

I have fixed it like this: I added a third argument to your show method- I pass in the grid's store:


this.recordForm.show(record, grid.getView().getCell(row, col), this.store);


In your show method, I save the store:


,show:function(record, animEl, theStore) {
this.theStore = theStore;
. . .


And in your updateRecord method, I manually fire the datachanged event, supplying the store. I could avoid all this passing the store around, but I figured I'd populate the datachanged event as it supposed to be.



,updateRecord:function() {
// loop through form fields and update underlying record
this.form.getForm().items.each(function(item, i) {
this.record.set(item.name, item.getValue());
}, this);

if (this.theStore)
this.theStore.fireEvent('datachanged', this.theStore);
} // eo function updateRecord


Does this seem like a reasonable approach? It does work.

Moreover, I wonder how others have gotten around this, including yourself?

Thanks

jsakalos
1 May 2008, 12:34 PM
You know what? I'll add afterUpdateRecord function that will be called from updateRecord and will default to emptyFn. Then you can easily override it to achieve what you want.

Gimme a couple of minutes.

jsakalos
1 May 2008, 12:46 PM
OK, grab the code now override afterUpdateRecord and you're done. Tell me how it works then.

lkasdorf
1 May 2008, 6:54 PM
Saki- the addition of the afterUpdateRecord func worked perfectly- an elegant solution.

This is the first time I've overridden a class method- this is how I did it and it worked, so I guess it is right. I assume that you need to do the override before you create an instance of the class.


Ext.override(Ext.ux.grid.RecordForm, {afterUpdateRecord:this.updateRecord});
this.recordForm = new Ext.ux.grid.RecordForm({
title:'Ext.ux.grid.RowRecord Example'
,iconCls:'icon-edit-record'
,columnCount:2
,ignoreFields:{clientId:true}
,formConfig:{
labelWidth:80
,buttonAlign:'right'
,bodyStyle:'padding-top:10px'
}
});


Also, here is a tiny little tip for those using recordForm. When I define my record, I stagger the field definitions so I can understand where they are going to fall on the form:


var clientRecordObj= Ext.data.Record.create([
{name: 'clientId'} //I tell it to ignore this field
,{name: 'fname'}
,{name: 'addr1'}
,{name: 'lname'}
,{name: 'addr2'}
,{name: 'homephone'}
,{name: 'city'}
,{name: 'workphone'}
,{name: 'state'}
,{name: 'cellphone'}
,{name: 'zip'}
,{name: 'faxphone'}
,{name: 'referredby'}
,{name: 'rating'}
,{name: 'notes'}
]);

So this is all working nicely for me now. However, I realize a deficiency to this approach. No validation on the form. But, it is great for a quick data entry form.

Thanks for the code and the help.

jsakalos
2 May 2008, 12:29 AM
Re override: No need to override unless you really want to change prototype. You can pass you function in config as:


this.recordForm = new Ext.ux.grid.RecordForm({
afterUpdateRecord:this.updateRecord
// or
afterUpdateRecrod:function(record) {
// your code here
}
....
})
// or
this.recordForm.afterUpdateRecord = function(record) {
// your code here
};
Re form validation: It is on by default and OK button is bound to form what means it is disabled until the form is valid.

jcwatson11
3 May 2008, 9:15 PM
Hi Saki,

Awesome upgrade for EditorGrid. I like it a lot.

I noticed your EditorGrid has the same problem mine does. Dates don't save. I searched the rest of this thread, but it's pretty long so I'm sorry if I missed it.

I worked the problem down to the fact that the commitChanges function needs to check for date fields in the record before submitting. For some reason it seams that the store's record stores a date field as a javascript Date() object rather than a string. I'm not sure whether I'm doing something wrong, or if it's just a bug.

Anyway, if commitChanges doesn't check for date objects, the date's toString function is automagically calelled by javascript and a huge string is submitted to the server rather than a formatted date. Though then there's another problem in that you would have to have access to the original date field to get the format, and I don't know how to do that.

Here's my change to the function if you're interested. Note I'm not getting the original date field's format property. Still room to improve there.



,commitChanges:function() {
var records = this.store.getModifiedRecords();
if(!records.length) {
return;
}
var data = [];
Ext.each(records, function(r, i) {
var o = r.getChanges();
if(r.data.newRecord) {
o.newRecord = true;
}
o[this.idField] = r.get(this.idField);
for(var i in o) {
if(Ext.isDate(o[i])) {
o[i] = o[i].format('Y-m-d');
}
}
data.push(o);
}, this);
var o = {
url:this.url
,method:'post'
,callback:this.onCommitSuccess
,scope:this
,params:{
cmd:'UU'
,"class":this.mclass
,data:Ext.encode(data)
}
};
Ext.Ajax.request(o);
} // eo function commitChanges


Thanks for all your work Saki!

jcwatson11
3 May 2008, 10:51 PM
Hello again Saki,

Apart from the issue reported above. I also found out that the date's input format coming from the server needs to match the DateField's format property. So the value coming from the database: 2008-04-03T00:00:00 is the reason why dates are not displaying in your demo for RecordForm.

jsakalos
4 May 2008, 4:29 AM
@jcwatson11,

take a look at it now. The whole problem was wrong dataFormat in data store config. Dates were saved but when returned back the format was not recognized.

Anyway, it has not been problem of the plugin itself, it was problem of the demo application.

Thank you for pointing out.

pokerking400
4 May 2008, 8:52 PM
Great plugin. I am using it as a template , mainly because i am learning to create something similiar , instead of copying , i am picking bits and pieces from everywhere and make it my own..that way if i stumble , i will learn more about extjs.

At present i am trying to run your example in my pc but it is missing icons. I just added rowactions part to my code to see how rowactions are added. i have empty column but no icons. I downloaded silk and match the directory path from realtive. Image is there. Still no icons on those colums.

Anyway i will dig more and find out why it is giving me headache..it is more of my lack of understanding...later.

Your plugins are really helpful in understanding things. Keep creating more!.:D.

jsakalos
5 May 2008, 1:19 AM
You need icons.css and correct paths.

pokerking400
5 May 2008, 1:31 AM
icons.css is there and all silk icons as well.

When i try to click row expander + symbol ..nothing happens

And also i do not see action icons.

My setup is little different but i copy everything based on your sample. Something else is missing.. i compared line by line...damn...wasted 5 hrs now...i thought i could figure it...

Every time my cursor goes to action column it throws weird error.

pokerking400
5 May 2008, 1:34 AM
This is the error when i move over action column.

this.config[A] has no properties
http://localhost:81/js/core/ext/ext-all.js
Line 2


this.config[A] has no properties
DomHelper(false)ext-all.js (line 2)
DomHelper(Object browserEvent=Event mouseout button=0 type=mouseout, div.x-grid3-hd-inner)ext-all.js (line 2)
DomHelper(Object browserEvent=Event mouseout button=0 type=mouseout)ext-all.js (line 2)
apply(mouseover clientX=0, clientY=0)ext-base.js (line 2)
[Break on this error] Ext.DomHelper=function(){var L=null;var F=/^(?:br|frame|hr|img|input|link|meta|r...

jsakalos
5 May 2008, 1:36 AM
Have you read the Files and Directories section of this: http://blog.extjs.eu/know-how/writing-a-big-application-in-ext/ ?

I'm not saying that it mustn't be different, however, the above is best I've found out so far.

jsakalos
5 May 2008, 1:37 AM
The error you posted doesn't come from RowActions themselves for 99.99%.

pokerking400
5 May 2008, 1:44 AM
it is.. it is something works and something does n't work.. But it is not your code that gives error...it is me.. something is not linking..something is null and it throws weird error.

My belief is plugins are not attached to panel...i have to dig deeper...

Thanks for the link...i have to figure it out myself... it is all learning process ...:)

pokerking400
5 May 2008, 4:34 AM
what triggers loading of icon.css? It seems like there is no call to all the images in the icon.css

My lack of understanding of who triggers what is the problem.

I try to debug with firebug ..went nowhere...well...:)

pokerking400
5 May 2008, 7:00 AM
I figured it out. As i was using Autogrid , i was adding plugins in meta event instead of initcomponent.

had to separate creation and adding plugins and colum creation.. All working now!.:D

AlxH
6 May 2008, 12:14 AM
@jcwatson11,

take a look at it now. The whole problem was wrong dataFormat in data store config. Dates were saved but when returned back the format was not recognized.

Anyway, it has not been problem of the plugin itself, it was problem of the demo application.

Thank you for pointing out.

I Think there still is a problem with dates:



if('date' === f.type && f.dateFormat) {
o.dateFormat = f.dateFormat;
}


should be



if('date' === f.type && f.dateFormat) {
o.format = f.dateFormat;
}


since a datefield takes a "format" property, not "dateFormat".

greetings,
Alex

jsakalos
6 May 2008, 1:15 AM
Yes, you're right. It's mapping from store... Updating...

pokerking400
6 May 2008, 3:04 AM
This record plugin is useful for my Master detail forms not for normal forms.

Normal forms are Updated in the server side. So i have to use yours as a template and create a Dynamic form window. Is there anyother plugin that basic form feature?

Yours will work well where i can add . delete child records in master/detail form in where people can upload child records finally.

i do things differently. I save it in every call and then call view. Yes it is two calls but very simple processing.

pokerking400
6 May 2008, 3:15 AM
ok i found it. Examples have few forms.. i have to understand that...forms are complex in a sense that i have to create dynamic layout. May be i will have few types of layout and send the layout from server. Wizard layour , plain layout , tablayout.. it will take another 4 days before i get this working...need to think how i am going to make it dynamic.
laters.

pokerking400
7 May 2008, 3:09 AM
Ok as i am browsing through your recordform example , i saw one thing. How do you remove the actions , qtip out of the form fields?.

Any easier way ?..

Thanks
alex

jsakalos
7 May 2008, 4:06 AM
Form fields are independent of grid.

pokerking400
7 May 2008, 4:53 AM
i have to hack it , it seems. I need to filter few fields out of all the records. i had to remove all qtip , action out of forms.

So i am creating another flag for colum model. if i detect that, then i won't display it.

I initially thought forms are generated just before display using record. It is actually generated when the plugins are added.

Your form is ok , i need generic form based on stripped out column model.

Thanks for the reply ..i am still debugging your code to see how it works... :)

Added a flag to all my column meta fields to differentiate between actions and actual data.

Thanks.

pokerking400
7 May 2008, 5:14 AM
Yep that removed all actions out of forms. cool.

Now i have to figure out a layout to adjust label length field lengh.

That form is good learning ..now i have to write dynamic form from scratch with configurable options like child tabs and child tabs with grid and non grid.

Thanks for the example.

pokerking400
7 May 2008, 6:06 AM
sometime it messes up layout if i try to edit fields in the popup form in different tabs.

Here is an example.
messed up
http://farm3.static.flickr.com/2304/2472986295_a1ea0ebffe_o.png

clean stuff
http://farm4.static.flickr.com/3176/2473821932_7df81cef2f_o.png
I have to create my own simple form and start building on it. That way it is better debug and understand.

AlxH
7 May 2008, 9:10 AM
Ok as i am browsing through your recordform example , i saw one thing. How do you remove the actions , qtip out of the form fields?.

Any easier way ?..

Thanks
alex

You can use the 'ignoreFields' property of recordform.

pokerking400
7 May 2008, 6:35 PM
i have to try that.

pokerking400
7 May 2008, 7:38 PM
Yes that works. But i have another problem in that how do you destroy the window without hiding? Simply because i open 100s of forms one by one , i can't hide as it may overlap and give funny layouts. i have to destroy the form every time.

pokerking400
7 May 2008, 7:41 PM
Is there a way to hide forms such that it does n't overlap ?

derf
11 May 2008, 4:01 AM
Hi, how do functional deleteRecord function? Thank

jsakalos
11 May 2008, 5:14 AM
Send delete request to server and delete the record from store on success response.

mask_hot
15 May 2008, 6:15 AM
Hi Saki,

would it be possible to have a field array like IgnoreFields but for ReadOnly fields.

I would like to display some fields even I won't edit them...

thx

jsakalos
15 May 2008, 6:40 AM
Hi Saki,

would it be possible to have a field array like IgnoreFields but for ReadOnly fields.

I would like to display some fields even I won't edit them...

thx
Take a look at it now, I've added readonlyFields and disabledFields config options but I haven't tested it thoroughly. Can you please do it and report any problems?

Thank you.

mask_hot
15 May 2008, 6:57 AM
Take a look at it now, I've added readonlyFields and disabledFields config options but I haven't tested it thoroughly. Can you please do it and report any problems?

Thank you.

At first sight it works well!

thanks a lot!

mask_hot
15 May 2008, 7:07 AM
I have a question not directly linked to this plugin :

I want to edit the row by right-clicking and then click the 'Edit' entry of the context menu displayed.

I did like this :

in my onRender function of my Extended Grid


Ext.MPDI.LogGrid.superclass.onRender.apply(this, arguments);
this.addListener('rowcontextmenu', function(grid, rowIndex, e){
e.stopEvent();

var record = grid.getStore().getAt(rowIndex);

var messageContextMenu = new Ext.menu.Menu({
//id: 'messageContextMenu',
items: [{
text: 'Edit',
handler: this.onEditLog(record, grid)
,scope: this
}]
});
messageContextMenu.showAt(e.getXY());
});



then I've got the following onEditLog function :



,onEditLog: function(record, grid){
console.log('Ext.MPDI.LogGrid.js - inside function onEditLog');
this.recordForm.show(record, grid.getView());
} // end of function onEditLog



he problem is that the RecordForm does not wait me to click to my 'Edit' contextmenu entry...
I right-click on a row, my contextmenu is displayed and the recordform too...


I guess there is an issue with my listener, isn't it?

jsakalos
15 May 2008, 7:18 AM
I'd say RowActions currently don't distinguish between right and left click. You can look in that direction...

mask_hot
15 May 2008, 7:24 AM
But I do not use RowActions :-?

jsakalos
15 May 2008, 7:25 AM
Then I don't know... :-/

neenhouse
28 May 2008, 8:12 AM
Saki-

Fantastic plugin. Thank you for all your hard work!

I'm having an issue that has been previously posted about, but I have not been able to resolve with that information. I have defined 3 of your handy EditorGridPanels like:


RecordForm.Grid1 = Ext.extend(Ext.grid.EditorGridPanel, {options});
RecordForm.Grid2 = Ext.extend(Ext.grid.EditorGridPanel, {options});
RecordForm.Grid3 = Ext.extend(Ext.grid.EditorGridPanel, {options});

Each with different column/store/record defintitions, and different update methods. Their xtypes are registered as well. I am calling these grids from a clickable nodes in a tree on the left side of a window panel. The click action loads the editorGrids into the main view like this:


listeners:{'click':function(node){
cp = Ext.getCmp('configPanel'); // the id name of the main panel
cp.body.mask('Loading Grid...', 'x-mask-loading')
var divPanel = {
id:'divPanel',
xtype:'panel',
layout:'fit',
border:false, bodyBorder:false,
stateful:false,
defaults:{border:false, bodyBorder:false, bodyStyle:'10px 10px 10px 10px;'},
items:{xtype:'grid1', id:'grid1'},
listeners:{
'remove':function(){
Ext.getCmp('grid1').destroy();
}
}
};
cp.body.unmask();
cp.remove(Ext.getCmp('divPanel'), true);
cp.add(divPanel);
cp.doLayout();
}}

But when I click on one editorGrid, then a 2nd one, and try to add a record, the form from the first editorGrid is loaded instead. I am unsure where I am going wrong! Can you help?

neenhouse
28 May 2008, 8:16 AM
Well- turns out a previous suggestion worked when I restarted my browser (sometimes firebug hangs on to javascript with a deathgrip, for me anyways...)


I had a small issue when destroying and recreating the recordform object.
It took me hours to find out what is causing it. The following seems to fix it:
Replace


var config = Ext.apply(this.defaultWindowConfig, this.windowConfig);

With


var config={};
Ext.apply(config,this.defaultWindowConfig);
Ext.apply(config, this.windowConfig);

in the show-function.

How is my code look anyway? Is the destroy method unneccessary you think? Is there a better way to update/replace a panels body?

neenhouse
28 May 2008, 8:23 AM
Sorry to bomb this thread so fast!

I have a remote combo box in my editor grid, when I use it in the editor grid then try to use it when adding a record, the combo box does not load the remote data even though I can see a ajax call and correct data being returned.

Here is how my combo is defined in the column model:


,columns:[{
header:'Status'
,id:'status'
,dataIndex:'status'
,width:100
,sortable:true
,editor:new Ext.form.TextField({
allowBlank:false
,decimalPrecision:0
,selectOnFocus:true
})
},{
header:'Type'
,dataIndex:'type'
,width:100
,sortable:true
,align:'right'
,editor:statusTypeCombo
,renderer:Ext.ux.renderer.Combo(statusTypeCombo)
}, this.rowActions]


statusTypeCombo is created from a function before this column model is defined:


var statusTypeCombo = genStatusTypeCombo();
...
function genStatusTypeCombo(){
return new Ext.form.ComboBox({fieldLabel:'Status',
store: new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: 'php/combo.php'
}),
reader: new Ext.data.JsonReader({
root: 'results',
id: 'display'
}, new Ext.data.Record.create([
{name: 'value', mapping:'value'},
{name: 'combo', mapping:'display'}
])),
baseParams: {view:'status', field:'status_type'}
//autoLoad:true
}),
id:'status_type_edit',
hiddenName:'status_type',
mode:'remote',
displayField:'combo',
valueField:'value',
triggerAction:'all',
allowBlank:false
});
}


and I have a defined combo renderer like this:


Ext.ns("Ext.ux.renderer");

Ext.ux.renderer.ComboRenderer = function(options) {
var value = options.value;
var combo = options.combo;

var returnValue = value;
var valueField = combo.valueField;

var idx = combo.store.findBy(function(record) {
if(record.get(valueField) == value) {
returnValue = record.get(combo.displayField);
return true;
}
});

// This is our application specific and might need to be removed for your apps
if(idx < 0 && value == 0) {
returnValue = '';
}

return returnValue;
};

Ext.ux.renderer.Combo = function(combo) {
return function(value, meta, record) {
return Ext.ux.renderer.ComboRenderer({value: value, meta: meta, record: record, combo: combo});
};
}


What could cause the combo not to load its data the 2nd time and up on?

jsakalos
28 May 2008, 9:42 AM
All these "2nd time" issues could be one of the following:

1) colliding ids - same ids for more than one component/element
2) not properly destroying a component so it stays in javascript's variable table
3) creating new component in a variable over an old one, e.g.
var combo = new ....
// later in code
combo = new ...

Be in your shoes I'd go strictly for lazy instantiating/rendering, keeping as much variables as possible as class variables and I'd provide custom onDestroy methods if needed.

neenhouse
28 May 2008, 10:14 AM
Thanks Saki- I'll put your comments into some serious practice and see where it leads me. One question- If I destroy a parent container, do its children also get destroyed along with it?

jsakalos
28 May 2008, 1:22 PM
If they have been added with add method or defined as items array, then yes.

neenhouse
28 May 2008, 1:28 PM
excellent, thanks

chiphi13
30 May 2008, 7:35 AM
Saki,

I am trying to configure your wonderful grid extension to be able to display the grid in one panel and the form in another panel instead of popping up in a window. I have tried to add the formCt property with a valid panel
this.recordForm = new Ext.ux.grid.RecordForm({
title:'Ext.ux.grid.RowRecord Example'
,iconCls:'icon-edit-record'
,columnCount:2
,ignoreFields:{compID:true}
,formCt:'mn-test-panel'
,readonlyFields:{action1:true}
,disabledFields:{qtip1:true}
,autoShow:true
The have the following in the ext.onReady



var p= new Ext.Panel({
renderTo:'test-grid', //This is a div on the page
id:'rfwin'
,title:'test'
,iconCls:'icon-grid'
,width:700
,height:400
,plain:true
,layout:'fit'
,closable:false
,border:false
,items:{xtype:'examplegrid1', id:'examplegrid1'}
,plugins:[new Ext.ux.IconMenu()]
});

It appears that if the renderTo for the above panel is Ext.getBody() then it works, but if I try to render it to another panel I get the following error:

this.el has no properties

Is this possible with your plugin to accomplish this? Any suggestions of what I may be doing wrong?

jsakalos
30 May 2008, 8:00 AM
I guess you were digging into the code deeply and that you discovered some unfinished fragments, right? I was also thinking along the same line of having a panel as the form container, I've made some tests but there was a couple of problems that I haven't resolved yet. Try to uncomment win2 part in the example to see how far I have got.

chiphi13
30 May 2008, 9:58 AM
It appears that the win2 example appears to be working except for the location of the window popping up, but when I try the following....I get the same error when it is trying to create the fields on the form

var rf = new Ext.ux.grid.RecordForm({
formCt:'east-form'
,autoShow:true
,autoHide:false
// ,showButtons:false
,ignoreFields:{compID:true}
,formConfig:{autoHeight:false,border:true, frame:false, margins:'10 10 10 10'}
});
var win2 = new Ext.Panel({
id:'rfwinbl',
renderTo:'test-grid'
,title:'test'
,layout:'border'
,width:800
,height:600
,border:false
,stateful:false
,plugins:[new Ext.ux.IconMenu({iconCls:'icon-grid'})]
,items:[{
region:'center'
,id:'center-grid'
,title:'Grid'
,stateful:false
,xtype:'examplegrid'
,autoScroll:true
,plugins:[rf]
},{
region:'north'
,id:'east-form'
,title:'Form'
,stateful:false
,height:300
//,split:false
,border:true
,frame:true
,collapsible:false
,layout:'fit'
}]
});

Any suggestions what could be causing the problem? It appears that it is bombing when trying to do the layout.

jsakalos
30 May 2008, 10:19 AM
Best suggestion would be: Wait until I finish it. I'll take a look at it this weekend so it's possible that I'll finish it, however, I do not promise anything.

trak
3 Jun 2008, 8:55 AM
Hi Saki,

First let me congratulate you for this great plugin! It's really awesome.:D

I had a little problem with the error messages when the msgTarget was 'under'. The width of the div would get miscalculated. Looking around i found that on the show method if you load the form before showing the window this issue gets resolved. I just wanted to tell you and to ask you if there's another way to fix this issue.

chiphi13
3 Jun 2008, 10:15 AM
Saki,

I know that you are extremely busy, but did you get a chance to look at the problem with the grid and window opening up in separate panels?

jsakalos
3 Jun 2008, 1:58 PM
Hi Saki,

First let me congratulate you for this great plugin! It's really awesome.:D

I had a little problem with the error messages when the msgTarget was 'under'. The width of the div would get miscalculated. Looking around i found that on the show method if you load the form before showing the window this issue gets resolved. I just wanted to tell you and to ask you if there's another way to fix this issue.
Do you have a patch and/or screenshot? Looks it could be a minor fix easily done...

jsakalos
3 Jun 2008, 1:59 PM
Saki,

I know that you are extremely busy, but did you get a chance to look at the problem with the grid and window opening up in separate panels?
Sorry, not yet, had another unexpected things to do. Will go into it soon...

mask_hot
6 Jun 2008, 1:15 AM
Hi all,

I use the recordform plugin and I had a problem using Remote Combobox and sending back data to save them.

First, I had the "Combo ValueField displayed instead DisplayField" issue.
For this, I used NeenHouse technic.

My next problem was the commiting of the changed or newed values.

I was using the saki example :


// handler to Save Button
,commitChanges:function() {
var records = this.store.getModifiedRecords();
if(!records.length) {
return;
}
var data = [];
Ext.each(records, function(r, i) {
var o = r.getChanges();
if(r.data.newRecord) {
o.newRecord = true;
}
o[this.idName] = r.get(this.idName);
data.push(o);
}, this);

var o = {
url:this.url
,method:'post'
,callback:this.requestCallback
,scope:this
,params:{
cmd:'saveData'
,objName:this.objName
,data:Ext.encode(data)
}
};
Ext.Ajax.request(o);
} // eo function commitChanges


The issue is calling the r.getChanges function. As my combo is for displaying labels of FK, I do not want to save them but only the Ids.

So here is my code (using hiddeName for the Editor, and I modified the process-request.php for the saveData function)

the combo renderer


Ext.ns("Ext.ux.renderer");

Ext.ux.renderer.ComboRenderer = function(options) {
var value = options.value;
var combo = options.combo;

var returnValue = value;
var valueField = combo.valueField;

var idx = combo.store.findBy(function(record) {
if(record.get(valueField) == value) {
returnValue = record.get(combo.displayField);
return true;
}
});

// This is our application specific and might need to be removed for your apps
if(idx < 0 && value == 0) {
returnValue = '';
}

return returnValue;
};

Ext.ux.renderer.Combo = function(combo){
return function(value, meta, record){
return Ext.ux.renderer.ComboRenderer({
value: value,
meta: meta,
record: record,
combo: combo
});
};
}


in the column model the combo editor


{
header: 'ID Pattern'
,dataIndex: 'id_pattern'
,width: 30
,hidden: true

},{
header: 'Pattern'
,dataIndex: 'pattern_name'
,sortable: true
,width: 100
,renderer:Ext.ux.renderer.Combo(this.patternCombo)
,editor:this.patternCombo
}


the combo


this.patternCombo = this.genPatternCombo();

,genPatternCombo:function (){
return new Ext.form.ComboBox({
store: new Ext.data.JsonStore({
id:'cbo_pattern'
,root:'rows'
,totalProperty:'total'
,url:this.url
,baseParams:{cmd: 'getData', objName:'dfs_pattern'}
,fields:[
{name: 'id_pattern', type: 'int'}
,{name: 'pattern_name', type: 'string'}
,{name: 'pattern_description', type: 'string'}
]
,sortInfo:{field: 'pattern_name', direction: "ASC"}
})
,hiddenName:'id_pattern'
,valueField: 'id_pattern',
displayField: 'pattern_name',
triggerAction: 'all',
mode: 'remote',
editable: false,
lazyRender: true,
forceSelection: true

});

}


the afterEdit event


,onAfterEdit:function(o){
if(o){
var grid=o.grid;
var record=o.record;
var cm=grid.getColumnModel();
var editor=cm.getCellEditor( o.column, o.row);
var v=editor.getValue();

if(editor.field.hiddenField){
var v=editor.field.hiddenField.value;
record.set(editor.field.hiddenName, v);
}
}
}


the commitChanges (called when saving)



,commitChanges:function() {

var records = this.store.getModifiedRecords();
if(!records.length) {
return;
}
var data = [];
var cm=this.getColumnModel();
Ext.each(records, function(r, i) {
//var o = r.getChanges();
var m = r.modified, o={};
for (var n in m) {
var column = cm.findColumnIndex(n);
var editor=cm.getCellEditor( column, 0);

if (editor) {
if (editor.field.hiddenField) {
// muste be the displayField of a combo
}
else {
if (m.hasOwnProperty(n)) {
o[n] = r.data[n];
}
}
}
else {
if (m.hasOwnProperty(n)) {
o[n] = r.data[n];
}
}

}
if(r.data.newRecord) {
o.newRecord = true;
}
o[this.idName] = r.get(this.idName);
data.push(o);

},this);

var o = {
url:this.url
,method:'post'
,callback:this.requestCallback
,scope:this
,params:{
cmd:'saveData'
,objName:this.objName
,data:Ext.encode(data)
}
};
Ext.Ajax.request(o);
} // eo function commitChanges
// }}}


ServerSide
the object defined (with a left join for display)


,"dfs_patternsystem"=>array(
"table"=>"dfs_patternsystem left join dfs_pattern on dfs_patternsystem.id_pattern=dfs_pattern.id_pattern "
."left join dfs_system on dfs_patternsystem.id_system=dfs_system.id_system"
,"idName"=>"id_patternsystem"
,"fields"=>array(
"id_patternsystem"
,"dfs_patternsystem.id_pattern"
,"pattern_name"
,"dfs_patternsystem.id_system"
,"system_name"
,"system_col"
,"system_specific"
)
)// }}}



The saveData


function saveData($osql) {
//logPDI('saveData');
global $objects;
$params = $objects[$_REQUEST["objName"]];
unset($params["fields"]);

$params["table"]= $_REQUEST["objName"];

$params["data"] = json_decode(stripslashes($_REQUEST["data"]));
$osql->output($osql->saveData($params));

} // eo function saveData

jsakalos
6 Jun 2008, 1:29 AM
Have you modified also plugin code istself? If so, let me know please.

mask_hot
6 Jun 2008, 1:46 AM
no at all. I worked only on your recordform.js, not on the recordform plugin itself.

I needed a fully EditorGridPanel working :D

I handled the deleteData too

The following listener is added to the grid Store


,listeners:{
remove:{scope:this, fn:this.deleteRecordAjx,buffer:200}
}


The onRowAction:


,onRowAction:function(grid, record, action, row, col) {
switch(action) {
case 'icon-minus':
this.deleteRecord(record);
break;

case 'icon-edit-record':
this.recordForm.show(record, grid.getView().getCell(row, col));
break;
}
} // eo onRowAction


and the functions


,deleteRecord:function(record) {
Ext.Msg.show({
title:'Delete record?'
,msg:'Do you really want to delete <b>' + record.get('pattern_name') + '</b><br/>There is no undo.'
,icon:Ext.Msg.QUESTION
,buttons:Ext.Msg.YESNO
,scope:this
,fn:function(response) {
if('yes' !== response) {
return;
}
this.store.remove(record);
// console.info('Deleting record');
}
});
} // eo function deleteRecord
// }}}
// {{{
,deleteRecordAjx:function(el, record, idx) {
var o = {
url:this.url
,method:'post'
,callback:this.requestCallback
,scope:this
,params:{
cmd:'deleteData'
,objName:this.objName
,data:Ext.encode(record.get(this.idName))
}
};
Ext.Ajax.request(o);
} // eo function deleteRecord



serverSide


function deleteData($osql) {
//logPDI('saveData');
global $objects;
$params = $objects[$_REQUEST["objName"]];
unset($params["fields"]);

$params["data"] = json_decode(stripslashes($_REQUEST["data"]));
$osql->output($osql->deleteData($params));

} // eo function saveData


and in the csql class :


public function deleteData($params) {
// params to vars
extract($params);
// return object
$o = new stdClass;
$o->success = false;


if(!isset($table) || !isset($idName) || !isset($data)) {
$o->error = "Table, idName or data not set.";
return $o;
}
$where = "where $idName = $data";

if(!$where) {
$o->error = "idName not found in data";
return $o;
}
$sql = "delete from $table " . $where;

try {
$this->odb->exec($sql);
$o->success = true;
}
catch(PDOException $e) {
$o->error = "$e";
}

$result = $o;

// handle error
if(true !== $result->success) {
$o->success = false;
$o->error = $result->error;
$this->odb->exec("rollback");
return $o;
}
else {
$o->success = true;
}

$this->odb->exec("commit");
return $o;
} // eo function deleteData

jsakalos
6 Jun 2008, 2:36 AM
OK, so no action needed on my end... ;)

mask_hot
6 Jun 2008, 5:22 AM
Saki,

now I would like to use a GroupingStore to group my lines by System for example.
I coded it but grouping is not rendered. Just sorts are applyed. Do you know where it could be coming from?

my store:


store: new Ext.data.GroupingStore({
reader : new Ext.data.JsonReader({
id:'id_patternsystem'
,root:'rows'
,totalProperty:'total'
,fields:[
{name: 'id_pattern', type: 'int'}
,{name: 'pattern_name', type: 'string'}
,{name: 'id_system', type: 'int'}
,{name: 'system_name', type: 'string'}
,{name: 'system_col', type: 'string'}
,{name: 'system_specific', type: 'int'}
,{name: 'id_patternsystem', type: 'int'}

]
})
,url:this.url
,remoteSort:true
,baseParams:{cmd: 'getData', objName:this.objName}
,view: new Ext.grid.GroupingView({
forceFit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})'
})
,groupField:'system_name'
,sortInfo:{field: 'pattern_name', direction: "ASC"}
//,groupOnSort:true

,listeners:{
remove:{scope:this, fn:this.deleteRecordAjx,buffer:200}
}
})
// }}}


my onRender


,onRender: function() {
console.log('Ext.DFS.GridPatternSystem.js - inside function onRender where this = ',this);
console.log('Ext.DFS.GridPatternSystem.js - inside function onRender where arguments = ',arguments);

// before parent code

/**
* Call parent method
* The PatternSystem of calling the parent (superclass) method is always the
* same. We call the parent to ensure we start with the capabilities
* of the parent class before we apply any additions or overrides.
*/
//MyExtendedClass.superclass.onRender.apply(this, arguments);
Ext.DFS.GridPatternSystem.superclass.onRender.apply(this, arguments);

this.store.load();
//this.store.groupBy('pattern_name');


} // end of function onRender

mask_hot
6 Jun 2008, 5:55 AM
:">:">

I was a "boulet" as we say in french... (we can translate it as "dumb")

I had put the view option in the store definition...

shame on me!

chiphi13
10 Jun 2008, 5:33 AM
Any updates on the issue with the form not being able to be rendered in a panel

jsakalos
11 Jun 2008, 12:34 AM
Not yet, currently I have no time to implement this new feature.

gthe
11 Jun 2008, 6:56 AM
Sorry for my English.

May be bug ?
When edit fields clear all fields and press Enter. Than Save.
And rezult:

jsakalos
11 Jun 2008, 11:50 AM
I have also succeeded to fool validation logic of the demo, otherwise I have no clue what is problem. Is it a bug in the plugin? Do you have a patch?

mask_hot
12 Jun 2008, 12:40 AM
OK, so no action needed on my end... ;)

Hello Saki, in fact there might be something to do in the plugin.

As I add a renderer to the combo, in the RecorForm the right value is not selected and when I select a value, the record form returns the valueField (or maybe I should recall my renderer?)

I think it's due to the form.loadRecord. How could I solve this?

jsakalos
12 Jun 2008, 2:25 PM
It could be because the store is not loaded. Form has copies of grid editor fields in fact but there is no combo store data copy into the newly created combo. I'll take a look at it, or you can.

ostghost
18 Jun 2008, 12:46 AM
situation

editable grid with approximately 16 columns - cca half is disabled and one is readOnly for rowActions plugin

bug

sometime - as ie decide - some of items are rendered too heigh

definition of such bad rendered item is

[CODE]
{
id: 'polozka',
header: "Polo

jsakalos
18 Jun 2008, 1:47 AM
1) That too high field is textarea? If so, check grow and growMin options.
2) Doctype? If so, remove it.

ostghost
18 Jun 2008, 4:37 AM
previous part of code was from column definition for grid - 'polozka' isn't editable nor editor isn't defined. so growMin you mentioned couldn

jsakalos
18 Jun 2008, 5:17 AM
Yeah, let us know then if it helped.

mask_hot
23 Jun 2008, 12:51 AM
It could be because the store is not loaded. Form has copies of grid editor fields in fact but there is no combo store data copy into the newly created combo. I'll take a look at it, or you can.

Hi Saki,

I think something should be done there :



// attempt to get config from column model
var c = this.findConfig(cm, f.name);
var o = {};

// use cm editor if we have one
if(c && c.editor && c.editor.field) {
Ext.apply(o, {
xtype:c.editor.field.getXType()
,fieldLabel:c.header
}, c.editor.field.initialConfig);
}

// use this.mapping to get field xtype
else {
Ext.apply(o, {
fieldLabel:(c && c.header ? c.header : f.name)
,xtype:this.mapping[f.type] || 'textfield'
});
if('date' === f.type && f.dateFormat) {
o.format = f.dateFormat;
}
}


but I don't know what!

Add as store? add a renderer?
Could you have a look on it?

Thanks.

jsakalos
23 Jun 2008, 2:03 AM
Generally it would be:


if(f.store) {
f.store.reload();
}

The only question is when to do it...

mask_hot
23 Jun 2008, 5:00 AM
Generally it would be:


if(f.store) {
f.store.reload();
}

The only question is when to do it...

Hi saki,

I add it like this :



// store record fields loop
fields.each(function(f, i) {
// ignore some fields
if(this.ignoreFields && this.ignoreFields[f.name]) {
return;
}


// attempt to get config from column model
var c = this.findConfig(cm, f.name);
var o = {};

// use cm editor if we have one
if(c && c.editor && c.editor.field) {
Ext.apply(o, {
xtype:c.editor.field.getXType()
,fieldLabel:c.header
}, c.editor.field.initialConfig);
}

// use this.mapping to get field xtype
else {
Ext.apply(o, {
fieldLabel:(c && c.header ? c.header : f.name)
,xtype:this.mapping[f.type] || 'textfield'
});
if('date' === f.type && f.dateFormat) {
o.format = f.dateFormat;
}
}



// read only and disabled fields
if(this.readonlyFields && true === this.readonlyFields[f.name]) {
o.readOnly = true;
}
if(this.disabledFields && true === this.disabledFields[f.name]) {
o.disabled = true;
}

// field has to have name
o.name = f.name;
o.tabIndex = tabIndex++;

// Mask_Hot Add for load correct value from a remote combo
if(o.store) {
o.store.reload();
}

// do not anchor date and time fields
if('datefield' === o.xtype || 'timefield' === o.xtype || 'datetime' === o.xtype) {
o.anchor = '';
}
if('textarea' === o.xtype) {
o.grow = false;
o.autoHeight = true;
}

// add field to a column on left-to-right top-to-bottom basis
this.form.items[0].items[colIndex++].items.push(o);
colIndex = colIndex === this.columnCount ? 0 : colIndex;

}, this);


So when I open the recordform, the combo is well initialized.
I have a new issue now :
When I change the value in the combon, my hiddenField associated to the combo is not updated and so the RecordForm.updateRecord does not send back to my grid the value...

In my grid I have a listener on AfterEdit event, I think I have to do something like that on my combos... but how?



,onAfterEdit:function(o){
if(o){
var grid=o.grid;
var record=o.record;
var cm=grid.getColumnModel();
var editor=cm.getCellEditor( o.column, o.row);
var v=editor.getValue();

if(editor.field.hiddenField){
var v=editor.field.hiddenField.value;
record.set(editor.field.hiddenName, v);
}
}
}

jsakalos
23 Jun 2008, 12:03 PM
Why would you need any hiddenName for cell editor? All you need is to update the underlying record.

Re code: I'm thinking that I'll do it as a config option (default true), sth like reloadComboStores:true so the user will be able to turn it off if he doesn't want it.

mask_hot
23 Jun 2008, 11:38 PM
Why would you need any hiddenName for cell editor? All you need is to update the underlying record.

Re code: I'm thinking that I'll do it as a config option (default true), sth like reloadComboStores:true so the user will be able to turn it off if he doesn't want it.

I have a table like this :

TBL_PATTERN_SYSTEM
id_pattern_system (pk)
id_pattern (fk)
id_system (fk)
...

I have a grid to update, insert, delete into this table, so I want to display the pattern_name and the system_name but post the ids to the server.
So I used remote combos with hiddenName (ids as hidden names).

If you have an easier working way to do it...

hsurya
28 Jun 2008, 5:42 PM
Hi Saki,
how to make it so that when I add a new record then it will go to the first row instead of the last row?

jsakalos
28 Jun 2008, 11:33 PM
The plugin doesn't add records itself. Your code should use store's method insert.

se7en.hu
30 Jun 2008, 7:28 PM
Ok so I like the idea of having the edit row action, but I would like to have an edit button in the tbar too, so I've put it there. I have copied the code from row actions into the tbars edit button listener, not sure why it wont work. Could someone please give me a hand.

Thanks



,listeners:{
click:{scope:this, buffer:200, fn:function(btn) {
this.recordForm.show(record, grid.getView().getCell(row, col));
}}
}

jsakalos
1 Jul 2008, 11:24 AM
Any Firebug error? You can also mimic the code of Add Record with recordform, with some modifications.

CINUE
2 Jul 2008, 12:21 PM
When i create a new RecordForm, I get error: 'Ext.ux.RecordForm is not a constructor'.

How can i solve it?????

jsakalos
2 Jul 2008, 12:22 PM
Include Ext.ux.grid.RecordForm.js file.

CINUE
2 Jul 2008, 1:18 PM
it was added, but in bad order. Thanks

descheret
8 Jul 2008, 10:48 PM
Hello,

I'm looking for a solution to export the records to excel (or just CSV). I found this Thread:

http://extjs.com/forum/showthread.php?p=152522#post152522

I know this example is only working without the paging bar, but anyway I tried to get it work with the RecordForm plugin and that wasn't very successfull (:|

Does anyone know a good solution how to export all records in the store direct to CSV or Excel just by click a button in the Grid? Any comment or idea would be very helpfull

thanky you
ronald

bluesapphire
9 Jul 2008, 1:14 AM
Hi!
I tried your nice example. I have faced following problem in your demo example.

1- Blank rows are added and nothing happens when I click on reset button. I think, blank rows should be removed from grid after reset button is clicked.

Iam using your example in IE7.

jsakalos
9 Jul 2008, 3:04 PM
Well, the example is aimed to the RecordForm usage.

jcmartinez
10 Jul 2008, 8:10 AM
Hi Saki,

We're developing a commercial application with Ext, and we'd like to use your GRID extension.

Can we have your permission to do this ?

regards

jsakalos
10 Jul 2008, 2:27 PM
The plugins is LGPL so as far as you can follow LGPL and your Ext licensing is OK, you can use it. If you need another arrangement, contact me via PM please.

hui2008
30 Jul 2008, 2:40 AM
Hi Saki,

I want to use Ext.form.HtmlEditor in the RecordForm.but can't do.

My code:


{
header:'Note'
,dataIndex:'note'
,width:75
,sortable:true
,editor:new Ext.form.HtmlEditor()
}
Look the first picture

But I need the stype like the two picture.

How could I do?

regards

jsakalos
30 Jul 2008, 7:59 AM
Set columnCount:1 Of course, then you will have also other fields one above the other.

hui2008
31 Jul 2008, 5:08 PM
Set columnCount:1 Of course, then you will have also other fields one above the other.

Thanks for your reply.

,columnCount:1 it looks like the default value is 1.

hui2008
31 Jul 2008, 5:39 PM
Thanks for your reply.

,columnCount:1 it looks like the default value is 1.


sorry for my reply, I find ",columnCount:2" in initComponent.

I want to do this: when I rowdblclick the grid, open a new tabpanel and show edit form panel like pic. I should what to do?

I don't understand the code
this.recordForm.show(record, grid.getView().getCell(row,col)); use in tabpanel.

jsakalos
1 Aug 2008, 2:47 AM
RecordForm is the simple record editing form. It doesn't put fields in tabs; it supports only columns. If you need anything else you need to code it.

hui2008
1 Aug 2008, 5:39 AM
RecordForm is the simple record editing form. It doesn't put fields in tabs; it supports only columns. If you need anything else you need to code it.

Thank you very much!

mask_hot
5 Aug 2008, 6:23 AM
Hi Saki,

is the RecordForm Ext 2.2 compliant?

jsakalos
5 Aug 2008, 9:43 AM
Hi Saki,

is the RecordForm Ext 2.2 compliant?
Do you have any troubles running it?

mask_hot
5 Aug 2008, 11:56 PM
I had some but after some tests I can say it's not reliable to 2.2 version.

jsakalos
6 Aug 2008, 12:02 AM
I had some but after some tests I can say it's not reliable to 2.2 version.
Can you be more specific? I cannot do any action based on this statement.

mask_hot
6 Aug 2008, 12:48 AM
Can you be more specific? I cannot do any action based on this statement.


I am checking if it is really linked to the recordform code or to my code :

I still have problems with my combo (with remote store) to send to the server the valuefield :

In my store I have this :


{name: 'id_update', type: 'int'},
{name: 'dt_update', type: 'date', dateFormat: 'Y-m-d H:i:s'},
{name: 'dt_done', type: 'date', dateFormat: 'Y-m-d H:i:s'},
{name: 'status', type: 'string'},
{name: 'task_name', type: 'string'},
{name: 'id_task', type: 'int'},
...


my columnModel:


new Ext.grid.CheckboxSelectionModel(),
{
header: "#"
,readOnly: true
,width: 50
,dataIndex: 'id_update'
,sortable: true
,hidden: false
,renderer: function(value, cell){
cell.css = "readonlycell";
return value;
}
},
{
header: "DATE UPD"
,width: 60
,dataIndex: 'dt_update'
,renderer: Ext.util.Format.dateRenderer('d/m/Y H:i:s')
,sortable: true
,editor: new Ext.form.DateField({ // rules about editing
maxLength: 60
})
},
{
header: "DATE DONE"
,width: 60
,dataIndex: 'dt_done'
,renderer: Ext.util.Format.dateRenderer('d/m/Y H:i:s')
,sortable: true
,editor: new Ext.form.DateField({ // rules about editing
maxLength: 60
})
},
{
header: "STATUS"
,width: 50
,dataIndex: 'status'
,sortable: true
,renderer: this.renderStatus.createDelegate(this)
,editor:new Ext.form.ComboBox({
store: new Ext.data.SimpleStore({
id: 0,
fields: ['stat'],
data: [['ERROR'], ['DONE'], ['ON HOLD'], ['TO DO'], ['PENDING'],['IGNORE']]
}),
displayField: 'stat',
valueField: 'stat',
triggerAction: 'all',
mode: 'local',
editable: false,
lazyRender: true,
forceSelection: true
})
},{
header: "ID TASK"
,width: 80
,dataIndex: 'id_task'
,readOnly: true
,hidden: true
,editor: new Ext.form.TextField({
maxLength: 30
})

},
{
header: "TASK"
,width: 200
,dataIndex: 'task_name'
,sortable: true
,editor: this.taskCombo
,renderer:Ext.ux.renderer.Combo(this.taskCombo)
,notupdatable:true

},...


my taskCombo is created like this:


,genTaskCombo:function (){
return new Ext.form.ComboBox({
store: new Ext.data.JsonStore({
id:'id_task'
,root:'results'
,totalProperty:'total'
,url:'controller.php'
,baseParams:{task: 'getListingTask'}
,fields:[
{name: 'id_task', type: 'int'},
{name: 'task_name', type: 'string'},
{name: 'description', type: 'string'},
{name: 'pattern', type: 'string'}

],
sortInfo:{field: 'task_name', direction: "DESC"}
})
,hiddenName:'id_task'
,displayField: 'task_name'
,valueField: 'id_task'
,triggerAction: 'all'
,mode: 'remote'
,editable: false
,lazyRender: true
,forceSelection: true

});

}



In the record form the field ID_TASK is well displayed but not filled.
My combo TASK_NAME select the right value but if I want to change it,
the record form put in my record :
task_name: the value (and not the display as I would like)
task_id : null

Do you have a best practice to handle this?

cnagel
6 Aug 2008, 7:11 AM
Hi Saki,

In the two weeks I've been attempting to get my head around Ext, your examples and thoughts have been by far the most helpful (and plentiful). So, thanks for everything you've done.

I downloaded the zip archive of RecordForm and I'm attempting now to integrate it with my existing sandbox application (which is basically a reconfiguring of examples/Desktop). This is my first, and I'm a bit uncertain as to where to put things, and what to remove, and what to alter.

How do I start using RecordForm in my app?

Step 1. I am guessing that to take everything that starts with "Ext.ux" from js/ and css/ and put it into my application's js/ and css/ is step 1. (Though I don't need searching - what's the minimum requirements?) Or is there a "ux" folder inside the Ext distro?

Step 2. Adding the glue in index.jsp (imports).

Step 3. Modify my grid declaration/init so it does things similarly to Example.Grid.js?

Step 4. there is no step 4?

I have read about 1/2 of the posts here and don't see much in the way of this kind of basic newbie guidance, and the FAQ is, I suppose, still in development. I'll keep reading, but just in case, I thought I'd post...

Thanks,
Chris

jsakalos
6 Aug 2008, 12:17 PM
@cnagel,

I think that the following links can help you a lot:

http://blog.extjs.eu/know-how/writing-a-big-application-in-ext/
http://blog.extjs.eu/category/patterns/file-patters/

jsakalos
6 Aug 2008, 12:18 PM
@mask_hot,

If your question is not directly related to recordform, post it please in a separate thread.

pravidya
6 Aug 2008, 1:40 PM
Saki,

Is there an example where if you select a row and edit(or double click) that an ajax call will be sent to the server for that row and to populate a tabpanel or a form. If not what is the change that I should do in your program to do the same? Thanks, prabat.

jsakalos
6 Aug 2008, 2:18 PM
I would use recordform as it is because you can have data in store but not displayed in the grid. Then you wouldn't need another request. The example is done such way.

If you insist on sending request you need to code it exactly as you said: send request to the server with id of clicked record and populate a form with received data.

mask_hot
6 Aug 2008, 11:35 PM
@mask_hot,

If your question is not directly related to recordform, post it please in a separate thread.


It is related and I found a solution overriding the afterUpdateRecord function.
Unfortunately it is not as clean as I would like : it is dependent on each grid and I have to give the combo field names :



,afterUpdateRecord:function(record)
{
var mod = record.modified;
//console.log('afterUpdateRecord', mod);
if (mod.task_name)
record.set('id_task', record.data['task_name']);


//console.log('afterUpdateRecord',record);
}

jsakalos
6 Aug 2008, 11:42 PM
The fact that combo displays value, not text, if it doesn't find the corresponding record in store is basic combo behavior and it has already been discussed many time elsewhere. I've already posted a chunk of code of my solution to this recently.

Rothariger
7 Aug 2008, 10:03 AM
Hi,


i must to make something, i must tu make a field readonly, but only when its edited... and i cant accomplish this...

can someone point me in the right direction?


thanks!