Django: How to read info from custom radio select in view - html

So yesterday I spent whole day customizing star-rating ("radio-button-ish"). Now I don't want to abandon my css masterpiece (I am not much of a front-end guy so this was real pain for me), but it looks like that my approach to the problem wasn't correct. Html code is quite simple:
<div class="col-md-5 mb-0 mt-3">
<div id="rating">
<input type="radio" name="star" id="star1"><label for="star1"></label>
<input type="radio" name="star" id="star2"><label for="star2"></label>
<input type="radio" name="star" id="star3"><label for="star3"></label>
<input type="radio" name="star" id="star4"><label for="star4"></label>
<input type="radio" name="star" id="star5"><label for="star5"></label>
</div>
</div>
Now, is there a way to simply read from this choice and then use it in my view?
The situation is, normally I would probably use Field in form with choices but the design would be lost. Do you see a simple solution? Or is there a way of customizing a ChoiceField with widget RadioSelect into the same form, so i can use the name, id just like in above html code?
Note: this is my first django project, pardon me if it is a complete nonsense or I missed something basic..

you can put this code inside your form.
here the field name is star. so you if you access field value of star, then you should get the selected value
small note: in your code this snippent 'id="rating"' is unnecessary

Related

Can I use more than one name attribute in HTML tag?

I am doing a django project.
But I wanted to have radio buttons grouped as well as name of the buttons to work with django.
Is it okay to use two name attributes in one HTML tag?
Will I be facing any errors if I do so?
Below is my code I am stuck in.
<input type="radio" name="group1" name="removePunc"> Remove Punctuations
<br>
Input name attributes must be unique to send data using traditional forms. If you find yourself needing more attributes, use the data- attributes. Pls share some code to undertand what you are trying to achieve.
If you want to label the group of radio buttons add class="group1" to all of the radio buttons instead of name="group1".
<label for="removePunc">Remove Punctuations</label>
<input type="radio" class="group1" name="removePunc">
<label for="button2">Button 2</label>
<input type="radio" class="group1" name="button2">
<label for="button3">Button 3</label>
<input type="radio" class="group1" name="button3">

why input and label elements got change automatically on development instance

Here is my code
<input class="input-radio" data-pid="${pdict.Product.ID}" type="radio" name="shippingMethod" value="shipToStore" id="ship-shop-${pdict.Product.ID}" />
<label for="ship_to_store">
But when this code goes to develop environment it's reflecting like
<input class="input-radio" data-pid="10775895" type="radio" checked="checked" name="shippingMethod" value="shipToStore" id="ship-shop-10775895" data-ae-form-field="true">
<label for="ship-shop-10775895" class="ae-label">
Can you please help me to find out
From where this data-ae-form-field="true" is coming ?
Why my label for attribute value got change automatically (There is
no js written for this, already checked whole js part).
Why it's adding class to my label class="ae-label"

Is there a way to streamline the creation of similar multi-component elements in HTML5?

I am new to HTML and I want to implement a rather large list of user options that use radio buttons. The various items all have a similar format and look like this:
<p>
"Question 1 text"
<input style="radio" name="question1" id="q1_id1">
<label for="q1_id1">Yes</label>
<input style="radio" name="question1" id="q1_id2">
<label for="q1_id2">No</label>
<input style="radio" name="question1" id="q1_id3">
<label for="q1_id3">Maybe</label>
</p>
<p>
"Question 2 text"
<input style="radio" name="question1" id="q2_id1">
<label for="q2_id1">Yes</label>
<input style="radio" name="question1" id="q2_id2">
<label for="q2_id2">No</label>
<input style="radio" name="question1" id="q2_id3">
<label for="q2_id3">Maybe</label>
</p>
etc.
Since so much of this code is repetitive, I was wondering if there was a way to declare an html object or something (I know html isn't an object oriented language), like you would do in other programming languages so you could have something like this:
Define html object that contains text and three radio buttons
Add a list of those objects to the document, changing only the question text and the button label text
in just a few lines of html.
Is there a way to do this, or do I have to resort to copy-pasting?
There is no way to do this in HTML. There are other ways:
1) You can use a template language to generate the appropriate HTML on the server before you send it to the user. Depending on your server, there are different options for this.
2) You can send the input's data to the user's browser as JSON and generate the HTML using Javascript. This can be more economical if the element repeats many times, like in a large data table.

html/Thymeleaf - Implementation of radio input

I am working on this little project with an online order service for pizzas.
(using Spring Web MVC, Thymeleaf, ...)
Yesterday, someone helped me out adding inputs for selecting an specific amount and size.
<div>
<form th:action="#{/saveOrderAndReload(name=${pizza.name})}" method="post">
<div class="input-group">
<span class="input-group-addon">Bestellmenge (min. 1, max. 10):</span>
<input type="number" name="amount" class="form-control" min="1" max="10" placeholder="1"/>
</div>
<div class="input-group">
<input type="radio" name="size" value="1"> Klein</input>
<input type="radio" name="size" value="2"> Mittel</input>
<input type="radio" name="size" value="3"> Gross</input>
</div>
<div class="form-group">
<div class="form-group">
<input type="submit" class="btn btn-primary btn-success" value="zur Bestellung hinzufuegen"/>
</div>
</div>
</form>
The "amount" field protects the application itself from false input because it only allows integers from 1-10, otherwise the User gets a notification asking for an numeric input.
The radio input where you can select between 3 sizes has 2 problems:
1) The buttons arent among themselfes, they are next to each other.
2) I dont know how to prevent the user from doing no input.
I looked around for quite some time finding the standart html version for this:
<form>
<input type="radio" name="gender" value="male" checked> Male<br>
<input type="radio" name="gender" value="female"> Female<br>
<input type="radio" name="gender" value="other"> Other
</form>
And something like this:
<ul>
<li th:each="ty : ${allTypes}">
<input type="radio" th:field="*{type}" th:value="${ty}" />
<label th:for="${#ids.prev('type')}" th:text="#{${'seedstarter.type.' + ty}}">Wireframe</label>
</li>
</ul>
We didnt learn anything about the second one so I decided to use the standart html. But I does not want to work like that example: It gets errors that this "checked" expression is not allowed, " tag is not closed" and whatnot.
So my questions are:
1) What can I do to make the input look better?
2) How can I set like a placeholder or standart value so the application always gets this input and does not crash?
As you might have realized I am a complete beginner with this type of stuff so be lenient ;)
Answer 1
If you want the change the way the radio buttons are looking, this might help: http://code.stephenmorley.org/html-and-css/styling-checkboxes-and-radio-buttons/.
Some notes and Answer 2
It gets errors that this "checked" expression is not allowed, " tag is
not closed" and whatnot.
Thymeleaf dies not allow attribute minimization. That means that you need to provide a value for each attribute. You just have to use checked="checked" instead of checked.
<form method="post">
<!-- Make sure to always set a value for attributes when using thymeleaf (use checked="checked" instead of checked) -->
<div><input type="radio" name="gender" value="male" checked="checked" />Male</div>
<div><input type="radio" name="gender" value="female" />Female</div>
<div><input type="radio" name="gender" value="other" />Other</div>
</form>
This is actually wrong:
The "amount" field protects the application itself from false input
because it only allows integers from 1-10, otherwise the User gets a
notification asking for an numeric input.
You are only validating on the client side. Clientside validation is okay if you want to give your users feedback even before they submit your form but it is not enough to protect yourself from bad input.
Nathan Long does explain why client side validation is not enough pretty well (JavaScript: client-side vs. server-side validation):
It is very dangerous to trust your UI. Not only can they abuse your
UI, but they may not be using your UI at all, or even a browser. What
if the user manually edits the URL, or runs their own Javascript, or
tweaks their HTTP requests with another tool? What if they send custom
HTTP requests from curl or from a script, for example?
As you are using spring-mvc you should take adventage of it and take a look at the following tutorial: https://spring.io/guides/gs/validating-form-input/.
To provide default values when working with spring-mvc you can just give the field a value:
public class PersonForm {
// this field will have a default value (foo)
// NotNull will ensure that a value is set for this field when validated by spring (however it can be an empty string... take a look at hibernates #NotBlank annotation if you want to prevent empty string or use a regex)
#NotNull
private String gender = "foo";
}
However default values often dont make sense for input[type="text"]. If you want to prodive a placeholder for any input you could just use the html attribute placeholder="the placeholder":
<input type="text" name="name" value="" placeholder="Enter your name" />

HTML form send unchecked checkboxes

I need to send a very long form with lots of checkboxes. They're grouped by areas, like this:
<fieldset>
<legend>Whatever1</legend>
<div class="checkbox-list">
<label class="checkbox inline"><input type="checkbox" name="Hobbies" value="Arts"> Arts</label>
<label class="checkbox inline"><input type="checkbox" name="Hobbies" value="Bars"> Bars</label>
<label class="checkbox inline"><input type="checkbox" name="Hobbies" value="Books"> Books</label>
(more items)
</div>
</fieldset>
<fieldset>
<legend>Whatever2</legend>
<div class="checkbox-list">
<label class="checkbox inline"><input type="checkbox" name="Interests" value="Architecture"> Architecture</label>
<label class="checkbox inline"><input type="checkbox" name="Interests" value="Audio"> Audio/vĂ­deo</label>
<label class="checkbox inline"><input type="checkbox" name="Interests" value="Business"> Business</label>
(more items)
</div>
</fieldset>
The form is much longer, but you get the idea.
Using name="Hobbies" value="Arts" my django backend receives all the checkboxes grouped in a Hobbies array, which is very convenient, but I need to know the unchecked checkboxes, too. I know about the hidden input trick, but it's not useful to me, because I use the value field as part of the checkbox grouping.
Any idea about what can I do?
Well, as I guess you already know, there is fundamentally no way of asking the browser which boxes were left unticked. Blame the inventors of HTML forms...
Here are a few simple approaches which don't break your grouping logic:
Re-generate the list of checkboxes which you displayed on your server side. This is preferable in a lot of cases anyway, since it means you're not trusting the data coming back to be exactly what you displayed. (Consider what happens if I use a debugging tool like Firebug to delete one of your checkboxes, or add a new one...)
Include hidden inputs with a corresponding name for each checkbox - "Interests_All", "Hobbies_All", etc - so that you have two arrays of data, one including just the checked items, one including everything displayed.
Use radio buttons instead of check-boxes. Yes, they display differently, but they can have the functionality you want of submitting a Yes/No value, rather than just adding to the array or not.
How about setting a default false value for each checkbox in the backend. If a value has been passed by the browser, you can then change the value to true.
You could add a hidden input field, and on form submit, use jQuery to populate the value of the hidden input with an array containing the values of the unchecked checkboxes:
$("form").on("submit", function(e) {
e.preventDefault();
// Create an array of unchecked Hobbies
var uncheckedValues = [];
$(this).find("input[name='Hobbies']:not(:checked)").each(function() {
uncheckedValues.push(this.value);
});
// Set the uncheckedValues array as hidden input value
$("#your-hidden-input").val(uncheckedValues);
alert($("#your-hidden-input").val());
// Handle the form submission
handleFormSubmit();
});
See DEMO.
I've solved it. The idea was in IMSoP's answer. Here's my solution, maybe it can help someone:
<fieldset>
<legend>Whatever1</legend>
<div class="checkbox-list">
<input type="hidden" name="Hobbies_Arts">
<label class="checkbox inline"><input type="checkbox" name="Hobbies" value="Arts"> Arts</label>
<input type="hidden" name="Hobbies_Bars">
<label class="checkbox inline"><input type="checkbox" name="Hobbies" value="Bars"> Bars</label>
<input type="hidden" name="Hobbies_Books">
<label class="checkbox inline"><input type="checkbox" name="Hobbies" value="Books"> Books</label>
(more items)
</div>
</fieldset>
With that, is very easy to handle the lists in the django side.