PrettyFaces: #URLQueryParameter is not passed to #URLAction method - prettyfaces

I can't figure out how to pass a parameter from an URL to a specified controller method.
So here is how I annotated the controller:
#Component
#ManagedBean
#RequestScoped
#URLMappings(mappings={
#URLMapping(id = "posts", pattern = "/posts/", viewId = "/faces/posts/list.xhtml"),
#URLMapping(id = "postComments", pattern = "/posts/#{id}/comments", viewId = "/faces/posts/post_comments.xhtml")
})
public class PostsController {
#Autowired
private PostService postService;
private Post post;
#URLQueryParameter("id")
private String id;
public Post getPost() {
return postService.findById(Long.valueOf(getId()));
}
#URLAction(mappingId = "postsComments")
public void loadPost() {
System.out.println("in loadPost, ID: " + getId());
}
}
And here is the view:
<ui:repeat value="#{postsController.posts}" var="post">
<tr>
<td>#{post.title}</td>
<td>
<pretty:link mappingId="postComments">
<f:param value="#{post.id}" />
Comments
</pretty:link>
</td>
<td>Edit</td>
<td>Delete</td>
</tr>
</ui:repeat>
And my id is always null. Nevertheless, in the generated HTML code the id is always correct:
posts/1/comments
posts/2/comments
posts/3/comments
etc.
Any idea? I'm using PrettuFaces 3.3.3.
Thank you.

You could get your id parameter in the getPost() method with :
FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id")

Related

How to display foreign key name in list table in Blazor Client Side

I am trying to display a subject name for a course where I saved the subject from a database driven dropdown list in a client-side Blazor app. The value returns as a Guid instead of the subject name. Has anyone accomplished this with Blazor? I couldn't find anything in the Blazor documentation or any tutorials that could solve the issue I'm having. This is in Blazor client-side and I am using Entity Framework Core
This is what my Course model looks like in the Shared project:
public class Course
{
public Guid CourseID { get; set; }
[Required]
public string CourseCode { get; set; }
[Required]
public string CourseName { get; set; }
public string CourseSubject { get; set; }
public string CourseCredits { get; set; }
}
This is what my Subject model looks like in the Shared project:
public class Subject
{
public Guid SubjectID { get; set; }
public string SubjectName { get; set; }
}
This is my CourseData Data Access Model in the Server project:
ApplicationDbContext db = new ApplicationDbContext ();
public IEnumerable<Course> GetAllCourses()
{
try
{
return db.Courses.ToList();
}
catch
{
throw;
}
}
public void AddCourse(Course course)
{
try
{
db.Courses.Add(course);
db.SaveChanges();
}
catch
{
throw;
}
}
This is my SubjectData Data Access Model in the Server project:
ApplicationDbContext db = new ApplicationDbContext ();
public IEnumerable<Subject> GetAllSubjects()
{
try
{
return db.Subjects.ToList();
}
catch
{
throw;
}
}
public void AddSubject(Subject subject)
{
try
{
db.Subjects.Add(subject);
db.SaveChanges();
}
catch
{
throw;
}
}
This is my Course Controller in the Server project:
CourseData objcourse = new CourseData();
[HttpGet]
[Route("api/Courses/Courses")]
public IEnumerable<Course> Index()
{
return objcourse.GetAllCourses();
}
[HttpPost]
[Route("api/Courses/Create")]
public void Create([FromBody] Course course)
{
if (ModelState.IsValid)
objcourse.AddCourse(course);
}
This is how I save the value in my Course creation page in my Client project:
#page "/Courses/Create"
#inject HttpClient Http
#inject Microsoft.AspNetCore.Components.NavigationManager NavigationManager
<h1>Add Course</h1>
<hr />
<div class="row">
<div class="col-md-4">
<div>
<div class="form-group">
<label for="CourseCode" class="control-label">Course Code</label>
<input for="CourseCode" class="form-control" #bind="#course.CourseCode" />
</div>
<div class="form-group">
<label for="CourseName" class="control-label">Course Name</label>
<input for="CourseName" class="form-control" #bind="#course.CourseName" />
</div>
<div class="form-group">
<label for="CourseSubject" class="control-label">Subject</label>
<select class="form-control" #bind="#course.CourseSubject">
<option></option>
#foreach (var subject in subjectList)
{
<option value="#subject.SubjectID">#subject.SubjectName</option>
}
</select>
</div>
<div class="form-group">
<label for="CourseCredits" class="control-label">Course Credits</label>
<input for="CourseCredits" class="form-control" #bind="#course.CourseCredits" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-default" #onclick="#CreateCourse">Save</button>
<button class="btn" #onclick="#cancel">Cancel</button>
</div>
</div>
</div>
</div>
#functions {
List<Subject> subjectList = new List<Subject>();
Course course = new Course();
protected override async Task OnInitializedAsync()
{
subjectList = await Http.GetJsonAsync<List<Subject>>("api/Subjects/Subjects");
}
protected async Task CreateCourse()
{
await Http.SendJsonAsync(HttpMethod.Post, "/api/Courses/Create", course);
NavigationManager.NavigateTo("/Courses/Courses");
}
void cancel()
{
NavigationManager.NavigateTo("/Courses/Courses");
}
}
And finally this is my Courses list page in my Client project where it returns the Guid for the subject name, for which I would like to show the subject name instead of it's Guid:
#page "/Courses/Courses"
#inject HttpClient Http
<h1>Courses</h1>
<p>
Create New
</p>
#if (courseList == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class='table'>
<thead>
<tr>
<th>Course Code</th>
<th>Course Name</th>
<th>Subject</th>
<th>Credits</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
#foreach (var course in courseList)
{
<tr>
<td>#course.CourseCode</td>
<td>#course.CourseName</td>
<td>#course.CourseSubject</td>
<td>#course.CourseCredits</td>
<td>
<a href='/Courses/Edit/#course.CourseID'>Edit</a> |
<a href='/Courses/Delete/#course.CourseID'>Delete</a>
</td>
</tr>
}
</tbody>
</table>
}
#functions {
Course[] courseList;
protected override async Task OnInitializedAsync()
{
courseList = await Http.GetJsonAsync<Course[]>
("/api/Courses/Courses");
}
}
Database Context as requested:
public class ApplicationDbContext : DbContext
{
public virtual DbSet<Course> Courses { get; set; }
public virtual DbSet<Subject> Subjects { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer(#"REMOVED-FOR-SECURITY");
}
}
}
Help would be much appreciated.
Other answers are good but let me give you something else to think about...
When writing Blazor apps try to think in terms of components more often than of code.
For example, let's say that the Subjects are static data that doesn't change a lot. So if every time you show a list, or want to build a dropdown for them, you're potentially going to have to make a database call or a SQL JOIN? So my first thought would be to create a lookup cache for GUID-to-Subject-name. And since this is Blazor if it's cached on the client you no longer need to make a database or API call - it's loaded once.
Then, since we're in Blazor, I'd create a <SubjectName> component, e.g.
Subject: <SubjectName Id="#Model.SubjectId" />
The component uses the cache to get the value, it can handle a null value, it can handle an invalid subject ID. You've encapsulated a lot of behaviour and error handling in a single place, and can re-use that every time you need to map an ID to a subject name.
Similarly I'd create a <SubjectDropdown> component to show a list of subjects, again using the cache.
You set CourseSubject with the SubjectID with is a Guid, so you get a Guid.
If you want to display the subject name either, request the subject by its Guid, or return the Subject in your course:
public class Course
{
public Guid CourseID { get; set; }
[Required]
public string CourseCode { get; set; }
[Required]
public string CourseName { get; set; }
public string CourseSubject { get; set; }
public string CourseCredits { get; set; }
public virtual Subject Subject { get; set; }
}
public IEnumerable<Course> GetAllCourses()
{
try
{
return db.Courses
.Include(c => c.Subject)
.ToList();
}
catch
{
throw;
}
...
}
#foreach (var course in courseList)
{
<tr>
<td>#course.CourseCode</td>
<td>#course.CourseName</td>
<td>#course.Subject.SubjectName</td>
<td>#course.CourseCredits</td>
<td>
<a href='/Courses/Edit/#course.CourseID'>Edit</a> |
<a href='/Courses/Delete/#course.CourseID'>Delete</a>
</td>
</tr>
}

Why does my nested POJO return null from a form in Play! 1.x

In Play! Framework 1.5.1, why am I getting null back for thingy.Owner ? Shouldn't the automatic binding take care of this?
User class
package models;
#Entity
#Table(name="objtest_user")
public class User extends Model
{
#Required
public String username;
#Password
#Required
public String password;
public String fullname;
public User(String username, String password, String fullname)
{
this.username = username;
this.password = password;
this.fullname = fullname;
}
#Override
public String toString()
{
return this.fullname;
}
}
and this Thingy class that references the User class
package models;
import java.util.*;
import javax.persistence.*;
import play.db.jpa.*;
import play.data.validation.*;
#Entity
public class Thingy extends Model
{
#Required
public String Name;
#ManyToOne
public User Owner;
public Thingy(String name, User owner)
{
this.Name = name;
this.Owner = owner;
}
#Override
public String toString()
{
return Name;
}
}
and this Template form
#{extends 'main.html' /}
#{set title:'Home' /}
<p>Current user = ${currentUser}</p>
#{form #saveThingy(), id:'saveThingy'}
<input type="text" id="thingy.Name" name="thingy.Name"/>
<input type="hidden" id="thingy.Owner" name="thingy.Owner" value="${currentUser}"/>
<input type="submit" id="Save" value="Save"/>
#{/form}
Controller method
public static void saveThingy(Thingy thingy)
{
System.out.println("Name = " + thingy.Name);
System.out.println("Owner = " + thingy.Owner);
thingy.save();
}
Try changing the following line
<input type="hidden" id="thingy.Owner" name="thingy.Owner" value="${currentUser}"/>
To
<input type="hidden" id="thingy.Owner" name="thingy.Owner.id" value="${currentUser.id}"/>
If you check out the docs (https://www.playframework.com/documentation/1.2.x/controllers#params), and look for JPA object binding section, it talks about requiring sub objects to have an id. Play when it finds an ID for an object, it will load the relavent entity via JPA/Hibernate.

model class is not working in laravel project

i am beginner in la-ravel,problem in work on model how be work on project.
firstly used the api.php to link the page
Route::any('/user',['uses'=>'PagesController#my']);
create the controller
public function my(Request $request){
$val=validator::make($request->all(),[
'id'=>'required',
'name'=>'required',
'email'=>'required',
'mobile'=>'required'
]);
//return 'rahul';
return response()->json([$val]);
}
model is link to the controller
use App\rahul;
use Validator;
create the model page design
class rahul extends Model{
protected $table = "display";
public function my($data)
{
$save = new rahul;
$save->id = $data['id'];
$save->name = $data['name'];
$save->email = $data['email'];
$save->mobile = $data['mobile'];
$save->save();
return $save->id;
}
}
and,last step will done it create the database like
enter image description here
database name is lara2 and table name display simple page design
but problem how to model be used
Route::get('first', 'ApiController#first')->name('first');
Route::post('store', 'ApiController#store')->name('store');
using the code in api.php
and next step model is create
php artisan make: model Article
model page
class Article extends Model{ protected $fillable = ['name', 'email'];}
next step create the controller
controller page (apicontroller)
public function first(){
return view('first');
}
public function store(Request $request)
{
$article = Article::create($request->all());
return response()->json($article, 201);
}
blade page web page design
<form method="POST" action="store">
{{csrf_field()}}
<input type="text" name="name">
<input type="email" name="email">
<input type="submit" name="submit"></form>
migration is create Article table name connection
public function up()
{
Schema::create('Articles', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('Articles');
}

Doctrine with ZF2 Annotation: how to clear a multi select field?

I've got a problem with my multi select fields. Here is the code:
In the Entity class
/**
* #Annotation\Options({ "disable_inarray_validator":"true", "label":"Bound Checkpoints", "target_class":"Checkpoint","property":"name"})
* #Annotation\Type("DoctrineORMModule\Form\Element\EntitySelect")
* #Annotation\Attributes({ "multiple":"true", "class":"form-control"})
* #Annotation\Required(false)
* #ORM\ManyToMany(targetEntity="Checkpoint", inversedBy="affectedByCheckpoints")
*/
private $boundCheckpoints;
public function __construct() {
$this->boundCheckpoints= new \Doctrine\Common\Collections\ArrayCollection();
}
public function addBoundCheckpoints( $items)
{
foreach($items as $item)
{
$this->boundCheckpoints->add($item);
}
}
public function removeBoundCheckpoints($items)
{
foreach($items as $item)
{
$this->boundCheckpoints->removeElement($item);
}
}
My issue is: if I set some stuff into the field, it save it well. If I remove one, still working. But if I remove all items I set and fire the form, the removeBoundCheckpoints method is never called.
I tried to set a required validator to the form, but If I do that, I've got a validation issue.
Any ideas ?
solved by adding this workaround into the template.
{% if field.getAttribute('multiple') == 'multiple' or field.getAttribute('multiple') == 'true' %}
<input type="hidden" name="{{field.getName()}}" value="" />
{% endif %}
{{formElement(field) }}

CheckBoxList multiple selections: how to model bind back and get all selections?

This code:
Html.CheckBoxList(ViewData.TemplateInfo.HtmlFieldPrefix, myList)
Produces this mark-up:
<ul><li><input name="Header.h_dist_cd" type="checkbox" value="BD" />
<span>BD - Dist BD Name</span></li>
<li><input name="Header.h_dist_cd" type="checkbox" value="SS" />
<span>SS - Dist SS Name</span></li>
<li><input name="Header.h_dist_cd" type="checkbox" value="DS" />
<span>DS - Dist DS Name</span></li>
<li><input name="Header.h_dist_cd" type="checkbox" value="SW" />
<span>SW - Dist SW Name </span></li>
</ul>
You can check multiple selections. The return string parameter Header.h_dist_cd only contains the first value selected. What do I need to do to get the other checked values?
The post method parameter looks like this:
public ActionResult Edit(Header header)
I'm assuming that Html.CheckBoxList is your extension and that's markup that you generated.
Based on what you're showing, two things to check:
The model binder is going to look for an object named Header with string property h_dist_cd to bind to. Your action method looks like Header is the root view model and not a child object of your model.
I don't know how you are handling the case where the checkboxes are cleared. The normal trick is to render a hidden field with the same name.
Also a nit, but you want to use 'label for="..."' so they can click the text to check/uncheck and for accessibility.
I've found that using extensions for this problem is error prone. You might want to consider a child view model instead. It fits in better with the EditorFor template system of MVC2.
Here's an example from our system...
In the view model, embed a reusable child model...
[AtLeastOneRequired(ErrorMessage = "(required)")]
public MultiSelectModel Cofamilies { get; set; }
You can initialize it with a standard list of SelectListItem...
MyViewModel(...)
{
List<SelectListItem> initialSelections = ...from controller or domain layer...;
Cofamilies = new MultiSelectModel(initialSelections);
...
The MultiSelectModel child model. Note the setter override on Value...
public class MultiSelectModel : ICountable
{
public MultiSelectModel(IEnumerable<SelectListItem> items)
{
Items = new List<SelectListItem>(items);
_value = new List<string>(Items.Count);
}
public int Count { get { return Items.Count(x => x.Selected); } }
public List<SelectListItem> Items { get; private set; }
private void _Select()
{
for (int i = 0; i < Items.Count; i++)
Items[i].Selected = Value[i] != "false";
}
public List<SelectListItem> SelectedItems
{
get { return Items.Where(x => x.Selected).ToList(); }
}
private void _SetSelectedValues(IEnumerable<string> values)
{
foreach (var item in Items)
{
var tmp = item;
item.Selected = values.Any(x => x == tmp.Value);
}
}
public List<string> SelectedValues
{
get { return SelectedItems.Select(x => x.Value).ToList(); }
set { _SetSelectedValues(value); }
}
public List<string> Value
{
get { return _value; }
set { _value = value; _Select(); }
}
private List<string> _value;
}
Now you can place your editor template in Views/Shared/MultiSelectModel.ascx...
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<WebUI.Cofamilies.Models.Shared.MultiSelectModel>" %>
<div class="set">
<%=Html.LabelFor(model => model)%>
<ul>
<% for (int i = 0; i < Model.Items.Count; i++)
{
var item = Model.Items[i];
string name = ViewData.ModelMetadata.PropertyName + ".Value[" + i + "]";
string id = ViewData.ModelMetadata.PropertyName + "_Value[" + i + "]";
string selected = item.Selected ? "checked=\"checked\"" : "";
%>
<li>
<input type="checkbox" name="<%= name %>" id="<%= id %>" <%= selected %> value="true" />
<label for="<%= id %>"><%= item.Text %></label>
<input type="hidden" name="<%= name %>" value="false" />
</li>
<% } %>
</ul>
<%= Html.ValidationMessageFor(model => model) %>
Two advantages to this approach:
You don't have to treat the list of items separate from the selection value. You can put attributes on the single property (e.g., AtLeastOneRequired is a custom attribute in our system)
you separate model and view (editor template). We have a horizontal and a vertical layout of checkboxes for example. You could also render "multiple selection" as two listboxes with back and forth buttons, multi-select list box, etc.
I think what you need is how gather selected values from CheckBoxList that user selected and here is my solution for that:
1- Download Jquery.json.js and add it to your view as reference:
2- I've added a ".cssMyClass" to all checkboxlist items so I grab the values by their css class:
<script type="text/javascript" >
$(document).ready(function () {
$("#btnSubmit").click(sendValues);
});
function populateValues()
{
var data = new Array();
$('.myCssClas').each(function () {
if ($(this).attr('checked')) {
var x = $(this).attr("value");
data.push(x);
}
});
return data;
}
function sendValues() {
var data = populateValues();
$.ajax({
type: 'POST',
url: '#Url.Content("~/Home/Save")',
data: $.json.encode(data),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function () { alert("1"); }
});
}
</script>
3- As you can see I've added all selected values to an Array and I've passed it to "Save" action of "Home" controller by ajax 4- in Controller you can receive the values by adding an array as argument:
[HttpPost]
public ActionResult Save(int[] val)
{
I've searched too much but apparently this is the only solution. Please let me know if you find a better solution for it.
when you have multiple items with the same name you will get their values separated with coma