vitmalina / w2ui

UI widgets for modern apps. Data table, forms, toolbars, sidebar, tabs, tooltips, popups. All under 120kb (gzipped).
http://w2ui.com
MIT License
2.67k stars 727 forks source link

Unable to populate data into a form when the form is based on a URL? #2546

Closed carlbeechvuw closed 3 months ago

carlbeechvuw commented 4 months ago

Short description W2UI version 2 - forms, using URL method to get information from a database - I can see data is queried (from the URL/php code that supplies the JSON data), however, no information is displayed on screen. Its possible this is my lack of understanding of necessary code.

What is current behavior I have a form with a URL entry which points to a PHP backend which queries a database and supplies JSON data. I can see from logs that this is working, and sending data. On the form I have a button which sets a recid, and no matter what function I use, I can see the form flash as it refreshes, however, the data is not presented on screen.

What is desired behavior When I set a recid within the form item, it should populate the fields - and when I change something, it should be able to send the updates back to the original URL

Link to jsfidle/codepan with sample code https://jsfiddle.net/carlbeech/pk0vaw96/9/

Steps to reproduce or sample Sample is given in the jsfiddle.

carlbeechvuw commented 3 months ago

I've run through a debugging session with visual studio code, single stepping through, and I can confirm that the data has definitely been retrieved, however, its just not being displayed...?

Digging deeper, into the refresh() function I can see (line 21706):

        // set value to HTML input field
        this.setFieldValue(field.field, this.getValue(field.name))

Not sure why you'd want to set the field value to the HTML input field? - it appears that the getValue function looks at the original record, and returns the value of the record, not the value that has been retrieved from the remote data source?

'This.record[field]' holds the new incoming value from the source data - however, the 'return val' is executed, which appears to always return undefined - so the value is never set in the 'setFieldValue' function.

getValue(field, original) {
    if (this.nestedFields) {
        let val = undefined
        try { // need this to make sure no error in fields
            let rec = original === true ? this.original : this.record
            val = String(field).split('.').reduce((rec, i) => { return rec[i] }, rec)
        } catch (event) {
        }
        return val
    } else {
        return this.record[field]
    }
}

Looking at the docs I see: reload - reload([callBack]) Reloads record data and refreshes the form. request - request([postData], [callBack]) Reloads record data and refreshes the form.

Both of these are the same description - is this correct?

As mentioned, I'm assuming that either reload() or request() will perform a query of the database and put the values into the field onto the screen - however, there's always the possibility I should be using a different function, and the above is operating normally?

Hope that helps?

carlbeechvuw commented 3 months ago

Fixed it myself - however, not without 'consequences' -

Changed the routine:

getValue(field, original) {
    //if (this.nestedFields) {
    //    let val = undefined
    //    try { // need this to make sure no error in fields
    //        let rec = original === true ? this.original : this.record
    //        val = String(field).split('.').reduce((rec, i) => { return rec[i] }, rec)
    //    } catch (event) {
    //    }
    //    return val
    //} else {
        // console.log(this.record[field])
        // return this.record[field]

        if (this.record.records != null)
            {
            console.log(this.record.records[0][field])
            return this.record.records[0][field]
            }
    //}
}

The main problem was that 'this.record[field]' appeared to be returning undefined all the time - so changing this to 'this.record.records[0][field]' appears to send back the values.

In the version of the code I've got now, I don't copy field values from a grid into the form - in the grid, I send across the key field (character or number) into the recid, and because I've got the URL set, it requeries the database directly... its a little less efficient (from the point of view of increased traffic), however, it does mean the grid where I pick the record from can be simpler (i.e. only the fields for the grid, not all the fields to drive the form...

Hope that helps...?

Cheers Carl.

vitmalina commented 3 months ago

I looked at your issue and I think the issue is because you return wrong data structure from the server. It returns

{ records: [{ fields }], total 1 }

but is should return just

{fields}

Here is jsFiddle that works https://jsfiddle.net/brv0mo9s/1/

carlbeechvuw commented 3 months ago

Many thanks for your example - I've now got my code working correctly with your library (without my mods :-) )

Cheers Carl.