Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom component exported fields #800

Closed
dzonerzy opened this issue Jan 10, 2023 · 5 comments
Closed

Custom component exported fields #800

dzonerzy opened this issue Jan 10, 2023 · 5 comments

Comments

@dzonerzy
Copy link

Hi i'm trying to create a modular login form which include a reset form and a sign-in form, below the code:

package components

import (
	"github.com/maxence-charriere/go-app/v9/pkg/app"
)

type FormKind int

const (
	Login FormKind = iota
	Register
	Recover
)

type LoginForm struct {
	app.Compo
	username string
	password string
	Typ      FormKind
}

func (l *LoginForm) setUsername(ctx app.Context, e app.Event) {
	l.username = ctx.JSSrc().Get("value").String()
}

func (l *LoginForm) setPassword(ctx app.Context, e app.Event) {
	l.password = ctx.JSSrc().Get("value").String()
}

func (l *LoginForm) btnClickAnimation(btn app.Value, e app.Event) {
	// simple click animation (ease-in-out)
	btn.Call("animate", []interface{}{
		map[string]interface{}{
			"transform": "scale(0.9)",
		},
		map[string]interface{}{
			"transform": "scale(1)",
		},
	}, map[string]interface{}{
		"duration": 200,
		"easing":   "ease-in-out",
	})
}

func (l *LoginForm) btnClick(ctx app.Context, e app.Event) {
	btn := e.Get("currentTarget").JSValue()
	ctx.Async(
		func() {
			l.btnClickAnimation(btn, e)
		},
	)
}

func (l *LoginForm) inputFocus(ctx app.Context, e app.Event) {
	// remove placeholder
	ctx.JSSrc().Set("placeholder", "")
}

func (l *LoginForm) inputBlur(ctx app.Context, e app.Event) {
	// if value is empty, set placeholder
	if ctx.JSSrc().Get("value").String() == "" {
		// capitalize first letter of placeholder
		placeholder := ctx.JSSrc().Get("name").String()
		placeholder = string(placeholder[0]-32) + placeholder[1:]
		ctx.JSSrc().Set("placeholder", placeholder)
	}
}

func (l *LoginForm) Render() app.UI {
	switch l.Typ {
	case Login:
		return app.Div().Class("fill").Body(
			app.Div().Class("login-form").Body(
				app.H4().Class("login-title").Text("Login"),
				app.Input().Type("text").Placeholder("Username").Name("username").Value(l.username).OnChange(l.setUsername).OnFocus(l.inputFocus).OnBlur(l.inputBlur),
				app.Input().Type("password").Placeholder("Password").Name("password").Value(l.password).OnChange(l.setPassword).OnFocus(l.inputFocus).OnBlur(l.inputBlur),
				app.Div().Class("login-button-container").Body(
					app.Button().Class("login-button").Text("Login").OnClick(l.btnClick),
					app.Button().Class("login-button").Text("Register").OnClick(l.btnClick),
				),
			),
		)
	case Register:
		return app.Div().Class("fill").Body(
			app.Div().Class("login-form").Body(
				app.H4().Class("login-title").Text("Register"),
				app.Input().Type("text").Placeholder("Username").Name("username").Value(l.username).OnChange(l.setUsername).OnFocus(l.inputFocus).OnBlur(l.inputBlur),
				app.Input().Type("password").Placeholder("Password").Name("password").Value(l.password).OnChange(l.setPassword).OnFocus(l.inputFocus).OnBlur(l.inputBlur),
				app.Input().Type("password").Placeholder("Confirm Password").Name("confirm-password").Value(l.password).OnChange(l.setPassword).OnFocus(l.inputFocus).OnBlur(l.inputBlur),
				app.Div().Class("login-button-container").Body(
					app.Button().Class("login-button").Text("Register").OnClick(l.btnClick),
					app.Button().Class("login-button").Text("Login").OnClick(l.btnClick),
				),
			),
		)
	case Recover:
		return app.Div().Class("fill").Body(
			app.Div().Class("login-form").Body(
				app.H4().Class("login-title").Text("Recover"),
				app.Input().Type("text").Placeholder("Username").Name("username").Value(l.username).OnChange(l.setUsername).OnFocus(l.inputFocus).OnBlur(l.inputBlur),
				app.Div().Class("login-button-container").Body(
					app.Button().Class("login-button").Text("Recover").OnClick(l.btnClick),
					app.Button().Class("login-button").Text("Login").OnClick(l.btnClick),
				),
			),
		)
	default:
		return app.Div().Class("fill").Body(
			app.Span().Text("Invalid form kind"),
		)
	}
}

func NewLoginForm(k FormKind) *LoginForm {
	return &LoginForm{
		Typ: k,
	}
}

For some reason when the component is rendered Typ field is always 0 even if it was initialized with a different value.

@oderwat
Copy link
Sponsor Contributor

oderwat commented Jan 10, 2023

I doubt that the problem is in this code. I would add print debug in NewLoginForm() and Render()to check on what Type is.

@dzonerzy
Copy link
Author

dzonerzy commented Jan 10, 2023

Already done , once in Render() the value is always 0

$ go run .
NewLoginForm => 2
Render LoginForm => 0

@oderwat
Copy link
Sponsor Contributor

oderwat commented Jan 10, 2023

I would try to an OnInit() or OnMount(), print debug the value and transfer it to an internal value tor whatever. But I still guess that you use that NewLoginForm() wrong (for example, as component of a route you add, which consumes a type and not a concrete value).

@dzonerzy
Copy link
Author

Yes i'm using this with app.Route("/", components.NewLoginForm(components.Recover)) so basically I can't use the same component to product different output this way

@oderwat
Copy link
Sponsor Contributor

oderwat commented Jan 10, 2023

Yes. This is why somebody made #562. I still do not know why @maxence-charriere never commented on that PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants