Thymeleaf bind a String field to a select box - string

#GetMapping("add")
public String addPart(Model model)
{
model.addAttribute("suppliers", this.partService.getSupplierNames());
model.addAttribute("part", new AddPartViewModel());
return "parts/parts-add";
}
This is my class
public class AddPartViewModel
{
private String name;
private double price;
private int quantity;
private String supplierName;
//PUBLIC GETERS AND SETTERS AND AN EMPTY CONSTRUCTOR
}
Thymeleaf syntax
<div class="form-group">
<label for="supplierName">Example select</label>
<select class="form-control" id="supplierName">
<option th:each="name : ${suppliers}" th:text="${name}" th:field="*{supplierName}"></option>
</select>
</div>
This is the only place where i get error on. The rest of the fragment works correctly, even if just remove the th:field tag the List<String> suppliers parces it self correctly in to the select box. Not i tried to put the th:field in the <select> tag as well, i.e
<select class="form-control" id="supplierName" th:field="*{supplierName}">
but still i get an error during parcing

th:field reffers to a form-backing bean's field, so make sure you've provided the proper bean in a <form> tag (using th:object attribute).
Regarding select: th:field should be provided in a <select> tag, like you've attempted to do. But you should provide also the proper th:value attribute in a <option> tag, so that any value could be assigned to the field.
Your form containing the problematic select should look like this:
<form th:object="${part}">
<div class="form-group">
<label for="supplierName">Example select</label>
<select class="form-control" th:field="*{supplierName}">
<option th:each="name : ${suppliers}" th:value="${name}" th:text="${name}"></option>
</select>
</div>
<!-- the rest of form's inputs and buttons -->
</form>

Related

XSRF token mismatch

Hi I am trying to handle a form submission via a custom controller in the admin section
This is my test controller
#Controller
#RequestMapping("/" + TempController.SECTION_KEY)
public class TempController extends AdminAbstractController {
protected static final String SECTION_KEY = "test2";
#RequestMapping(value = "", method = RequestMethod.GET)
public String test(HttpServletRequest request, HttpServletResponse response, Model model) throws Exception {
// This is expected by the modules/emptyContainer template, this is a custom template that gets included into the body
model.addAttribute("customView", "views/test2");
ShippingEntity shp=new ShippingEntity();
model.addAttribute("shipping",shp);
// ensure navigation gets set up correctly
setModelAttributes(model, SECTION_KEY);
// gets the scaffolding set up to display the template from the customView attribute above
return "modules/emptyContainer";
}
#RequestMapping(value = "", method = RequestMethod.POST)
public String testPost(HttpServletRequest request, HttpServletResponse response, Model model,#ModelAttribute ShippingEntity shp) throws Exception {
// This is expected by the modules/emptyContainer template, this is a custom template that gets included into the body
model.addAttribute("customView", "views/test2");
System.out.println(shp.getLink());
System.out.println(shp.getTrackingNumber());
model.addAttribute("shipping",shp);
// ensure navigation gets set up correctly
setModelAttributes(model, SECTION_KEY);
// gets the scaffolding set up to display the template from the customView attribute above
return "modules/emptyContainer";
}
}
And this is the view template :
<div class="row">
<div class="twelve columns">
<form action="#" th:action="#{/test2}" th:object="${shipping}" method="post">
<p>Id: <input type="text" th:field="*{trackingNumber}" /></p>
<p>Message: <input type="text" th:field="*{link}" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
</div>
</div>
The problem is that when I submit the values I get the error:
XSRF token mismatch (null). Session may be expired
I understand that this has to do with security issues however I can't find a way to make it work.
Any tips how to solve this?
Apparently it was simpler than I thought, maybe it will help someone in the future.
Just change <form> </form> to <blc:form></blc:form>

Angular 4 ngModel between components

I'm trying to filter my products by categoryId value.
Products are listing in product-component.
I have a categoryFilter pipe that filters Products and returns list of Product.
This pipe requires categoryId but this value is in category-component scope. So my product-component cannot access it. What should I do to make it work?
product-component.html
<ul class="list-group">
<li class="list-group-item" *ngFor="let product of products |productFilter:filterText|categoryFilter:filterCategory">
<button (click)="addToCart(product)" class="btn btn-sm btn-primary float-right">
<i class="fa fa-plus"></i>
add to cart
</button>
<h5>{{product.productName | uppercase}} ({{product.categoryId}})</h5>
<p>{{product.quantityPerUnit}}</p>
<h6>{{product.unitPrice | currency:'TRY':'₺'}} (KDV DAHİL: {{product.unitPrice |vatAdded:8 | currency:'TRY':'₺'}})</h6>
</li>
category-component.html
<select class="form-control" [(ngModel)]="filterCategory">
<option value="" selected="selected">-- Choose Category --</option>
<option *ngFor="let category of categoryList" value="
{{category.categoryId}}">{{category.categoryName}}</option>
</select>
category-filter.pipe.ts
import { Pipe, PipeTransform } from '#angular/core';
import { Product } from '../product/product';
#Pipe({
name: 'categoryFilter'
})
export class CategoryFilterPipe implements PipeTransform {
transform(value: Product[], filterCategory?: any): Product[] {
return filterCategory?
value.filter((p:Product)=>p.categoryId==filterCategory):value;
}
}
You may share data between two components that cannot communicate via Events by using services.
You can inject a service in the two components and access the required field from there. Changing the value of service's field will reflect in both the components.
Please take a look at the below demo to get some sort of idea on how to implement.
https://stackblitz.com/edit/angular-prge5p?file=src%2Fapp%2Fproduct.component.ts
Change the value of appService.category from category-component and it will automatically reflect in the product-component.

How to get data from a form dropdown select element?

I'm using Express.js and trying to get form data of a dropdown select element,
I tried with body-parser but what I get with eq.body.method_select is undefined.
I didn't find much info about how to do this on the web.
Here is my code html code:
<form action="url_analyse">
<div class="col-lg-6">
<div class="input-group">
<select class="custom-select mb-2 mr-sm-2 mb-sm-0" name="method_select" id="inlineFormCustomSelect">
<option value="5">Regular Search (Short)</option>
<option value="10">Intense Search (Long)</option>
<option value="20">Deep Search (Very Long)</option>
</select>
<input type="text" name="url_input" class="form-control" placeholder="Enter URL">
<span class="input-group-btn">
<button class="btn btn-secondary">Go!</button>
</span>
</div>
</div>
Here is my js code:
app.get('/url_analyse', function(req, res) {
console.log(req.body.method_select);
})
Hope you can help me with that.
Thank you.
There are two issues here:
You might want to explicitly add the leading forward slash: action="/url_analyse"
The default form submission HTTP method is GET, which means that form fields will be passed in the query string portion of the URL. This means you will instead need to access req.query to get at the form fields. You only need body-parser and req.body when you use POST and other methods (with the appropriate enctype) to submit your form.

Detect Input Focus Using Angular 2+

I'm trying to create an auto-complete list that appears as you type, but disappears when you click elsewhere on the document. How do I detect that a form input is focused using Angular 2. Angular 1 has ng-focus, but I don't think Angular 2 supports that anymore.
<input id="search-box" type="search" class="form-control [(ngModel)]=query (keyup)=filter()>
<div id="search-autocomplete" *ngIf="filteredList.length > 0">
<ul *ngFor="#item of filteredList" >
<li > <a (click)="select(item)">{{item}}</a> </li>
</ul>
</div>
By the way, I used this tutorial as guidance.
There are focus and blur events:
<input (blur)="onBlur()" (focus)="onFocus()">
For those using #angular/material, you can get a reference to the MatInput instance which implements MatFormFieldControl interface exposing a nice focused property.
<mat-form-field>
<input matInput #searchInput="matInput" type="text" />
<mat-icon matPrefix svgIcon="filter" [color]="searchInput.focused ? 'primary' : ''"></mat-icon>
</mat-form-field>
You could also use FocusMonitor from #angular/cdk.
https://material.angular.io/guide/creating-a-custom-form-field-control#focused
focused = false;
constructor(fb: FormBuilder, private fm: FocusMonitor, private elRef: ElementRef<HTMLElement>) {
...
fm.monitor(elRef.nativeElement, true).subscribe(origin => {
this.focused = !!origin;
this.stateChanges.next();
});
}
ngOnDestroy() {
...
this.fm.stopMonitoring(this.elRef.nativeElement);
}
You can use the ngControl directive to track change-state and validity of form fields.
<input type="text" ngControl="name" />
The NgControl directive updates the control with three classes that reflect the state.
State: Control has been visited
ng-touched
ng-untouched
State: Control's value has changed
ng-dirty
ng-pristine
State: Control's value is valid
ng- valid
ng- invalid

Adding more functions to helper classes in zend

Here is my helper class
class Zend_View_Helper_CommonArea extends Zend_View_Helper_Abstract {
public function commonArea()
{
?>
<div class="clear"></div>
<div id="quick_search">
<div class="search">
<strong>QUICK SEARCH </strong>
<input type="text" name="keyword" id="keyword" value="Enter keywords" class="form" onfocus="if(this.value==this.defaultValue)this.value='';" onblur="if(this.value=='')this.value=this.defaultValue;" />
<select name="select" id="select" class="selectstyled">
<option>Prefered Location</option>
<option>Prefered Location</option>
<option>Prefered Location</option>
<option>Prefered Location</option>
<option>Prefered Location</option>
</select>
</div>
<div class="bt_box">
<input name="find" type="submit" class="find" id="search" value="Find Jobs" />
</div>
<div class="resume"><img src="images/resume.jpg" alt="" /></div>
</div>
<?php
}
}
and My question is , I needed to add a new function to this class. I have tried by adding new function like
public function addBox()
{
?>
<div id="add_right_box"style="height:500px;"><h3 class="add_h2">Width 210px</h3></div>
<?php
}
to the above class, but I am getting eror something like
Plugin by name 'AddBox' was not found in the registry;
Here I need to know Can I add more functions to the helper class , if yes how is this possible.
First, you should return all output, not echo it directly.
From the Zend_View_Helper docs:
In general, the class should not echo or print or otherwise generate output. Instead, it should return values to be printed or echoed. The returned values should be escaped appropriately.
When you call $this->commonArea() from the view, it will load the 'CommonArea' class, and then call the matching method. So a call to $this->addBox() will look for the 'AddBox' class - it won't know that you expect it to be part of the 'CommonArea' plugin.
If you want to call multiple methods from the same plugin, have the matching method return an instance of the plugin:
public function commonArea(){
return $this;
}
Then call the methods like this:
$this->commonArea()->addBox();
$this->commonArea()->display(); //assuming you renamed the original method to 'display'
You could look at the navigation helper or the placeholder helper to see this pattern.

Resources