How to update "th:field" in Thymeleaf form? - javascript

I'm making a Spring MVC app using Thymeleaf.
The app contains a Combo Box/Dropdown Menu inside a form. I want every selected value in the Combo Box to be linked to the update of specific fields. I.e.
value 1 -> form updates field 1
value 2 -> form updates field 2
...
I tried by changing the value of th:field using JavaScript, but looks like Thymeleaf tags are "pre-processed" and once the HTML is rendered and the form is associated with a specific field, it stays like that.
What would be the best way to face this problem?
Would it be necessary to trigger the refreshment of the page every time that the value of the Combo changes so that the field that the form updates can vary or there's a better way?
Thanks in advance.

Like you mention, it's not possible to change "th:field" or any thymeleaf-specific attributes after the page has been rendered.
However, "th:field" is usually just a shortcut for setting the "id", "name", and "value" attributes. (See here: https://www.thymeleaf.org/doc/tutorials/3.0/thymeleafspring.html#inputs) So you could update those manually from your Javascript.
Although in this case I think the simplest solution would be to create a new type of object in your Java code with fields that match the fields of your form, and use that object instead. So, for example:
class MyFormDTO {
private String fieldToUpdate;
private String newValue;
// ... getters and setters ...
}
And in your template:
<select th:field="*{fieldToUpdate}">
<option value="field1">Field1</option>
<option value="field2">Field2</option>
</select>
<input type="text" th:field="*{newValue}" />
And your POST handler method:
#PostMapping("/my-form")
public String submitMyForm(MyFormDTO myFormDTO) {
MyBackendObject myBackendObject = MyBackendService.get(...);
switch (myFormDTO.getFieldToUpdate()) {
case "field1": myBackendObject.setField1(myFormDTO.getNewValue()); break;
case "field2": myBackendObject.setField2(myFormDTO.getNewValue()); break;
}
}
...rather than using the "MyBackendObject" (or whatever) directly as the form object.

Related

Django Modelmultiplechoicefield Checkboxselectmultiple Problem Getting Selected Checkbox

I have been working all day to try and get the selected values on one set of checkboxes on my Django form and copy the selected ones only to an identical checkbox on my form. If a user clicks on a checkbox in form.author defined below, I want the same identical checkbox to automatically be checked on form.favorite_author defined below.
I've tried a JQuery approach as documented here...Copy Selected Checkbox Value From One Checkbox To Another Immediately Using JQUERY but no luck so far. I've recently begun exploring an avenue with the Modelmultiplechoicefield and the checkboxselectmultiple parameters within the form itself. From what I can tell, when I am using JQuery and trying to check a box on the form, the value is coming back as undefined which is most likely why it is not propagating the checkbox selection to the other checkbox.
Here is my form....
class ManagerUpdateNewAssociateForm(forms.ModelForm):
class Meta:
model = Library
self.fields['author'] = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple(),
queryset=Books.objects.all()
self.fields['favorite_author'] = forms.ModelMultipleChoiceField(
widget=forms.CheckboxSelectMultiple(),
queryset=Books.objects.all()
My HTML...
<div class="spacer83">
{{ form.author }}
</div>
<div class="spacer83">
{{ form.favorite_author }}
</div>
When I tried to trace JQuery, it told me the checkbox selections are undefined. I did read a bit about how Modelmultiplechoicefield, since it uses a queryset it doesn't show the selections, but I can't figure out how to get it to.
Thanks in advance for any thoughts.
In combination with the other issue included in this one, I went back to the JQuery route and explored further. From what I can tell, I was not able to use the class for the input because of the way the HTML for Django forms is generated in this use case. I ultimately was able to leverage the input name and then used the code below to interrogate the checkboxes accordingly:
$(document).ready(function() {
$("[name=author]").change(function() {
let selectedValA = $(this).val();
let isAChecked = $(this).prop("checked");
$(`[name=favorite_author][value="${selectedValA}"]`).prop("checked", isAChecked);
});
});
});

Save state of multiple Dynamic Components on ReactJS

Hi I have this component structure:
<ScheduleApp />
<ScheduleForm />
<TeamField />
My ScheduleApp contains a form called ScheduleForm and under this form I have a field where users can specify a number of teams and depends on the number the number of TeamField is created.
My form looks like this:
And what I wanted is to save all the teams' names under my ScheduleApp component. I can save all the other states with no problem, example: the No. of Teams field with no problem but I'm stuck on how to save the Team Name fields in an array.
Here is my poor attempt on saving the array but it looks like it saves all the keystrokes I've made probably because I triggered it onChange event.
How am I suppose to solve this problem and just save the dynamic components on the parent components' state?
Now here are my codes on jsfiddle for some reason I can't make it run on the site but will post it there for easier access.
Hope I made it clear. Any help would be much appreciated!
You are pushing the current content of text box into the array on every change/keystroke. Instead what you should do is text box 1 should only modify the first index in your array. And text box 2 should only modify second field in your array and so on. On each change, replace entire content with new content.
Or a cleaner approach would be to store a teams object. And send a team number field too in the on change handler against which you can store the team name.
<input className="form-control" type="text" ref="teamName"
onChange={this.handleChange.bind(null, 'team1')} /> // pass any index or string instead of team1
...
handleChange(teamIndex, teamName) {
let { teams } = this.state;
teams[teamIndex] = teamName;
this.setState({teams: teams};
}

Angular Select NgOptions double selecting when directive compiles

I am working on a dynamic form that populates a dropdown conditionally based on another input. I have written a directive because the data that comes back will also carry validation rules that need to be applied. However when i apply the validation rules to the dropdown and recompile the select options are borked. The final HTML looks like this:
The questions on the form can depend on another to be answered in a very specific way before they appear. This dropdown for example depends on the country selected but can be required or optional depending on what country is selected. The data coming back from my server gives me a validation object that contains validation information for the input field such as:
var question = scope.question;
var input = element.find('select');
if (question.validation.required) {
if (!input.attr('required')) {
input.attr('required', question.validation.required);
}
}
$compile(input)(scope);
The standard <option value="?" selected="selected"></option> is put in but when the question the dropdown depends on triggers the watch and a request happens for the dropdown the server returns and the backing select values are changed but the HTML output results as seen above all the items that are set to selected are unselectable and the form validation fails.
function answerMatch(countryCode) {
sectionService.getDivisionsByCountryCode(countryCode).then(function (response) {
scope.question.selectValues = response.data;
element.show();
});
}
and an HTML snippet for good measure
<select id="question{{question.questionId}}" name="answer" ng-model="question.value" ng-options="value.text for value in question.selectValues" class="form-control">
</select>

WordPress - Custom Form for custom post types in back-end

I am creating an eSports website and I want to create a bracket generator for each tournament. What I essentialy want to achieve is a custom form for each of the tournaments (post types). In that form I want to have an ability to choose how many rounds should this tournament have and be able to assign teams to any of the parts of the bracket.
I thought about doing this with custom fields but I doubt that they can be dynamic (for example, the amount of fields should increase if the tournament has more rounds than by default). They should also be simple to use for my client, so he shouldn't have to add custom fields manualy.
I decided to create a meta box with a form inside of it:
function add_meta_boxes() {
add_meta_box('peterworks-tournament-bracket', 'Peterworks Tournament Bracket', 'pworks_bracket', 'tournaments', 'side');
}
function pworks_bracket() {
?>
<form method="POST">
<input type="text" name="test_it" value="test" />
</form>
<?php
}
Then I tested if data from that form is reachable inside the wp_insert_post_data filter. It is:
function modify_post_title( $data , $postarr )
{
$data['post_title'] = $_POST['test_it'];
return $data;
}
This succesfully changes the title of a post to the value of that form's input. It means that I can create a custom form and make it dynamic with JavaScript.
My question is - is this approach correct? What are the potential problems I might be facing using this technique? Is there a better/easier way to do this?

Use #Html.ValidationMessageFor or other validation (custom messages) on pure html elements in MVC

Because I use a plugin called select2, I need to define the select lists in my application in pure Html (so without any helpers) like so:
<select name="TopicIds" id="topDrop" multiple style="width: 700px" required>
#foreach (var top in ((List<Topic>)ViewBag.TopIds).Where(top => top.MainTopic == null))
{
<option value="#top.TopicId" class="optionGroup">#top.Name</option>
foreach (var subTopic in top.SubTopics)
{
<option value="#subTopic.TopicId" class="optionChild">#subTopic.Name</option>
}
}
</select>
As you can see 1 element needs to be chosen, that's why I set the "required" attribute.
The validation happens, when the form submits it doesn't go through when nothing is selected in the list. I would like to set a custom error message though when the validation for the field happens.
Normally you would use the helper #html.ValidationMessageFor(), but that doesn't seem to be working with this pure html control. You can see the select list is binded to the property "TopicIds" in my ViewModel.
I tried this: #Html.ValidationMessageFor(model => model.TopicIds), the only message I get is the default "This field is required", strangely enough only when this helper is defined...
How can I customize this message? I've been seraching for a while and tried all kinds of solutions with JavaScript and such, but nothing seems to change the message, I always get "This field is required.".
Anyone know how to do this? I'm using all this in an ASP.NET MVC 4 web application.
Annotate the property in your ViewModel
[Required(ErrorMessage = "My Custom Message")]
public string Id {get;set;}
Then you Html.ValidationMessageFor

Categories

Resources