FWIW, I'm working with Serge on this and one nice solution for cases like this is to use AJAX.
Basically what we ended up doing is using the wwEditable.js in place editing features on the columns that are 'updateable' and allowing inline saving plus a button on the row to 'Update'. You can just click on a cell and it becomes editable, plus tabbing to the next cell. The update button then allows actually sending the data from the current row's captured data.
You can either do an AJAX call at that time, or as we actually did - just fake a POST operation to mimic existing functionality with captured POST variables stuffed into hidden Vars to send to the server (you can use client side __doPostBack("this","Page_Method","Parm") to force a submit easily).
Lots of different options there really...
Hi Serge;
I have a number of pages that use a Repeater, like a spreadsheet for data entry.
The key would be in the save routine.
Here is some sample code I have taken from one such grid that saves information about stationery.
One key thing I do for existing records is add a hidden text box in the repeater that stores the primary key id for a record.
In some cases I use a temp table for the data and just append 5 or 10 blank records so that new records can be added.
This particular grid even has a file download control in each row so that images of each item can be downloaded as well.
Here is the relevant saving code:
FOR lnX = 1 TORECCOUNT([c_Stationary])
lcSort = this.rptStationery.UniqueID + "_txtSort_" + TRANSFORM(lnX)
lcType = this.rptStationery.UniqueID + "_cboType_" + TRANSFORM(lnX)
lcDesc = this.rptStationery.UniqueID + "_txtDesc_" + TRANSFORM(lnX)
lcPrice = this.rptStationery.UniqueID + "_txtPrice_" + TRANSFORM(lnX)
lcStationaryID = this.rptStationery.UniqueID + "_Stationaryid_" + TRANSFORM(lnX)
lcUpload = this.rptStationery.UniqueID + "_txtFileUpload_" + TRANSFORM(lnX)
lcFileName = []
lcJPGContent = Request.GetMultipartFile(lcUpload, @lcFilename)
lnSortOrder = VAL(Request.Form( lcSort))
lnType = VAL(Request.Form( lcType))
lcStationaryDesc = Request.Form(lcDesc)
lnStationaryPrice = VAL(Request.Form(lcPrice))
lnStationaryID = VAL(Request.Form(lcStationaryID))IF !EMPTY(lnStationaryID)
loRec.Load(lnStationaryID)
loRec.oData.SortOrder = lnSortOrder
IF !EMPTY(lnType)
loRec.oData.StationaryType = lnTypeENDIF
loRec.oData.StationaryDesc = lcStationaryDesc
loRec.oData.StationaryPrice = lnStationaryPriceIF !EMPTY(lcJPGContent)
lcFile = [/images/stationary/] + lcFileName
lcSource = [e:\inetpub\wwwroot\images\stationary\] + lcFileNameSTRTOFILE(lcJPGContent, lcSource )
loRec.oData.ImageFile = lcFileENDIFIF !loRec.Save()this.ErrorDisplay.Text = loRec.cErrorMsgthis.lError = .T.EXITENDIFENDIFENDFOR
Bob
I'm a math guy, who is growing more and more frustrated trying to get the web to behave as expected...
In essence I need an editable grid; behaviour more like a traditional spreadsheet. I tried working with grids but that didn't work out so well, so, I thought a repeater might be better. The look is closer to what I was hoping for, except, I can't save anything. Perhaps it's my complete lack of knowledge on VFP or perhaps WC, but, inevitably nothing works.
In the case of the repeater, here is what I have in the WC5 form
<code lang = "html">
<ww:wwWebPanel ID="WwWebPanel1" width="990px" Height="500px" ScrollBars="Auto" runat='server'>
<table class="blackborder">
<ww:wwWebRepeater ID="GeoParms" runat="server" DataSource="SocioGeoDemoGraphic_Parms">
<ItemTemplate>
<tr>
<td style="width: 50px;">
<ww:wwWebCheckBox runat="server" ID="chkSelected" />
<htmlcheckbox("chkSelected_" + transform(ID),"", SocioGeoDemoGraphic_Parms.Selected) >
<!-- <ww:wwWebCheckBox ID="WwWebCheckBox1" runat="server" ControlSource="SocioGeoDemoGraphic_Parms.Selected" /> -->
</td>
<td style="width: 500px;">
<%= SocioGeoDemoGraphic_Parms.Description%>
</td>
<td style="width: 100px;">
<ww:wwWebTextBox ID="WwWebLabel1" runat="server"
ControlSource= "SocioGeoDemoGraphic_Parms.value" >
</ww:wwWebTextBox>
</td>
</tr>
</ItemTemplate>
</ww:wwWebRepeater>
</table>
<ww:wwWebButton runat="server" ID="btnSave" Text="Save" Click="btnSave_Click" />
</ww:wwWebPanel>
As you can see I tried testing tying directly to the controlsource as well,but, in either case it simply fails to save.
In the VFP code, here is basically the guts;
<<CODE lang="vfp">>
Function OnLoad()
This.Page.EnableSessionState = .T.
This.oUser = Createobject("Client_Dataclass")
This.lUserName=Session.GetSessionVar("SGA_username")
This.lblTxtLoggedInAs.Text="Logged in as: " + This.lUserName
This.lbl_junk.preserveproperty("text")
If This.IsPostBack
Else
Select Recno() As Id, Attribute, operator, Descriptio As Description, 000.00 As Value, .F. As Selected ;
FROM Addbs(Config.cDataPath)+"ClientAccess\geodemoparms" Into Cursor SocioGeoDemoGraphic_Parms ReadWrite
Endif
Endfunc
* Onload
Function OnPreRender()
This.RenderGrid()
Endfunc
Function RenderGrid()
This.GEOPARMS.Datasource=[SocioGeoDemoGraphic_Parms]
This.GEOPARMS.DataSourceType = 1
This.databind()
Endfunc
Function btnSave_Click()
Local lnCount, lnX
*** Grab all the checkbox form variables
Dimension laVars[1,2]
lnCount = Request.aFormVars(@laVars,"chkSelected_")
WAIT WINDOW lncount
Select SocioGeoDemoGraphic_Parms
*** Because we're dealing with checkboxes which don't post values back if not set
*** we have to update all values to unselected first.
*** If you're running against a full table you'd have to filter this update to match
*** your subset
*Update SocioGeoDemoGraphic_Parms Set Selected = .F. && where customerId = lnCustId
For lnX = 1 To lnCount
*** Grab the id from the Field ID
lnId = Val(Strtran(laVars[lnX,1],"chkSelected_"))
Update SocioGeoDemoGraphic_Parms Where Id = lnId Set Selected = .T.
Endfor
Endfunc
I trapped the result of lncount; the value is 0. Obviously I screwed up since I am apperantly gathering nothing... I have also checked to edit the cursor and you can...
What the heck am I doing wrong????
Serge