{"id":36525724,"url":"https://github.com/dv1x3r/w2go","last_synced_at":"2026-01-15T02:25:20.705Z","repository":{"id":332008028,"uuid":"974426570","full_name":"dv1x3r/w2go","owner":"dv1x3r","description":"go bindings for w2ui","archived":false,"fork":false,"pushed_at":"2025-12-06T13:29:26.000Z","size":31,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-12T05:30:22.341Z","etag":null,"topics":["bindings","crud","datagrid","datatable","dropdown","editing","form","go","golang","inline","library","ui","w2ui"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dv1x3r.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-28T19:00:46.000Z","updated_at":"2025-12-06T13:29:19.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dv1x3r/w2go","commit_stats":null,"previous_names":["dv1x3r/w2go"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/dv1x3r/w2go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dv1x3r%2Fw2go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dv1x3r%2Fw2go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dv1x3r%2Fw2go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dv1x3r%2Fw2go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dv1x3r","download_url":"https://codeload.github.com/dv1x3r/w2go/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dv1x3r%2Fw2go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28441299,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:55:22.719Z","status":"online","status_checked_at":"2026-01-15T02:00:08.019Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bindings","crud","datagrid","datatable","dropdown","editing","form","go","golang","inline","library","ui","w2ui"],"created_at":"2026-01-12T02:55:33.090Z","updated_at":"2026-01-15T02:25:20.697Z","avatar_url":"https://github.com/dv1x3r.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go bindings for w2ui\n\nThis package offers Go bindings for the [w2ui JavaScript UI Library](https://github.com/vitmalina/w2ui).\n\n- [Features](#features)\n- [Install](#install)\n- [Usage](#usage)\n  - [w2grid](#w2grid)\n  - [w2form](#w2form)\n  - [Dropdown](#dropdown)\n  - [SQL Builder](#sql-builder)\n  - [Utils](#utils)\n- [Example](#example)\n- [Changelog](#changelog)\n- [License](#license)\n\n## Features\n\n- `w2grid` support in `JSON` mode:\n  - **Pagination**, **sorting**, and **search**;\n  - **Inline editing** with typed updates;\n  - **Batch delete**;\n  - **Drag and Drop row reordering**;\n\n- `w2form` support in `JSON` mode:\n  - **Record retrieval**;\n  - **Form submission (create/update)**;\n\n- **Dropdowns**:\n  - Reusable across `w2grid` and `w2form` components;\n  - **Searchable** and **dynamic**;\n\n- **SQL Builder integration**:\n  - Translate `w2grid` data request into SQL with `go-sqlbuilder`;\n\n## Install\n\n```shell\ngo get github.com/dv1x3r/w2go\n```\n\n## Usage\n\n`w2go` types are JSON-serializable and work seamlessly with frameworks like `Echo` or `Fiber`, or standard `net/http`.\nThe following examples use Go's standard `net/http` library: `(w http.ResponseWriter, r *http.Request)`.\n\n### w2grid\n\n**Get Records**\n\n```go\nreq, err := w2.ParseGridDataRequest(r.URL.Query().Get(\"request\"))\nif err != nil {\n\tres := w2.NewErrorResponse(err.Error())\n\tres.Write(w, http.StatusBadRequest)\n\treturn\n}\n\n// Process the request...\n\nrecords := []Todo{{ID: 1, Name: \"Buy groceries\"}}\nres := w2.NewGridDataResponse(records, len(records))\nres.Write(w)\n```\n\n**Save Changes**\n\n```go\nreq, err := w2.ParseGridSaveRequest[Todo](r.Body)\nif err != nil {\n\tres := w2.NewErrorResponse(err.Error())\n\tres.Write(w, http.StatusBadRequest)\n\treturn\n}\n\n// Apply updates for req.Changes slice...\n\nres := w2.NewSuccessResponse()\nres.Write(w, http.StatusOK)\n```\n\n**Remove Records**\n\n```go\nreq, err := w2.ParseGridRemoveRequest(r.Body)\nif err != nil {\n\tres := w2.NewErrorResponse(err.Error())\n\tres.Write(w, http.StatusBadRequest)\n\treturn\n}\n\n// Apply updates for req.ID slice...\n\nres := w2.NewSuccessResponse()\nres.Write(w, http.StatusOK)\n```\n\n**Reorder Rows**\n\n```go\nreq, err := w2.ParseGridReorderRequest(r.Body)\nif err != nil {\n\tres := w2.NewErrorResponse(err.Error())\n\tres.Write(w, http.StatusBadRequest)\n\treturn\n}\n\n// Apply updates based on req.RecID, req.MoveBefore and req.Last...\n\nres := w2.NewSuccessResponse()\nres.Write(w, http.StatusOK)\n```\n\n### w2form\n\n**Get Record**\n\n```go\nreq, err := w2.ParseFormGetRequest(r.URL.Query().Get(\"request\"))\nif err != nil {\n\tres := w2.NewErrorResponse(err.Error())\n\tres.Write(w, http.StatusBadRequest)\n\treturn\n}\n\n// Process the request based on req.RecID...\n\nrecord := Todo{ID: 1, Name: \"Example\"}\nres := w2.NewFormGetResponse(record)\nres.Write(w)\n```\n\n**Save Record**\n\n```go\nreq, err := w2.ParseFormSaveRequest[Todo](r.Body)\nif err != nil {\n\tres := w2.NewErrorResponse(err.Error())\n\tres.Write(w, http.StatusBadRequest)\n\treturn\n}\n\n// Insert or update based on req.RecId...\n\nres := w2.NewFormSaveResponse(req.RecID)\nres.Write(w)\n```\n\n### Dropdown\n\n**Get Records**\n\n```go\nreq, err := w2.ParseDropdownRequest(r.URL.Query().Get(\"request\"))\nif err != nil {\n\tres := w2.NewErrorResponse(err.Error())\n\tres.Write(w, http.StatusBadRequest)\n\treturn\n}\n\n// Process the request based on req.Max and req.Search...\n\nrecords := []w2.DropdownValue{{ID: 1, Text: \"Open\"}, {ID: 2, Text: \"Closed\"}}\nres := w2.NewDropdownResponse(records)\nres.Write(w)\n```\n\n### SQL Builder\n\nUse `w2sqlbuilder` with `github.com/huandu/go-sqlbuilder` to apply filters, sorters, limits, and updates.\n\n**Apply Filters**\n\n```go\nreq, _ := w2.ParseGridDataRequest(r.URL.Query().Get(\"request\"))\n\n// Create a SelectBuilder\nsb := sqlbuilder.NewSelectBuilder()\nsb.Select(\"t.id\", \"t.name\")\nsb.From(\"todo as t\")\n\n// Define the w2ui field to database field name mapping.\nmapping := map[string]string{\n\t\"id\":   \"t.id\",\n\t\"name\": \"t.name\",\n}\n\n// Apply query filters based on the request and mapping.\nw2sqlbuilder.Where(sb, req, mapping)\n```\n\n**Apply Sorters**\n\n```go\nreq, _ := w2.ParseGridDataRequest(r.URL.Query().Get(\"request\"))\n\n// Create a SelectBuilder\nsb := sqlbuilder.NewSelectBuilder()\nsb.Select(\"t.id\", \"t.name\")\nsb.From(\"todo as t\")\n\n// Define the w2ui field to database field name mapping.\nmapping := map[string]string{\n\t\"id\":   \"t.id\",\n\t\"name\": \"t.name\",\n}\n\n// Apply query sorters based on the request and mapping.\nw2sqlbuilder.OrderBy(sb, req, mapping)\n```\n\n**Apply Limits**\n\n```go\nreq, _ := w2.ParseGridDataRequest(r.URL.Query().Get(\"request\"))\n\n// Create a SelectBuilder\nsb := sqlbuilder.NewSelectBuilder()\nsb.Select(\"t.id\", \"t.name\")\nsb.From(\"todo as t\")\n\n// Apply limit and offset based on the request.\nw2sqlbuilder.Limit(sb, req)\nw2sqlbuilder.Offset(sb, req)\n```\n\n**Apply Updates**\n\nUse this approach to apply **inline changes** to editable `w2grid` fields.\n\nTo track whether a field was included in the request, wrap it with the `w2.Editable` type:\n\n```go\ntype Todo struct {\n\tID   int    `json:\"id\"`\n\tName string `json:\"name\"`\n\tDescription w2.Editable[string] `json:\"description\"`\n\tQuantity    w2.Editable[int]    `json:\"quantity\"`\n}\n```\n\nUpdate functions:\n\n- `w2sqlbuilder.SetEditable`: updates the field only if a value **is provided**. Uses **null** if the value **is empty**.\n- `w2sqlbuilder.SetEditableWithDefault`: updates the field only if a value **is provided**. Uses the **zero value** if value **is empty**.\n\n```go\nreq, _ := w2.ParseGridSaveRequest[Todo](r.Body)\n\nfor _, change := range req.Changes {\n\tub := sqlbuilder.Update(\"todo\")\n\tub.Where(ub.EQ(\"id\", change.ID))\n\n\tw2sqlbuilder.SetEditable(ub, change.Description, \"description\")\n\tw2sqlbuilder.SetEditable(ub, change.Quantity, \"quantity\")\n\n\t// ...\n}\n```\n\n### Utils\n\n- `w2sort.ReorderArray`: reorders a slice of integers based on `w2grid` drag and drop.\n\n## Example\n\nRun a **full** CRUD demo using in-memory SQLite:\n\n```shell\ngo run example/main.go\n```\n\nStarts the server on `http://localhost:3000`\n\n## Changelog\n\n- v0.2.8 2025-12-06 - Update go-sqlbuilder to v1.38\n- v0.2.7 2025-10-19 - EditableDropdown support for clean w2form records\n- v0.2.6 2025-05-24 - Write methods now return errors\n- v0.2.5 2025-05-16 - First stable release\n\n## License\n\nLicensed under the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdv1x3r%2Fw2go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdv1x3r%2Fw2go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdv1x3r%2Fw2go/lists"}