Phoenix forms with custom grid

Hi guys, im working on a form:


it is written in html, im using liveview and the form is rendered inside a modal live_component.
Actually I’m looking to rewrite it with pure phoenix html tags and form_for but I don’t know if this approach will allow me to handle the grid to put the items as I want I tried different ways but they doesn’t work.
It is possible to do this? or for handling rows and column better to use the html form?
this is my html code:

<div id="<%= @id %>">
  <form phx-submit="submit_form" phx-target="#<%= @id %>">
    <div class="row">
      <div class="form-group col-md-4">
        <label for="inputName">Name</label>
        <input name="name" type="text" class="form-control" id="name">
      </div>
      <div class="form-group col-md-2">
        <label for="inputState">Timezone</label>
        <select name="timezone" id="inputState" class="form-control">
          <option selected>Select timezone</option>
          <option>UTC</option>
          <option>Naive</option>
        </select>
      </div>
      <div class="form-group col-md-2">
        <label for="inputState">Laguage</label>
        <select name="language" id="inputState" class="form-control">
          <option selected>Select Language</option>
          <option>English</option>
          <option>Spanish</option>
          <option>French</option>
          <option>German</option>
          <option>Arabic</option>
        </select>
      </div>
      <div class="form-group col-md-2">
        <label for="inputState">1st Category</label>
        <select name="category_1" id="inputState" class="form-control">
          <option selected>Select One</option>
          <option>Arts</option>
          <option>Comedy</option>
          <option>Education</option>
          <option>Fiction</option>
          <option>Health</option>
          <option>HIstory</option>
        </select>
      </div>
      <div class="form-group col-md-2">
        <br>
        <br>
        <select name="subcategory_1" id="inputState" class="form-control">
          <option selected>Select One</option>
          <option>Books</option>
          <option>Design</option>
          <option>Fashion</option>
          <option>Food</option>
          <option>Visual Arts</option>
        </select>
      </div>
    </div>

    <div class="row">
      <div class="form-group col-md-4">
        <label for="inputEmail">Email</label>
        <input name="email" type="email" class="form-control" id="email" placeholder="email@example.com"></input>
      </div>
      <div class="form-group col-md-4">
        <label for="inputCopyrights">Copyrights</label>
        <input name="copyrights" type="text" class="form-control" id="copyright" ></input>
      </div>
      <div class="form-group col-md-2">
        <label for="inputState">2nd Category</label>
        <select name="category_2" id="inputState" class="form-control">
          <option selected>Select One</option>
          <option>Books</option>
          <option>Design</option>
          <option>Fashion</option>
          <option>Food</option>
          <option>Visual Arts</option>
        </select>
      </div>
      <div class="form-group col-md-2">
        <br>
        <br>
        <select name="subcategory_2" id="inputState" class="form-control">
          <option selected>Select One</option>
          <option>Comedy Interviews</option>
          <option>Improve</option>
          <option>Stand Up</option>
        </select>
      </div>
    </div>

    <div class="row">
      <div class="form-group col-md-4">
        <label for="inputAddress">Description</label>
        <textarea name="description" class="form-control" id="description"></textarea>
      </div>
      <div class="form-group col-md-4">
       <label for="inputName">Keywords</label>
       <input name="keywords" type="text" class="form-control" id="name">
     </div>
      <div class="form-group col-md-2">
       <label for="inputState">3rd Category</label>
       <select name="category_3" id="inputState" class="form-control">
         <option selected>Select One</option>
         <option>Books</option>
         <option>Design</option>
         <option>Fashion</option>
         <option>Food</option>
         <option>Visual Arts</option>
       </select>
     </div>
      <div class="form-group col-md-2">
         <br>
         <br>
         <select name="subcategory_3" id="inputState" class="form-control">
           <option selected>Select One</option>
           <option>Comedy Fiction</option>
           <option>Drama</option>
           <option>Science Fiction</option>
         </select>
       </div>
    </div>

    <div class="row">
      <div class="form-group col-md-4">
        <div class="form-check">
            <input name="is_private" class="form-check-input" type="checkbox" id="gridCheck">
            <label class="form-check-label" for="gridCheck">
              Is private?
            </label>
        </div>
        <div class="form-check">
          <input name="is_explicit" class="form-check-input" type="checkbox" id="gridCheck">
          <label class="form-check-label" for="gridCheck">
            Is explicit?
          </label>
        </div>
      </div>
      <div class="form-group col-md-4">
        <div class="">
          <label for="customRadioInline1">Show Type</label>
        </div>
        <div class="custom-control custom-radio custom-control-inline">
          <input name="episodic" type="radio" id="customRadioInline1" name="customRadioInline1" class="custom-control-input">
          <label class="custom-control-label" for="customRadioInline1">Episodic</label>
        </div>
        <div class="custom-control custom-radio custom-control-inline">
          <input name="serial" type="radio" id="customRadioInline2" name="customRadioInline1" class="custom-control-input">
          <label class="custom-control-label" for="customRadioInline2">Serial</label>
        </div>
      </div>
      <div class="form-group col-md-4">
        <div class="custom-file">
         <input name="image_file" type="file" class="custom-file-input" id="customFile">
         <label class="custom-file-label" for="customFile">Choose Image</label>
        </div>
      </div>
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>

  </form>
</div>

thanks in advice!

Within the <%= form_for ... %> tag, you can put a <div class="row"> and it would put it in a row as you would expect it. You did say that you tried different ways and that it didn’t seem to work, so could you elaborate on what you tried and what didn’t work?

1 Like

I’m guessing you would like to attempt using the Phoenix.HTML.Form functions instead of using your own <tag> structure.

:thinking: I would encourage you to attempt structuring it with form_for since you may encounter a “cleaner” view if you combine it with the Ecto.Schema and Ecto.Changeset helpers (but there’s nothing wrong with doing it custom).

If you would like to treat your data in separate structures you could also attempt different <form> tags within the same view.

<form phx-change="personal-info-change">
  Your HTML
</form>
<form phx-change="options-change">
  Your HTML
</form>
<form phx-change="categories-change">
  Your HTML
</form>

But its your call :slight_smile:

If all your would like to do is to add styles to the form functions you may attempt to pass a keyword list equivalent to the properties of your tag. From the documentation:

Other options will be passed as html attributes. ie, class: "foo", id: "bar"

@LTheGreats yeah, actually that’s one of the things I tried, but since I’m rendering that form inside a modal live component I created to reuse it.
look what happens:


image

@chouzar ok thank you I will read again that documentation, so what you are telling me is that the same things I can do with the html form can be done with the form_for right?

Unrelated and I’m unsure of the internal mechanics of form_for and liveview but documentation advises about form limitations.

At this point I would use the inspect tools of the browser to see how styles are being applied. There may be something interfering with the grid structure :thinking: have you tried using css columns or css grid for structuring your form?

Yes you can achieve the same effect; form_for is super useful if you already have your data structured in such a way that can be read by it :slight_smile: like an Ecto.Changeset.

I personally prefer plain html tags but the functions at Phoenix.HTML.Form bring some niceties to the table; It looks like your form could benefit by using them.

1 Like

thanks for your answer buddy, I can’t use my own css files for now I can only use bootstrap for styling

Too bad :frowning: try to see if maybe form_for is creating something that interferes with the original styling; I hope is an easy fix :slightly_smiling_face:.

2 Likes