advanced_functions

package
v3.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 21, 2024 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ATasteOfUsingVuetifyInGo = Doc(
	Markdown(`
[Vuetify](https://vuetifyjs.com/en/) is a really mature Vue components library for
[Material Design](https://material.io/design/). We have made the efforts to
integrate most all of it as a go package. You can use it with ease just like any
other go package.
`),
	utils.Anchor(H2(""), "Use container, toolbar, list, list item etc"),
	Markdown(`
This example is purely render, we didn't integrate any interaction (event func) to it.
`),
	ch.Code(generated.VuetifyListSample).Language("go"),
	utils.DemoWithSnippetLocation("Vuetify List", examples_vuetify.HelloVuetifyListPath, generated.VuetifyListSampleLocation),

	utils.Anchor(H2(""), "Use menu, card, list, etc"),
	Markdown(`
This example uses the menu popup, card, list component. and some interactions of clicking
buttons on the menu popup.
`),
	ch.Code(generated.VuetifyMenuSample).Language("go"),
	Markdown(`
~.VSlot("{ locals, form }").Init("{ myMenuShow: false }").FormInit(JSONString(fv))~ used to initialize the variables of ~web.Scope~.
~locals~ corresponds to the ~Init~ method and ~form~ corresponds to the ~FormInit~ method.

~.Init~ will initialize ~locals.myMenuShow~ to ~false~. So that you don't need to modify javascript code to do
the initialization. It's often useful to control dialog, popups. At this example,
We add it, So that the cancel button on the menu, could actually close the menu without
requesting server backend.

~toggleFavored~ event func did an partial update only to the favorite icon button. So that it won't close the
menu popup, but updated the button to toggle the favorite icon.
`),
	utils.DemoWithSnippetLocation("Vuetify Menu", examples_vuetify.HelloVuetifyMenuPath, generated.VuetifyMenuSampleLocation),
).Title("A Taste of using Vuetify in Go").
	Slug("vuetify-components/a-taste-of-using-vuetify-in-go")
View Source
var DetailPageForComplexObject = Doc(
	Markdown(`
By default, presets will only generate the listing page, editing page for a model,
It's for simple objects. But for a complicated object with a lots of relationships and connections,
and as the main data model of your system, It's better to have detail page for them. In there
You can add all kinds of operations conveniently.
`),
	ch.Code(generated.PresetsDetailPageTopNotesSample).Language("go"),
	utils.DemoWithSnippetLocation("Presets Detail Page Top Notes", examples.URLPathByFunc(examples_presets.PresetsDetailPageTopNotes)+"/customers", generated.PresetsDetailPageTopNotesSampleLocation),
	Markdown(`
- The name of detailing fields are just a place holder for decide ordering
- ~CellComponentFunc~ customize how the cell display
- ~vx.DataTable~ create a data table, Which the Listing page uses the same component
- ~LoadMoreAt~ will only show for example 2 rows of data, and you can click load more to display all
- ~vx.Card~ display a card with toolbar you can setup action buttons
- We reference the new form drawer that ~b.Model(&ActivityNote{})~ creates, but hide notes in the menu
`),
	utils.Anchor(H2(""), "Details Info components and actions"),
	Markdown(`
A ~vx.DetailInfo~ component is used for display main detail field of the model.
And you can add any actions to the detail page with ease:
`),
	ch.Code(generated.PresetsDetailPageDetailsSample).Language("go"),
	utils.DemoWithSnippetLocation("Presets Detail Page Details", examples.URLPathByFunc(examples_presets.
		PresetsDetailPageDetails)+"/customers", generated.PresetsDetailPageDetailsSampleLocation),
	Markdown(`
- The ~vx.Card~ Actions links to two event functions: Agree Terms, and Update Details
- Agree Terms show a drawer popup that edit the ~term_agreed_at~ field
- Update Details reuse the edit customer form
`),

	utils.Anchor(H2(""), "More Usage for Data Table"),
	Markdown(`
A ~vx.DataTable~ component is very featured rich, Here check out the row expandable example:
`),
	ch.Code(generated.PresetsDetailPageCardsSample).Language("go"),
	utils.DemoWithSnippetLocation("Presets Detail Page Credit Cards", examples_presets.PresetsDetailPageCardsPath+"/customers", generated.PresetsDetailPageCardsSampleLocation),
	Markdown(`
- ~RowExpandFunc~ config the content when data table row expand
- ~cc.Editing~ setup the fields when edit
- ~cc.Creating~ setup the fields when create
`),
).Title("Detailing").
	Slug("presets-guide/detail-page-for-complex-object")
View Source
var EventHandling = Doc(
	Markdown(`
We extend vue to support the following types of event handling, so you can simply use go code to implement some complex logic.

Using the ~~~Plaid()~~~ method will create an event handler that defaults to using the current ~~~vars~~~ and ~~~plaidForm~~~.
The default http request method is ~~~Post~~~, if you want to use the ~~~Get~~~ method, you can also use the ~~~Get()~~~ method directly to create an event handler
	`),

	utils.Anchor(H2(""), "URL"),
	Markdown(`Request a page.`),
	ch.Code(generated.EventHandlingURLSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=url", generated.EventHandlingURLSampleLocation),

	utils.Anchor(H2(""), "PushState"),
	Markdown(`Reqest a page and also changing the window location.`),
	ch.Code(generated.EventHandlingPushStateSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=pushstate", generated.EventHandlingPushStateSampleLocation),

	utils.Anchor(H2(""), "Reload"),
	Markdown(`Refresh page.`),
	ch.Code(generated.EventHandlingReloadSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=reload", generated.EventHandlingReloadSampleLocation),

	utils.Anchor(H2(""), "Query"),
	Markdown(`Request a page with a query.`),
	ch.Code(generated.EventHandlingQuerySample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=query", generated.EventHandlingQuerySampleLocation),

	utils.Anchor(H2(""), "MergeQuery"),
	Markdown(`Request a page with merging a query.`),
	ch.Code(generated.EventHandlingMergeQuerySample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=merge_query", generated.EventHandlingMergeQuerySampleLocation),

	utils.Anchor(H2(""), "ClearMergeQuery"),
	Markdown(`Request a page with clearing a query.`),
	ch.Code(generated.EventHandlingClearMergeQuerySample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=clear_merge_query", generated.EventHandlingClearMergeQuerySampleLocation),

	utils.Anchor(H2(""), "StringQuery"),
	Markdown(`Request a page with a query string.`),
	ch.Code(generated.EventHandlingStringQuerySample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=string_query", generated.EventHandlingStringQuerySampleLocation),

	utils.Anchor(H2(""), "Queries"),
	Markdown(`Request a page with url.Values.`),
	ch.Code(generated.EventHandlingQueriesSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=queries", generated.EventHandlingQueriesSampleLocation),

	utils.Anchor(H2(""), "PushStateURL"),
	Markdown(`Request a page with a url and also changing the window location.`),
	ch.Code(generated.EventHandlingQueriesSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=pushstateurl", generated.EventHandlingQueriesSampleLocation),

	utils.Anchor(H2(""), "Location"),
	Markdown(`Open a page with more options.`),
	ch.Code(generated.EventHandlingLocationSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=location", generated.EventHandlingLocationSampleLocation),

	utils.Anchor(H2(""), "FieldValue"),
	Markdown(`Fill in a value on form.`),
	ch.Code(generated.EventHandlingFieldValueSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=fieldvalue", generated.EventHandlingFieldValueSampleLocation),

	utils.Anchor(H2(""), "EventFunc"),
	Markdown(`Register an event func and call it when the event is triggered.`),
	ch.Code(generated.EventHandlingEventFuncSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=eventfunc", generated.EventHandlingEventFuncSampleLocation),

	utils.Anchor(H2(""), "Script"),
	Markdown(`Run a script code.`),
	ch.Code(generated.EventHandlingBeforeScriptSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=script", generated.EventHandlingBeforeScriptSampleLocation),

	utils.Anchor(H2(""), "Raw"),
	Markdown(`Directly call the js method`),
	ch.Code(generated.EventHandlingRawSample).Language("go"),
	utils.DemoWithSnippetLocation("Event Handling", examples_web.EventHandlingPagePath+"?api=raw", generated.EventHandlingRawSampleLocation),
).Title("Event Handling").Slug("basics/event-handling")
View Source
var LayoutFunctionAndPageInjector = Doc(
	Markdown("Read this code first, Guess what it does."),
	ch.Code(generated.DemoLayoutSample).Language("go"),
	Markdown(`
~ctx.Injector~ is for inject html into default layout's html head, and bottom of body.
html head normally for page title, keywords etc all kinds meta data, and css styles,
javascript libraries etc. You can see we put vue.js into head, but put main.js into the bottom of body.

Next part describe about these asset references:
`),
	ch.Code(generated.ComponentsPackSample).Language("go"),

	Markdown(`
~web.JSComponentsPack~ is the production version of QOR5 core javascript code.
Created by using [@vue/cli](https://cli.vuejs.org/guide/creating-a-project.html),
It does the basic functions like render server side returned html as vue templates.
Provide basic event functions that call to server, and manage push state
(change browser address urls before or after do ajax requests). do page partial refresh etc.

the javascript or css code are packed by using [embed](https://pkg.go.dev/embed).
`),
	ch.Code(generated.PackrSample).Language("go"),
	Markdown(`
And with ~web.PacksHandler~, You can merge multiple javascript or css assets together into one url.
So that browser only need to request them one time. and cache them. The cache is set to the start
time of the process. So next time the app restarts, it invalid the cache.
`),
	utils.Anchor(H2(""), "Summary"),
	Markdown(`
For a new project:

- Use [@vue/cli](https://cli.vuejs.org/guide/creating-a-project.html) to create an asset project that manage your javascript and css. and compile them for production use
- Use [embed](https://pkg.go.dev/embed) to pack them into Go code as ~ComponentPack~, which is a string
- Use ~PacksHandler~ to mount them as available http urls
- Write Layout function to reference them inside head, or bottom of body
`),
).Title("Layout Function and Page Injector").
	Slug("basics/layout-function-and-page-injector")
View Source
var LazyPortalsAndReload = Doc(
	Markdown(`
Use ~web.Portal().Loader(web.POST().EventFunc("menuItems")).Name("menuContent")~ to put a portal place holder inside a part of html, and it will load specified event func's response body inside the place holder after the main page is rendered in a separate AJAX request. Later in an event func, you could also use ~r.ReloadPortals = []string{"menuContent"}~ to reload the portal.
`),
	ch.Code(generated.LazyPortalsAndReloadSample).Language("go"),
	utils.DemoWithSnippetLocation("Lazy Portals", examples_vuetify.LazyPortalsAndReloadPath, generated.LazyPortalsAndReloadSampleLocation),
).Title("Lazy Portals").
	Slug("vuetify-components/lazy-portals")
View Source
var ManipulatePageURLInEventFunc = Doc(
	Markdown(`
Encode page state into query strings in url is useful. because user can paste the link to another person,
That can open the page to the exact state of the page being sent, Not the initial state of the page.

For example:
`),
	ch.Code(generated.MultiStatePageSample).Language("go"),
	utils.DemoWithSnippetLocation("Manipulate Page URL In Event Func", examples_web.MultiStatePagePath, generated.MultiStatePageSampleLocation),
	Markdown(`
This page have several state that encoded in the url:

- Page title have a default value, but if provided with a ~title~ query string, it will use that value
- The edit panel can be open, or closed based on having the ~panel~ query string or not

~web.Location(url.Values{"panel": []string{"1"}}).MergeQuery(true)~ means it will do a push state request to current page, with panel query string panel=1.
~MergeQuery~ means that it will not touch other query strings like ~title=1~ we mentioned above.

In ~update5~ event func, which is when you click the update button after open the panel, ~web.Location(url.Values{"panel": []string{""}}).MergeQuery(true)~ basically removes the query string panel=1, and won't touch any other query strings.

Don't have to be in event func to use push state query, can use a simple ~web.Bind~ to directly change the query string like:

~~~go
A().Text("change page title").Href("javascript:;").
	Attr("@click", web.POST().Queries(url.Values{"title": []string{"Hello"}}).Go()),
~~~

This don't have ~.MergeQuery(true)~, So it will replace the whole query string to only ~title=Hello~

`),
).Title("Manipulate Page URL in Event Func").
	Slug("basics/manipulate-page-url-in-event-func")
View Source
var NavigationDrawer = Doc(
	Markdown(`
Vuetify navigation drawer provide a popup layer that show on the side of the window.

Here is one example:
`),
	ch.Code(generated.VuetifyNavigationDrawerSample).Language("go"),
	utils.DemoWithSnippetLocation("Vuetify Navigation Drawer", examples_vuetify.VuetifyNavigationDrawerPath, generated.VuetifyNavigationDrawerSampleLocation),
).Title("Navigation Drawer").
	Slug("vuetify-components/navigation-drawer")
View Source
var PageFuncAndEventFunc = Doc(
	Markdown(`
~PageFunc~ is used to build a web page, ~EventFunc~ is called when user interact with the page, For example button or link clicks.
`),
	ch.Code(generated.PageFuncAndEventFuncDefinition).Language("go"),
	Markdown(`~web.Page(...)~ converts multiple ~EventFunc~s along with one ~PageFunc~ to a ~http.Handler~,
event func needs a name to be used by ~web.POST().EventFunc(name).Go()~ to attach to an html element that post http request to call the ~EventFunc~ when vue event like ~@click~ happens`),
	Markdown("Here is a hello world with more interactions. User click the button will reload the page with latest time"),
	ch.Code(generated.HelloWorldReloadSample).Language("go"),
	utils.DemoWithSnippetLocation("Page Func and Event Func", examples_web.HelloWorldReloadPath, generated.HelloWorldReloadSampleLocation),
	Markdown("Note that you have to mount the `web.Page(...)` instance to http.ServeMux with a path to be able to access the ~PageFunc~ in your browser, when mounting you can also wrap the ~PageFunc~ with middleware, which is ~func(in PageFunc) (out PageFunc)~ a func that take a page func and do some wrapping and return a new page func"),
	ch.Code(generated.HelloWorldReloadMuxSample1).Language("go"),
	Markdown("~wb.Page(...)~ convert any `PageFunc` into `http.Handler`, outside you can wrap any middleware that can use on Go standard `http.Handler`."),
	Markdown(`In case you don't know what is a http.Handler middleware,
It's a function that takes http.Handler as input, might also with other parameters,
And also return a new http.Handler,
[gziphandler](https://github.com/nytimes/gziphandler) is an example.`),

	Markdown(`But What the heck is ~demoLayout~ there?
Well it's a ~PageFunc~ middleware. That takes an ~PageFunc~ as input,
wrap it's ~PageResponse~ with layout html and return a new ~PageFunc~.
If you follow the code to write your own ~PageFunc~,
The button click might not work without this.
Since there is no layout to import needed javascript to make this work.
continue to next page to checkout how to add necessary javascript, css etc to make the demo work.`),
).Title("Page Func and Event Func").
	Slug("basics/page-func-and-event-func")
View Source
var PartialRefreshWithPortal = Doc(
	Markdown(`
As said before, The results of an ~web.EventFunc~ could be:

- Go to a new page
- Reload the whole current page
- Refresh part of the current page

We have covered two. Now let's demonstrate refresh part of the current page:
`),
	ch.Code(generated.PartialUpdateSample).Language("go"),
	utils.DemoWithSnippetLocation("Partial Update", examples_web.PartialUpdatePagePath, generated.PartialUpdateSampleLocation),
	Markdown(`
~web.Portal().Name("part1")~ Place a placeholder inside you page, and append ~web.PortalUpdate~ to ~er.UpdatePortals~ to update the portal with that name.
Multiple portal can be updated at the same time.
`),
	utils.Anchor(H2(""), "Load Portal in separate AJAX request"),
	Markdown(`
With ~web.Portal~, We can also load the portal with a separate AJAX request after page load.
It is useful for the type of the content is not that important to the page, But load them are
quite heavy. Like related products of a product detail page of a ECommerce site.
`),
	ch.Code(generated.PartialReloadSample).Language("go"),
	utils.DemoWithSnippetLocation("Partial Reload", examples_web.PartialReloadPagePath, generated.PartialReloadSampleLocation),
	Markdown(`
It is not only load the portal in separate AJAX request, Also you can reload it with ease ~er.ReloadPortals = []string{"related_products"}~ in an event func.

Under the hood, We use Vue's [Dynamic & Async Components](https://vuejs.org/v2/guide/components-dynamic-async.html), to load Go generated html (vue runtime templates)
from the server and mount those vue components into the page. It works the same way for reload the whole page, push state page switch, and refresh part of the current page.
`),
).Title("Partial Refresh with Portal").
	Slug("basics/partial-refresh-with-portal")
View Source
var ReloadPageWithAFlash = Doc(
	Markdown(`
The results of an ~web.EventFunc~ could be:

- Go to a new page
- Reload the whole current page
- Refresh part of the current page

Let's demonstrate reload the whole current page:
`),
	ch.Code(generated.ReloadWithFlashSample).Language("go"),
	utils.DemoWithSnippetLocation("Reload Page With a Flash", examples_web.ReloadWithFlashPath, generated.ReloadWithFlashSampleLocation),
	Markdown(`
~ctx.Flash~ Object is used to pass data between ~web.EventFunc~ to ~web.PageFunc~ just after the event func is executed. quite similar to [Rails's Flash](https://api.rubyonrails.org/classes/ActionDispatch/Flash.html).
Different is here you can pass in any complicated struct. as long as the page func to use that flash properly.

~er.Reload = true~ tells it will reload the whole page by running page func again, and with the result's body to replace the browser's html content. the event func and page func are executed in one AJAX request in the server.
`),
).Title("Reload Page with a Flash").
	Slug("basics/reload-page-with-a-flash")
View Source
var SummaryOfEventResponse = Doc(
	Markdown(`
The behaviour of ~web.EventFunc~ is controlled by it's return type ~web.EventResponse~
`),
	ch.Code(generated.EventResponseDefinition).Language("go"),
	Markdown(`
- ~PageTitle~ set the html head title, It not only set when render html page directly which is
  request the url directly from the browser. Also use javascript to set the page title when you do
  push state AJAX request to load the page
- ~Body~ is the set to ~web.PageResponse~'s body when ~Reload = true~ is set, Or set to the partial
  html component when using ~ReloadPortals~ together with ~web.Portal().EventFunc("related")~
- ~Reload~ is to reload the ~web.PageFunc~, before reload, you can set ~ctx.Flash~ object to let the
  event func render the page differently (flash message, validation errors, etc)
- ~Location~ is to change the browser url with push state, and AJAX load the page of that url
- ~RedirectURL~ is to change the browser url without AJAX, reload the whole page html includes it's
  head script, css assets
- ~ReloadPortals~ is for reload the portal that uses ~web.Portal().EventFunc("related")~
- ~UpdatePortals~ update the portal specified by the name ~web.Portal().Name("hello")~, ~pu.AfterLoaded~
  set the javascript function that execute after the portal is updated, for example:
  ~VarsScript: "setTimeout(function(){ comp.vars.drawer2 = true }, 100)"~
- ~Data~ is for any AJAX call that want pure JSON, you can set ~er.Data = myobj~ to any object that
  will marshals to JSON, and on the client side use javascript to utilize them
`),
).Title("Summary of Event Response").
	Slug("basics/summary-of-event-response")
View Source
var SwitchPagesWithPushState = Doc(
	Markdown(`Ways that page transition (between ~web.PageFunc~) in QOR5 web app:

- Use a traditional link to a new page by url
- Use a push state link to a new page that only change the current page body to new page body and browser url
- Use a button etc to trigger post to an ~web.EventFunc~ that do some logic, then go to a new page

Inside ~web.EventFunc~, two ways go to a new page:

- Use [push state](https://developer.mozilla.org/en-US/docs/Web/API/History_API#Examples) to only reload the body of the new page, This won't reload javascript and css assets.
- Use redirect url to reload the whole new page, This will reload target new page's javascript and css assets.

This example demonstrated the above:
`),
	ch.Code(generated.PageTransitionSample).Language("go"),
	utils.DemoWithSnippetLocation("Switch Pages With Push State", examples_web.Page1Path, generated.PageTransitionSampleLocation),
	Markdown(`
When running the above demo, If you check Chrome Developer Tools about Network requests,
You will see that the Location link and the Button is actually doing an AJAX request to the other page.

Look like this:
~~~
POST /samples/page_2?__execute_event__=__reload__ HTTP/1.1
~~~

The result is an JSON object with page's html inside.
~__reload__~ is another ~web.EventFunc~ that is the same as ~doAction2~,
But it is default added to every ~web.PageFunc~. So that the web page can
both respond to normal HTTP request from Browser, Search Engine, Or from
other pages in the same web app that can do push state link.
`),
	utils.Anchor(H2(""), "Summary"),
	Markdown(`
- Write once with PageFunc, you get both normal html page render, and AJAX JSON page render
- EventFunc is always called with AJAX request, and you can return to a different page, or rerender the current page,
- EventFunc is not wrapped with layout function.
- EventFunc is used to do data operations, triggered by page's html element. and it's result can be:
	1. Go to a new page
	2. Reload the whole current page
	3. Update partial of the current page

Next we will talk about how to reload the whole current page, and update partial of the current page.
`),
).Title("Switch Pages with Push State").
	Slug("basics/switch-pages-with-push-state")
View Source
var TheGoHTMLBuilder = Doc(
	Markdown(`
Like at the beginning we said, That we don't use interpreted template language (eg go html/template)
to generate html page. We think they are:

- error prone without static type enforcing
- hard to refactor
- difficult to abstract out to component
- yet another tedious syntax to learn
- not flexible to use helper functions

We like to use standard Go code. the library [htmlgo](https://github.com/theplant/htmlgo) is just for that.

Although Go can't do flexible builder syntax like [Kotlin](https://kotlinlang.org/docs/reference/type-safe-builders.html) does,
But it can also do quite well.

Consider the following code:
`),
	ch.Code(generated.TypeSafeBuilderSample).Language("go"),
	Markdown(`
It's basically assembled what Kotlin can do, Also is legitimate Go code.
`),
	utils.DemoWithSnippetLocation("The Go HTML Builder", examples_web.TypeSafeBuilderSamplePath, generated.TypeSafeBuilderSampleLocation),
).Title("The Go HTML builder").
	Slug("advanced-functions/the-go-html-builder")
View Source
var WebScope = Doc(
	Markdown(`

## Initialize form and locals vue variables

Since we we don't write vue javascript code, 
It's not easy to add reactive object to that can be used in vue templates. which is returned from the server. 
reactive object are used to trigger view updates,
We pre-set the ~locals~ and ~form~ object as a reactive object, 
and then we can initialize various types of values and slot it into ~locals~. 
And the valid scopes of these values are all inside web.Scope().

For example:
`),
	ch.Code(generated.WebScopeUseLocalsSample1).Language("go"),
	utils.DemoWithSnippetLocation("Web Scope Use Locals", examples_web.WebScopeUseLocalsPath, generated.WebScopeUseLocalsSample1Location),
	Markdown(`
Use ~web.Scope()~ to determine the effective scope of the variable, then use ~.Init(...).VSlot("{ locals }")~ to initialize the variable and slot it into the ~locals~ object.

In ~VBtn("")~, you can use the ~click~ event to change the variable value in ~locals~ to achieve the effect that the page changes with the click.

In ~VBtn("Test Can Not Change Other Scope")~, values in ~locals~ will not change with the click, because the button is not in ~web.Scope()~.

Video Tutorial (<https://www.youtube.com/watch?v=UPuBvVRhUr0>)
`),

	Markdown(`

## Use form

The main use of ~form~ is to submit one form which is inside another form, 
and the two forms are completely independent forms.

In the following example, each color represents a completely separate form. The ~Material Form~ contains the ~Raw Material Form~. You can submit the ~Raw Material Form~ to the server first. After receiving it, server will save the ~Raw Material data~ and return the ~ID~.
In this way, you can submit ~Raw Material ID~ directly in the ~Material Form~.

For example:
`),
	ch.Code(generated.WebScopeUsePlaidFormSample1).Language("go"),
	utils.DemoWithSnippetLocation("Web Scope Use PlaidForm", examples_web.WebScopeUseFormPath, generated.WebScopeUsePlaidFormSample1Location),
	Markdown(`
Use ~web.Scope().VSlot("{ form }")~ to determine the scope of a form.
`),
).Title("web.Scope").
	Slug("basics/web-scope")

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL