CFGRID, CFGRIDUPDATE en extra waarden

Ik gebruik CFGRID en CFGRIDUPDATE om waarden in een database in te voegen. Het probleem is dat elke record een extra veld moet krijgen dat zich niet in het raster bevindt. Is er een manier om dat extra veld in de geschiedenis op te slaan of moet ik een alternatief voor CFGRID maken?

Kortom, ik heb een aantal gebruikers die ik in een rooster invoeg. De pagina krijgt een categorie-ID. Ik wil dat alle gebruikers worden opgeslagen met die categorie-id.

Een ander ding dat zou werken, is als ik een lijst zou kunnen krijgen van alle primaire sleutels, inclusief die voor de zojuist gemaakte records, en deze allemaal met de categorie-id bij te werken. Maar het lijkt erop dat CFGRIDUPDATE geen informatie teruggeeft over de rijen die zijn gemaakt.

1

2 antwoord

- origineel antwoord verwijderd -

Op basis van je opmerking bij mijn oorspronkelijke antwoord, is er nu een impliciete aanname dat Category_ID een externe sleutel is, mogelijk op een join-tabel, die niet (om wat voor reden dan ook) kan worden opgenomen in de eerste displayquery - of dat je gewoon wilt om een ​​dynamische variabele op te nemen in het raster die wordt opgenomen tijdens inline invoegingen, zonder dat de gebruiker tussenkomt (dat wil zeggen fysiek verhindert dat ze zelf de Category_ID selecteren), maar dat deze nog steeds dynamisch is in enige hoedanigheid, zeg ... door gevoed te worden van een URL var).

Als dit klopt, denk ik dat de echte vraag dichter bij:

Kan een CFGRID meerdere tabellen/dynamische kolommen bijwerken via CFGRIDUPDATE?

Short answer: No

Lang antwoord: Ja, maar niet via CFGRIDUPDATE - eerder, via CFQUERY en een beetje meer werk aan de CFGRID, via CFC bindt en de CFAJAXPROXY.

Oplossing:

1) You'll need two files for this solution. File #1 is your Component which wraps the query functionality; we'll call it cfgrid.cfc



    

    
        
        
        
        

        

        
            SELECT Users.UserID, Users.FirstName, UserCategories.Category_ID
            FROM Users
        INNER JOIN UserCategories ON (Users.User_ID = UserCategories.UserID)

             
                order by #arguments.gridsortcolumn# #arguments.gridsortdirection#
                 
        

        
    

    
        
        

        
        INSERT INTO Users
        (
            fullname
        )
        VALUES
        (
            
        )
        

        
        SELECT Max(User_ID) as PKey
        FROM Users
        

        
        INSERT INTO UserCategories
        (
            User_ID,
            Category_ID
        )
        VALUES
        (
            
            
        )
        

        
    

    
        
        
         

    


Besteed aandacht aan deze belangrijke stukjes CFK:

a) getUsers() retourneert de huidige gebruikersgegevens samen met hun CategoryID. U moet deze query opnieuw schrijven om overeen te stemmen met uw schema, maar het belangrijkste is dat dit een gegevensbevolkingsquery is, dus alle gegevens die nodig zijn voor het maken van een gebruiker moeten ook aanwezig zijn om de gebruiker ook bij te werken. Dit veronderstelt ook dat je slechts 1 CategoryID per gebruiker hebt (die veel ontwikkelaars de-normaliseren door het CategoryID op de tabel Gebruikers te laten staan ​​- ik laat dat naar eigen goeddunken).

b) addNewUser() takes expects the form/grid submission to pass along the new name--as well as the category_id--but we know ahead of time we're not going to be asking that the Category_ID be filled out by the person entering the form/grid data--we'll do that programmatically. The end result is still the same, however--the query is going to need to know both values. For brevity, I've left off calls, but bear it in mind--you're about to execute three queries in succession, one of which (the 3rd) depends on dynamic data from the other (the 1st and 2nd)--so you'll need to keep concurrency in mind when you move forward with this type of design.

c) Negeer editUser() voorlopig - u zult het op een bepaald punt moeten invullen - het moet gewoon bestaan ​​om deze demonstratie te laten werken.

2) Het tweede bestand dat je nodig hebt is de voorkant - het raster zelf, we zullen het cfgrid.cfm noemen.

We gaan hier doorheen, van boven naar beneden, omdat het vrij groot is en elk stuk code uitleg nodig heeft:


De eerste regel van de sjabloon parametreert een URL-variabele, die we willen gebruiken om achter de schermen een toewijzing aan nieuwe gebruikers te programmeren. Gebruik uw eigen mechanisme om indien nodig een dynamische Category_ID te leveren.


Deze regel zorgt ervoor dat ColdFusion een javascript-object met de naam 'dataproxy' maakt en dit in een container plaatst die nodig is om toegang te krijgen tot de kernfuncties die bestaan ​​in de CFC waarnaar u verwijst, en in dit geval verwijst u naar 'cfgrid ', wat ons eerste hierboven genoemde bestand is (cfgrid.cfc). Daarom kunt u nu comfortabel verwachten dat u een javascript-object hebt met getUsers() en addNewUser() -methoden.

<html>
<head>
<script type="text/javascript" src="/CFIDE/scripts/ajax/ext/package/toolbar/toolbar.js"></script>

Hier begint u uw HTML-documenttags en voegt u een verwijzing naar een van de Ajax-bibliotheken in ColdFusion, het bestand toolbar.js, toe.

<script type="text/javascript">
var dataproxy = new dataproxy();

dataproxy.setCallbackHandler(handleResult);

function handleResult(response)
{
    alert(response);
}

Here, you create a local instance of the dataproxy object (remember above, from the call) and assign a callback handler, which points to another JavaScript function 'handleResult'. This is the process you employ when dealing with asynchronous communication--a fundamental part of working in Ajax.

function init()
{
    grid = ColdFusion.Grid.getGridObject("UserGrid");

    var gridHead = grid.getView().getHeaderPanel(true);

    var tbar = new Ext.Toolbar(gridHead);

    tbar.addButton({text:"Add User", handler:onAdd });
}

Deze init() -functie maakt de javascript-objecten die nodig zijn om de communicatie naar de cfgrid te sturen. U krijgt een verwijzing naar de cfgrid via ColdFusion.Grid.getGridObject en van daaruit krijgt u toegang tot de kop van het raster, waarmee u naar de werkbalk kunt richten en een knop "Gebruiker toevoegen" kunt toevoegen, die u vervolgens programmatisch besluit een nieuwe functie aan te roepen wanneer erop wordt geklikt ... wordt deze functie "onAdd" genoemd ...

function onAdd(button,event)
{
    ColdFusion.Window.show('addUserWin');
}

Niet verrassend, hier is die onAdd() functie, die een nieuw venster toont om een ​​gebruiker toe te voegen (dit is het venster dat het invoerveld voor de volledige naam van de gebruiker bevat).

Ten slotte heeft het nieuwe venster AddUserWin hierboven een eigen functie nodig om een ​​gebruiker toe te voegen, omdat we de Category_ID dynamisch moeten leveren - in tegenstelling tot de gebruiker deze te laten leveren. Dus addUser() doet precies dat:

function addUser()
{
    var f = document.frmUser;

    dataproxy.addNewUser(
        f.txtFullname.value,
        f.txtCategory_ID.value
    );

    ColdFusion.Window.hide('addUserWin');

    grid.refresh();
}
</script>
</head>

In addUser(), we refer to the <form> below by its name (frmUser), and call our JavaScript proxy object's addNewUser() method--which maps to the CFC. As expected, it'll need to know the values of the new user, so we'll pass it the value of txtFullname and txtCategory_ID. We finish by hiding the window and refreshing the grid.

Houd er rekening mee dat we nu asynchroon zijn, dus we hoeven geen resultaat te lezen en weer te geven. Het resultaat wordt geactiveerd via de hierboven toegewezen callback-handler in de handleResult() -methode.

Bouw nu de argumenten op die de populatie van de CFGRID voeden:









Hier Wij:   1. Noem het raster "UserGrid" (zoals we hierboven in JavaScript hierboven hebben vermeld),   2. Maak het render met behulp van html,   3. Laat het zijn gegevens binden wanneer de pagina laadt,   4. Bind die gegevens via cfgrid.cfc, waarbij u de methode getUsers() aanroept (en de huidige parameters van de cfgrid doorgeeft via de waarden voor pagina, paginagrootte, sorteerkolom en sorteerrichting),   5. Maak het bewerkbaar, en   6. Wijs een onChange-handler toe, voor het geval we ook willen dat de gebruikers kunnen worden bewerkt. Dit laatste deel (helaas) is noodzakelijk, dus ik kon het voor dit voorbeeld niet verwijderen.

Now, build the and :


    
        
        
        
    

Hier vullen we het rooster in met onze hierboven gespecificeerde argumenten, en je ziet dat we alleen het veld "FullName" in het raster weergeven, maar dat User_ID en Category_ID nog steeds aanwezig zijn, en een deel van de dataset; ze worden gewoon niet getoond aan de voorkant.

Last but not least, het venster dat wordt weergegeven wanneer een gebruiker op de knop "Nieuwe gebruiker toevoegen" klikt, die de interface biedt die we nodig hebben om gebruikersinvoer mogelijk te maken, terwijl tegelijkertijd (achter de schermen) wordt gecontroleerd wat Category_ID is dynamisch geleverd:


    <form name="frmUser">
<input type="hidden" name="txtCategory_ID" value="#URL.Category_ID#" />
    <table width="100%">
        <tr>
            <td>Fullname</td>
            <td><input type="text" name="txtFullname" value=""></td>
        </tr>
        <tr>
            <td colspan="2"><input type="button" value="Add User" onclick="javascript:addUser();"></td>
        </tr>
    </form>

This call to CFWINDOW provides the necessary "pop-up" to encapsulate the form. Note that the form name is frmUser, as we have referred to it above in code. Also, note that the name of the fields match (including their case) what are referred to in javascript. This form displays the Fullname field to the user to fill out, while the Category_ID stays hidden, but is still programmatically driven by you--via your URL parameter at the top of this code example. Finally, the button, when clicked, fires the addUser() method, which you'll recall is the one that talks to the JavaScript object--which in turn--talks to the CFC--and commits your data to the database.

Finally, just before you complete this template, don't forget to fire your init() JavaScript function!



</html>

Hope this helps.

Adapted from CRUD with cfgrid html format (Source: Anuj Gakhar)

3
toegevoegd
Levert dit de waarde voor nieuw geplaatste records door?
toegevoegd de auteur Jordan Reiter, de bron
Oh man, dit is teveel werk. Ik ga CFGRID gewoon helemaal omzeilen.
toegevoegd de auteur Jordan Reiter, de bron
Het zal niet - dus ik heb je een veel grondiger, robuuster werkend voorbeeld gegeven van de richting die je kunt gaan.
toegevoegd de auteur Shawn Holmes, de bron

Er is een andere manier. Het betreft het direct verwerken van de formuliervariabelen die door CFGRID zijn gepost. Hier is een voorbeeldcode:

form.cfm:


<input type="hidden" name="ParentID" value="#ParentID#">

    
    
    


<input type="submit" value="Save Records" />

dan in post.cfm


    
        
            
                
                    INSERT INTO Records (RecordName, RecordColor, RecordParent)
                    VALUES (
                        ,
                        ,
                        
                    )
                
            
            
                
                    UPDATE Records
                    SET
                        RecordName = ,
                        RecordColor = 
                    WHERE
                        RecordID=
                
            
            
                
                    DELETE
                    FROM Records
                    WHERE
                        RecordID=
                
            
        
    

1
toegevoegd
Ugh. Laat maar. Lijkt op redenen ColdFusion is helemaal niet consistent over welke recordshows in de GridData-variabele. Boe-geroep!
toegevoegd de auteur Jordan Reiter, de bron