Git Product home page Git Product logo

elm-form's Introduction

Elm Form

HTML live form builders and validation for Elm. Build Status

elm package install etaque/elm-form

For when the classical "a message per field" doesn't work well for you, at the price of losing some type safety (field names are made of strings, see #97).

Support

We have a dedicated channel in Elm slack, join us in #elm-form for any question, support or issues coordination.

Features

  • Validation API similar to Json.Decode with the standard map, andThen, etc: you either get the desired output value or all field errors
  • HTML inputs helpers with pre-wired handlers for live validation
  • Suite of basic validations, with a way to add your own
  • Unlimited fields, see andMap function (as in Json.Extra)
  • Nested fields (foo.bar.baz) and lists (todos.1.checked) enabling rich form build

See complete example here (source code).

Basic usage

See the example validation test suite and test helper function docs for how to test-drive validations.

module Main exposing (Foo, Model, Msg(..), app, formView, init, update, validate, view)

import Browser
import Form exposing (Form)
import Form.Input as Input
import Form.Validate as Validate exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)



-- your expected form output


type alias Foo =
    { bar : String
    , baz : Bool
    }



-- Add form to your model and msgs


type alias Model =
    { form : Form () Foo }


type Msg
    = NoOp
    | FormMsg Form.Msg



-- Setup form validation


init : Model
init =
    { form = Form.initial [] validate }


validate : Validation () Foo
validate =
    succeed Foo
        |> andMap (field "bar" email)
        |> andMap (field "baz" bool)



-- Forward form msgs to Form.update


update : Msg -> Model -> Model
update msg ({ form } as model) =
    case msg of
        NoOp ->
            model

        FormMsg formMsg ->
            { model | form = Form.update validate formMsg form }



-- Render form with Input helpers


view : Model -> Html Msg
view { form } =
    Html.map FormMsg (formView form)


formView : Form () Foo -> Html Form.Msg
formView form =
    let
        -- error presenter
        errorFor field =
            case field.liveError of
                Just error ->
                    -- replace toString with your own translations
                    div [ class "error" ] [ text (Debug.toString error) ]

                Nothing ->
                    text ""

        -- fields states
        bar =
            Form.getFieldAsString "bar" form

        baz =
            Form.getFieldAsBool "baz" form
    in
    div []
        [ label [] [ text "Bar" ]
        , Input.textInput bar []
        , errorFor bar
        , label []
            [ Input.checkboxInput baz []
            , text "Baz"
            ]
        , errorFor baz
        , button
            [ onClick Form.Submit ]
            [ text "Submit" ]
        ]


app =
    Browser.sandbox
        { init = init
        , update = update
        , view = view
        }

Advanced usage

Custom inputs

  • For rendering, Form.getFieldAsString/Bool provides a FieldState record with all required fields (see package doc).

  • For event handling, see all field related messages in Form.Msg type.

Overall, having a look at current helpers source code should give you a good idea of the thing.

Incremental validation

Similar to what Json.Extra provides you can also use Form.andMap

Form.succeed Player
    |> andMap (field "email" (string |> andThen email))
    |> andMap (field "power" int)

Nested records

  • Validation:
validation =
    map2 Player
        (field "email" (string |> andThen email))
        (field "power" (int |> andThen (minInt 0)))
        (field "options"
            (map2 Options
                (field "foo" string)
                (field "bar" string)
            )
        )
  • View:
Input.textInput (Form.getFieldAsString "options.foo" form) []

Dynamic lists

-- model
type alias TodoList =
    { title : String
    , items : List String
    }

-- validation
validation : Validation () Issue
validation =
    map2 TodoList
        (field "title" string)
        (field "items" (list string))

-- view
formView : Form () Issue -> Html Form.Msg
formView form =
    div
        [ class "todo-list" ]
        [ Input.textInput
            (Form.getFieldAsString "title" form)
            [ placeholder "Title" ]
        , div [ class "items" ] <|
            List.map
                (itemView form)
                (Form.getListIndexes "items" form)
        , button
            [ class "add"
            , onClick (Form.Append "items")
            ]
            [ text "Add" ]
        ]

itemView : Form () Issue -> Int -> Html Form.Msg
itemView form i =
    div
        [ class "item" ]
        [ Input.textInput
            (Form.getFieldAsString ("items." ++ (String.fromInt i)) form)
            []
        , a
            [ class "remove"
            , onClick (Form.RemoveItem "items" i)
            ]
            [ text "Remove" ]
        ]

Initial values and reset

  • At form initialization:
import Form.Field as Field


initialFields : List ( String, Field )
initialFields =
    [ ( "power", Field.string "10" )
    , ( "options"
      , Field.group
            [ ( "foo", Field.string "blah" )
            , ( "bar", Field.string "meh" )
            ]
      )
    ]


initialForm : Form
initialForm =
    Form.initial initialFields validation

See Form.Field type for more options.

  • On demand:
button [ onClick (Form.Reset initialFields) ] [ text "Reset" ]

Note: To have programmatic control over any input[type=text]/textarea value, like reseting or changing the value, you must set the value attribute with Maybe.withDefault "" state.value, as seen here. There's a downside of doing this: if the user types too fast, the caret can go crazy.

More info: evancz/elm-html#81 (comment)

Custom errors

type LocalError = Fatal | NotSoBad

validation : Validation LocalError Foo
validation =
    (field "foo" (string |> customError Fatal))

-- creates `Form.Error.CustomError Fatal`

Async validation

This package doesn't provide anything special for async validation, but doesn't prevent you to do that either. As field values are accessible from update with Form.getStringAt/getBoolAt, you can process them as you need, trigger effects like an HTTP request, and then add any errors to the view by yourself.

Another way would be to enable dynamic validation reload, to make it dependant of an effect, as it's part of the form state. Please ping me if this feature would be useful to you.

elm-form's People

Contributors

amitaibu avatar declension avatar dillonkearns avatar dimbleby avatar etaque avatar janjelinek avatar jhrcek avatar knuton avatar matsrietdijk avatar pablohirafuji avatar paparga avatar simonh1000 avatar soenkehahn avatar stephenreddek avatar thomasweiser avatar thsoft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

elm-form's Issues

Support: Validate dynamic list of fields

We are building a rather complex form. We have a couple of fields that we will duplicate depending on something set somewhere else. For example, we have a text field to select a number of people and then, we add a "name" and "last name" field for each person.

I have something like this:

type alias Model =
  { form : Form () Items }

type alias Items =
  { field : String
  , secondField : String
  -- Other fields
  , people : List Person
  }

type alias Person =
  { name : String
  , lastName : String
  }

But is in the validation when I'm running out of ideas. I don't know how to handle the List part on my validation. I guess I need to create a custom validation function, but following the current example I was not able to find a way to do it: https://github.com/etaque/elm-simple-form/blob/master/example/src/Model.elm#L90

My current validation looks like this:

(|:) =
  Validate.apply

validate : Validation CustomError Items
validate =
  Validate.succeed Items
    |: (get "field" string)
    |: (get "secondField" string)
    |: (get "people" validatePeople)

validatePeople : Validation CustomError List Person
validatePeople =

And here is where I'm stuck. Can you point me in the right direction? If I'm able to resolve this, I will provide an example with the code to show how it works and I will write a post explaining it.

How do you populate form with dynamic values from network for edit?

Hi there,

I am creating a form for editing user profile information. User profile info is pulled from the network and then I would populate the values returned from the network in the form so user can update fields where necessary.

What is the easiest way to do this? Setting the initialFields in the init function does not work as the values to be populated is not static but will depend on the information returned from the network.

Thanks.

0.18 upgrade

  • finish sub lists #60
  • study and maybe reflect changes from Json.Decode core API
  • do the 0.18 syntax upgrade
  • refresh README
  • prepare renaming to elm-form #61

Add chain example?

Hi,

Thanks for the library, it's really neat! I've studied the example's source code, and the action SubmitUser is never used. I'm trying to implement it but no success so far. Could you make an example or explain how can I chain Form.submit with a custom action?

Thank you!

Not recognised as 0.17 on elm-package

elm-package install -y etaque/elm-simple-form 
Error: Unable to find a set of packages that will work with your constraints.

Any idea what's happening?

Simplify read API with an Input record

Getting an input state would be something like:

getInput : String -> Form -> Input v

type alias Input v =
  { value : v
  , error : Option Error
  , isDirty : Bool
  , isVisited : Bool
  }

Functions like Form.getValueAt, Form.getErrorAt, etc would be reserved for low level access.

Default values should be evaluated immediately

While I am developing I am pre-populating my fields in a login form

initialFields : List (String, Field.Field)
initialFields =
  [ ("email", Field.text "[email protected]")
  , ("password", Field.text "foo")
  ]

Which gets later gets passed to view

view address model =
    let
        formAddress = Signal.forwardTo address FormAction
        -- error presenter
        errorFor : FieldState e String -> Html
        errorFor field =
            case field.liveError of
                Just error ->
                    -- replace toString with your own translations
                    div [ class "error" ] [ text (toString error) ]
                Nothing ->
                    text ""

        inputGroup name builder =
            div
                [ class "inputGroup"
                , style [ ("margin", "10px 0") ]
                ]
                [ label
                    [ style [ ("display", "block"), ("margin", "5px 0") ] ]
                    [ text name ]
                , builder
                    (getFieldAsString name model.form)
                    formAddress
                    []
                , errorFor (getFieldAsString name model.form)
                ]
    in
    div
        []
        [ h2
            []
            [ text <| toString' model.intent ]
        , Html.form
            [ onSubmitSPA address Submit ]
            [ inputGroup "email" Input.textInput
            , inputGroup "password" Input.passwordInput
            , buttons address model
            ]

The issue is that if I press the submit button immediately, I pass control too

        Submit ->
            case getOutput model.form of
                Just m ->
                    ( { model | msg = "Authenticating..." }
                    , case model.intent of
                        Login -> login m
                        SignUp -> signup m
                    )
                Nothing ->
                    ( { model | msg = "still have errors" }
                    , Effects.none
                    )

and that complains that I still have errors. If I focus on one of my fields and then press submit, all is fine. This may not be an issue once I move to production and remove default values but I would think this is still a bug?

Need help upgrading from 0.17 to 0.18 with regards to custom MDL textfields

I have an Elm 0.17 project that I'm in the process of upgrading. I used it in combination with elm-mdl. I got it working by writing my own onInput, onFocus and onBlur for the form inputs.

My old code looks like this:

Options.onInput <| FormMsg << Form.Input phone.path << Form.Field.Text

But Form.Field got a pretty large overhaul, and I can't quite figure out how I'm supposed to be using. What I want is to capture the onInput event and create the internal Form.Msg myself. How would I go about doing this in elm-simple-form 0.18? Thanks!

Create function Form.hasChanged

Hi!

I have a big form that can be saved and updated (currently migrating from angular), It will be very useful to have a function to check if a form has changed, instead to extracting the output and checking each field.

Great library BTW,

Thanks!

Borked readme

You might want to correct the readme. Formatting /code samples seems off.

simple.elm example does not compile

The Simple.elm example app does not compile:

Detected errors in 1 module.
-- NAMING ERROR ------------------------------------------------- src/Simple.elm

Cannot find variable `:=`

42│     ("bar" := email)
         ^^^^^^^^^^^^^^
Maybe you want one of the following?

    /=
    ::
    <=
    ==

-- NAMING ERROR ------------------------------------------------- src/Simple.elm

Cannot find variable `:=`

43│     ("baz" := bool)
         ^^^^^^^^^^^^^
Maybe you want one of the following?

    /=
    ::
    <=
    ==

-- NAMING ERROR ------------------------------------------------- src/Simple.elm

Cannot find variable `Form.submit`.

92│           [ onClick formAddress Form.submit ]
                                    ^^^^^^^^^^^
`Form` does not expose `submit`. Maybe you want one of the following?

    Form.Submit

Use of defaultValue instead of value

A known issue with using value is that when you have you type really fast some update are overwritten with the next one, which results in incomplete text. The fix for this is to use defaultValue. Is there a reason why this library uses value?

We currently have problems testing this with end-to-end tests and defaultValue will probably fix this.

Compute output with Form.Reset

I have a clone functionality that uses Form.reset. Unfortunatly, even if the form data is valid, the output is not computed, so I don't have access to Form.getOutput.

example index.html?

Hi, thanks for sharing this elm package! I'm eager to try it as I learn elm.

I pulled down the example and ran the make call, $ elm make src/Main.elm --output main.js per the README, but it doesn't create the index.html file as suggested. Did I miss a step (elm newbie here)?

I then tried $ elm make src/Main.elm --output index.html and that does generate the form, but without any of the styling.

I do see there is a .gitignore entry for index.html, perhaps that was intentional?

ideas?

Iterate over fields to render form

Hello,

Is it possible to iterate over fields to render form? There should be some way to inject field names and optional parameters for rendering like placeholder or help text. With this info I would like to iterate over that, pattern match on some value constructors and render form inputs using pre-wired primitives from Form.Input.

multi select support

Digging though the code its unclear how to implement multi select,

Seems that you would need something along the lines of getFieldAsList

Thanks

Example broken

When you compile the current source for the example, it no longer works as the online version of the example does. Specifically submit no longer works.

Form errors not coming through

Hi
Take a look at this gist

I'm trying to do a custom validation to check that, when a option2 is selected, a related count figure must be divisible by 4.

I can see that getOutput is returning Nothing in the right instances, but:

  • there is no InvalidFloat when the program launches
  • after switching to option2 and entering a number indivisible by 4, no error is shown

Can you see see what I am doing wrong?

Form fields for union types

Assume one needs form fields for the following type Account:

type alias CompanyName = String

type Account
    = Private
    | Business CompanyName

I assume the correct form for the UI would be a radio selection between Private and Business, with a text input for the company name appearing if Business is selected.

What would the correct approach be with elm-simple-form?

The part which is unclear to me is how to set up the validation for have one field depend on another.

Bug: `andThen` should return GroupErrors (partially solved)

Please see https://gist.github.com/simonh1000/67c1c98c8c7c7a63019bd4a7a9f85ec7

I am building a conditional validator that - in one instance - checks that a number is divisible by 4.

valCount : Validation CustomError Float
valCount =
    V.get "Select" V.string
    `V.andThen` (\binding ->
        case binding of
            "option2" ->
                V.get "Count" V.float
                `V.andThen` (\tpc ->
                    case round tpc `rem` 4 == 0 of
                        True ->
                            valFloat "Count"    -- checks > 0
                        _ ->
                            let _ = Debug.log "failing" tpc
                            in
                            V.fail InvalidFloat)
            _ ->
                valFloat "Count")

The problem is that when the divisibility check fails, the function returns InvalidFloat whereas it needs to return GroupErrors <| Dict.fromList [(field, InvalidFloat)] if the errors are to be returned to the user. In practise the developer is faced with the tricky combination of getOutput == Nothing but errors == Dict.empty!

So, I can make this work with
V.fail (GroupErrors <| Dict.fromList [("Count", InvalidFloat)]))
but I have a feeling that andThen needs tweaking, or the docs need updating to explain what is happening.

== Update ==
It is sufficient to pass a negative number to

V.get "Count" V.float `V.andThen` (V.minFloat 0)

to get getOutput == Nothing but errors == Dict.empty

SubmitUser Msg is never called and I can't quite figure out how to set it as the submit action

In Elm 0.16, you'd write this code in the submit event of a button for a form:

let
  submitClick =
    case Form.getOutput form of
      Just user ->
        onClick address (SubmitUser user)
      Nothing ->
        onClick formAddress Form.Submit

So you can call the SubmitUser message to your application once your form has actual output without validation errors.

In 0.17, all Html types now have an Msg attributed to them. This causes the above case statement in the let binding to produce two different types, because one produces Html MyApp.Msg and the other Html Form.Msg.

I noticed the example app in tag 3.0.0 does not even use SubmitUser. But now, I'm trying to update my own app, and I run into this issue.

How would I port that let binding I posted above to 0.17?

Should update be exposed

I don't think so because specific Actions are not exposed and that is needed to pass to update

Improvements for 'update' form

Hello,

I have this type:

type alias Area  =
   { areaDeleted: Bool
   , areaName: String
   , areaMobileVisible: Bool
   , areaMobileActive: Bool
   , areaMobileIndex: Int
   , areaMobileDefault: Bool
   , areaImage: (Maybe String)
   , areaDescription: (Maybe String)
   }

Here is my validation for that:

validateArea : Validate.Validation () Area
validateArea =
  Validate.succeed Area
    |: ("areaDeleted"       := Validate.bool)
    |: ("areaName"          := Validate.string)
    |: ("areaMobileVisible" := Validate.bool)
    |: ("areaMobileActive"  := Validate.bool)
    |: ("areaMobileIndex"   := Validate.int)
    |: ("areaMobileDefault" := Validate.bool)
    |: ("areaImage"         := (Validate.maybe Validate.string))
    |: ("areaDescription"   := (Validate.maybe Validate.string))

To edit Area I need to set up fields like this:

-- utils for cleaner code
import Maybe.Extra exposing ((?))
(=>) = (,)


initialAreaFields : Maybe Area -> List (String, Field.Field)
initialAreaFields o =
  [ "areaDeleted"       => Field.check (Maybe.map .areaDeleted o ? False)
  , "areaName"          => Field.text (Maybe.map .areaName o ? "New area")
  , "areaMobileVisible" => Field.check (Maybe.map .areaMobileVisible o ? True)
  , "areaMobileActive"  => Field.check (Maybe.map .areaMobileActive o ? True)
  , "areaMobileIndex"   => Field.text (toString (Maybe.map .areaMobileIndex o ? 0))
  , "areaMobileDefault" => Field.check (Maybe.map .areaMobileDefault o ? False)
  , "areaImage"         => Field.text (Maybe.Extra.join (Maybe.map .areaImage o) ? "")
  , "areaDescription"   => Field.text (Maybe.Extra.join (Maybe.map .areaDescription o) ? "")
  ]

Is it possible to add some functions that would simplify this code?

  • something like Field.int or Field.float would help
  • Field.maybeCheck, Field.maybeText etc. would be nice
  • an example for 'update' would be very helpful (is my approach good?)

Conditional validation

Is it possible to validate a field only if another field has a specific value, e.g. don't validate e-mail if the user prefers to be contacted by a phone?

Not allowing Empty fields

I have the following

validation =
    form3 MyForm
        (get "Name" string `andThen` nonEmpty)
        (get "Version" string)
        (get "Product" string `andThen` nonEmpty)

initFields =
    [ ("Name", Field.Text "")
    , ("Version", Field.Text "")
    , ("Product", Field.Text "")
    ]
init =
    ( Model
        (Form.initial initFields validation)
....

and yet the form is not validating when field versionName is empty. Am I missing something?

Update a text input problems

Hi, I will try to work on an example, but wanted to flag a problem straight away. I have a text input that filters the possible choices as you type. When you click on a choice it updates the text input.

That works, but if you then start deleting the input text, such that more choices appear again, then clicking a second time on the list does not update the text input any more.

Video at: https://youtu.be/L8DbIBFF5_U?rel=0

Note how at the end the input value is "Customer 2", but you do not see that in the input box.

If you have any ideas, I would welcome it. (I'm certainly not convinced that the problem lies with elm-form, but I do something similar on a simpler form elsewhere in my site without elm-form, and then I don't have the same issues)

Generic select for foreign keys

Hello,

I'm wondering how to make an input for foreign keys. Value stored in field should be integer, name displayed to the user should be string, I need support for autocompletion (dropdown with data from the server, so http query will be involved), there should be additional 2 buttons, one to add new item (if I want to select something that doesn't exist yet) and one to open a dialog where I can select an item (a list/table with sorting and filtering), is it possible to make such generic 'widget' with pre-wired actions?

Considering a rename to elm-form

As this package isn't really targeted for simple forms, and offers at the same time form building and validation, I'm tempted to do this rename.

(I'm aware of the procedure to avoid broken builds)

WDYT?

More Docs on Messages

In particular it would be nice to know what Append String and RemoveItem String Int can do.

How to update multiple form elements at once

I have a form to select products. After you have selected some parameters, the list of remaining possible options is shown. When you click one all the remaining parameter selects are completed for you.

I used to use Form.Reset to create a message with multiple form values, which I then intercepted in the update function to get the list and add those to the model, rather than letting the list be used to reinitialise the form.

Now the problem for me is that Form.Reset takes List ( String, Field ) whereas the update function needs Fieldvalues, and there is no function Field -> Fieldvalue

So far I've come up with

        FormMsg (Form.Reset lst) ->
            let
                reinitialisedForm =
                    Form.update (Form.Reset lst) model.form

                changedFields =
                    model.form
                        |> getChangedFields
                        |> Set.remove "Finish"
                        |> Set.remove "Height"
                        |> Set.remove "Width"
                        |> Set.remove "Weight"
                        |> Set.insert "Product"
                        |> Set.toList

                go : String -> SpecsEditor.Model -> SpecsEditor.Model
                go fname acc =
                    case getFieldAsString fname model.form |> .value of
                        Just val ->
                            Form.update (Form.Input fname Form.Text <| Field.String val) acc

                        Nothing ->
                            acc

                newForm =
                    L.foldl go reinitialisedForm changedFields
            in
                { model | form = newForm }

Async validation

It would be really awesome to have async validation built in. I can't think of a reason not to have this since most apps need some kind of API validation.

Add http post request to example

I am trying to get going with elm and I would really appreciate it if you could add an example about how to send this to a certain endpoint via http post, because in my static site the contact form is the only dynamic part I want and I would like to do it all in elm.
This might be slightly off topic, but from my point of view would make it easier for users new to elm to replace their jQuery clutter
Thanks for considering

How do you validate 2 form fields to have same value.

Hi there,

I am attempting to validate that my new password field and my confirm password fields are the same.

However I am unable to do so in the standard validator or with the custom validator as it seems each field is validating independently.

How can I validate by comparing different fields.

Thanks.

How to validate form fields which should have same values

Hi @etaque ,

This issue is related to issue 66 which was previously closed.

I have implemented your recommendation on how to do the password confirmation as below:

`validateChangePwdForm : Validation CustomError ChangePwdForm
validateChangePwdForm =
map2 ChangePwdForm
(field "newPassword" validatePassword)
(field "confirmPassword" string |> andThen passwordsMatch)

passwordsMatch : String -> Validation CustomError String
passwordsMatch confirmPassword =
(field "newPassword" string)
|> andThen
(\s ->
if (s /= confirmPassword) then
fail (customError PasswordsMustMatch)
else
succeed s
)`

And I am using the below code to show the error message when the passwords do not much.

`
let
password =
Form.getFieldAsString "confirmPassword" changePwdForm

( passwordError, invalid ) =
    case password.liveError of
        Just errorValue ->
            case errorValue of
                Form.Error.Empty ->
                    ( "Please confirm your password.", attribute "invalid" "" )

                Form.Error.CustomError PasswordsMustMatch ->
                    ( "Passwords must match", attribute "invalid" "" )

                _ ->
                    ( "Please provide a valid Password.", attribute "invalid" "" )

        Nothing ->
            ( "", class "" )

`
However, I am unable to see the Error message when the input is validated.

What am I doing wrong?

From the troubleshooting I have done so far, it seems that the line

fail (customError PasswordsMustMatch)

is failing to return the validation.

I will appreciate your feedback.

Thanks.

Publish a New Version?

Hey, I can see that the validations have been moved out of the model, which is great.

I'm still using 1.0.0 from the package repository and am wondering whether it makes sense to wait for a new version to be published or whether I should rather be including the repo in my elm-package.json.

Allow having fields cardinality

Is it currently possible to have the same field(s) appear multiple times . For example have a kids fields, so when user clicks on add another they are presented with Name and Age fields.

btw, Cardinality is the term Drupal uses to define the number of values a field can have - I'm so happy I got to use it in non-Drupal repos 😉

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.