How can I include an HTML input in rails strong params? - html

I'm trying to create instances of a model "Post" with strong params that look like this:
private
def post_params
params.require(:post).permit(:name, {images: []})
end
In my form, this is how I upload files to post_params["images"], and therefore to post.images:
<%= f.file_field :images, multiple: true %>
But I want to apply custom styling to the upload button, so I build one using HTML. But I can't figure out what name attribute to give the input so that it's included in post_params. Here's what I've tried:
<input name="images" type="file" multiple="true"/>
<input name="post[images]" type="file" multiple="true"/>
<input name="post['images']" type="file" multiple="true"/>
<input name=":images" type="file" multiple="true"/>
But they all just go to params["post"]["images"], not strong_params.
What name can I give an HTML input so it's included in strong params?

Something like this:
<input multiple="multiple" name="post[images][]" id="posts_images" type="file">
This should generate the correct JSON params that your controller is expecting. It can get confusing with the multiple levels of hash/array. That's why I use the inspect element in the browser as mentioned in my comment above to see what Rails is generating, then I can build custom styled elements to suit my needs.
One way to remember it is: You are require-ing post, and then looking for a hash with a key of images and a value of type array. That way it's easier to know where to use singular vs plural, what is the key, etc. So mapping it out syntactically would be:
<model name>[<key defined in strong params>][]
in the .erb version if you look at the top of your form, think about what the value of f is in the ... do |f|. That's where it gets the controller name of post (singular) and then you are giving it the method name :images (plural) in the file_field. According to the Rails Docs you could use the singular :image but the plural seems more correct to me.

Related

With use PathVariable CSS not loading and how to fill form to update in thymeleaf

I am trying to do same small service and sometimes I am sending requests to my Rest Api.
I am getting two problems:
How to fill field in form in html using thymeleaf? I have form like this and would like to fill fields with current values (th:value="${}" - not working for me):
<form th:action="#{/offences/edit}" method="post" th:object="${createOffenceForm}"> <input th:field="*{name}" th:value="${currentOffence.name}"/> <input th:field="*{penaltyPoints}" th:value="${currentOffence.penaltyPoints}"/> <input th:field="*{amountOfFine}" th:value="${currentOffence.amountOfFine}"/> <button type="submit">UPDATE</button> </form>
The problem is with loading css styles to html when I redirect to the site with path variable. For example i created html with two buttons. First one is hardcoded:
<a th:href="#{/offences/test}" class="link" style="text-decoration: none"><button class="buttonOK" type="submit">EDIT</button></a>
after redirect my site looks like this (everything works, it should be like that):
`
and here is after second button - redirect with path variable:
<a th:href="#{'/offences/edit/' + ${offence.id}}" class="link" style="text-decoration: none"><button class="buttonOK" type="submit">EDIT</button></a>
and view after load:
For the issue with your form data not being filled, this is because th:field and th:value are not meant to be used at the same time. So th:field ends up overwriting you value.
In your case I would suggest either manualy setting name (and id) or replacing th:object with the a filled version of the bean you want to return and only using th:field
As for the second issue it looks like a faulty fragment return on a post call to me but need to atleast have the controller functions and more complete html to say anything about that. And in general it's advisable to have 1 question per problem and not bundle things.
Ok so i found soultion.
To fill fields in form I only had to add to ModelMap form with fields.
Something like this and thymeleaf autofilled fields in html.
modelMap.addAttribute("createOffenceForm", new CreateOffenceForm(offenceDTO.getName(), offenceDTO.getPenaltyPoints(), offenceDTO.getAmountOfFine()));
Second solution is simple too. When changed mapping in Controller from #GetMapping("/path/{id}") to #GetMapping("/path-{id}") - everything works. There is no other problems with styles...

Displaying data from the console into an HTML form using EJS

So, I'm building an app where the user enters some data, the code modifies it, and returns it back to the user on the screen in an HTML input tag probably.
The user input is taken as : const userInput = req.body.user_word; (using Node.js for backend)
and the modified data is stored as var encrypted_word
I wish to display the contents of this variable into an input tag <input type="text" name="encrypted_word"> using EJS
I read that <%= tag is helpful in doing so but couldn't devise the solution.
Can someone help me with this...
i would use <%- instead of <%= also you have to the attribute value for inputs
<input type="text" value="<%- encrypted_word %>">

How to make a angucomplete-alt tag 'required' in a form

I am using angucomplete-alt in many places of my web application (in forms), but i cant make the autocomplete fields as a 'required' field, even thought i've used the 'field-required' attribute.
angucomplete-alt#sectorSuggested(field-required= true,placeholder='Search sectors', local-data='sectors', selected-object='onSectorSelected', search-fields='Sector', pause='300', minlength='1', title-field='Sector',input-class="form-control form-control-small", name='sector')
how do i make it required field, please help :)
Going off of the documentation and examples I can see here, it looks like the attribute should be
field-required="true"
In the above example, his element looks like this:
<div angucomplete-alt="" id="ex8" placeholder="Search countries" pause="100" selected-object="countrySelected8" local-data="countries" search-fields="name" title-field="name" minlength="1" input-class="form-control form-control-small" match-class="highlight" field-required="true" class="ng-isolate-scope">
Additionally, if you have many required fields, his documentation states:
Set custom class name for required. Unique class names need to be set
when you have multiple directives to validate
You can do this, using the field-required-class attribute.
Taken from here
you can use field-required = "true"
and it should work fine.

rails custom html elements form

I am new in Rails and i've searched around the web and books but I couldnt find how to make custom forms when working with rails..
what happens is that I am used to write my own HTML tags and I confortable with that. I dont like to use libs like JSF (from JAVA) that writes html components for me and I dont want that rails write it for me, except for simple tags like
text_field(:post, :title, :size => 20)
# => <input type="text" id="post_title" name="post[title]" size="20" value="#{#post.title}" />
so.. how can I do that.. for example: I would like to write by myself
<input type="text" class="myclass" data="mydata" name="how-to-get-the-attribute-name-with-rails" value="how-to-get-value-with-rails" />
how can I do that?
If you want more control over the html you are creating, you can also use a content_tag
content_tag :input, "label_name", class: "myclass", data: "mydata", name: "how-to-get-the-attribute-name-with-rails", value: "how-to-get-value-with-rails"
You can supplement any html element tag for :input. So if you want a div instead, use :div etc...
As you have written above, The name of any form field in rails is in the following format
name = 'post[name]' i.e. model_name[attribute_name]
So your params hash will contain :post => {:name => value} which allows you to use mass-assignment. But if you want to get some extra parameters from the form you can directly include them in the form and give them any name as you want. It will be available in your params hash.
You can get value easily using value = <%= #object.attribute_name. %>
I am not sure if you wanted to know this or something else. Let me know if you need more help.
You can simply write html inside a Rails form, so
<input type="text" class="myclass" data="mydata" name="how-to-get-the-attribute-name-with-rails" value="how-to-get-value-with-rails" />
is perfectly valid, but note that you should use the names and id's in correct way to automatically bind them to your back end controller.
After all, what text_field(:post, :title, :size => 20) does is it convert the parameters to pure HTML (we call them helper methods in Rails).
Read here for formhelper options (using helpers will keep your code clean).

google app engine - how to get ListProperty from an html form's input type="text"

i have an aplication that takes some parameters through an html form and then creates a model entity. The problem is, that whatever i try, i get an error like this:
BadValueError: Property xxx must be a list
this is the model:
xxx = db.ListProperty(int)
this is the sentence used for getting the list:
xxx = self.request.get('xxx')
I figure that the html form returns a string as i hit the submit button. So, how would i be able to get a list from an input type="text" in an html form? If i write 1,2 it's not ok, as isn't anything else.
The python code is similar to the helloworld application where a form is used to post greetings on the page, the difference is that i need to get a list, not text.
self.response.out.write("""
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
</body>
</html>""")
class Guestbook(webapp.RequestHandler):
def post(self):
greeting = Greeting()
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
self.redirect('/')
Is this the optimal way to get user input to create a model entity and how can i fix it so that it will get a list and write it in the models attributes?
The solution was very simple, once an expert showed me :)
tlist = map(lambda x: int(x), self.request.get_all('xxx'))
You should put lists inside xxx, not strings or integers.
Maybe you would want to use request.get_all method, instead of get.