I have a list shown in my view which is populated from my database and it uses pagination. Works fine so far. What I want to do now is to give the user the possibility to jump to a specific page via input into a text field.
My controller method would look like this, as my imagination goes:
#Controller
public class OrderController {
private static final int INITIAL_PAGE_SIZE = 15;
private int currentPage = 1;
#Autowired
private OrderService service;
#GetMapping("/dispo/orderViewList/{pageNumber}")
private String showSpecifiedPage(#RequestParam("pageNumber") Integer page, Model model) {
Page<LoadOrders> pagedList = service.findAll(page -1, INITIAL_PAGE_SIZE);
List<LoadOrder> orderList = service.createLoadOrderPage(pagedList);
model.addAttribute("page", orderList);
model.addAttribute("currentPage", page);
model.addAttribute("totalPages", pagedList.getTotalPages());
return "/dispo/orderViewList";
}
My idea is now since I have a model attribute named "page" to change this attribute to the page number I'd like to show and send this as a get request to the controller method. And this is the code for the view:
<form action="#" th:action="#{/dispo/orderViewList/{page}}" method="get">
Direkt zu Seite: <input type="text" th:field ="*{page}" size ="4"> <input type="submit">
</form>
The result is just what I wanted and looks like this:
But the controller is never called. In fact the controller for the standard list is called:
#GetMapping("/dispo/orderViewList")
private String showOrderList(#RequestParam("page") Optional<Integer> page, Model model) {
page.ifPresent(p -> currentPage = p);
Page<LoadOrders> pagedList = service.findAll(currentPage - 1, INITIAL_PAGE_SIZE);
List<LoadOrder> orderList = service.createLoadOrderPage(pagedList);
model.addAttribute("page", orderList);
model.addAttribute("currentPage", currentPage);
model.addAttribute("totalPages", pagedList.getTotalPages());
return "/dispo/orderViewList";
}
So what can I do to tell the controller to use the method with the page parameter?
Related
I have an integer field and when i enter a non integer value (let's say a symbolic one) the Feedback panel should be triggered automatically with default message, but it does not work, I have to call it in onError method of the form by method error().
This is the textField, that i use:
RequiredTextField<Integer> intField =
new RequiredTextField<>("intValue", integerValue,Integer.class);
this is my simple FeedBackPanel:
fragment.add(new FeedbackPanel("feedback"));
it works only when i call method error() in method onError() of the form.
Could you show us how you create your Form and the Model you use? As far as I understand it you will want to bind a Model to your Fields. My best guess is that your Model does not have a property "intValue".
You might want to (re)visit the Wicket Wiki "More on Models".
I'm not sure how you are setting your model. And once you add RequiredTextField it will not allow you empty and since you set the Integer type it will not allow characters to be entered.
I have tried some code snippet which is working perfectly and validating.
HomePage.html
<html xmlns:wicket="http://wicket.apache.org">
<body>
<form wicket:id="someForm">
<div wicket:id="feedback"></div>
<input type="text" wicket:id="requiredText">
<input type="submit" value="submit">
</form>
</body>
</html>
HomePage.Java
public class HomePage extends WebPage {
private static final long serialVersionUID = 1L;
public HomePage(final PageParameters parameters) {
super(parameters);
Form form = new Form("someForm");
form.add(new FeedbackPanel("feedback"));
IModel integerValue= Model.of("");
form.add(new RequiredTextField("requiredText",integerValue,Integer.class));
add(form);
}
}
Please let me get back to me on this incase if you need anything .
that's my code:
<listbox id="boxFirma" multiple="true"
visible="#load(vm.opzioneSelezionata eq 'firma' ? 'true' : 'false')"
checkmark="true" width="400px" height="200px"
model="#bind(vm.opzioniFirma)"
selectedItems="#bind(vm.pickedItemSet)">
<template name="model" var="item"
status="s">
<listitem selected="#bind(item.preSelected)">
<listcell label="#bind(item.valore)" />
</listitem>
</template>
</listbox> <button label="Salva" style="margin-top:10px" disabled="#load(empty vm.pickedUser)"
onClick="#command('salvaPersonalizzazioneUtente')" />
The problem is when I push the button Salva, I get on the vm.pickedItemSet only the item that the user has just chosen, but nothing about the preselected items -> 'listitem selected="#bind(item.preSelected)" ' . So if there were 2 items preselected and one clicked by the user on the view model, I get just the one clicked, whereas I want all three. How do I fix this?
I think that your problem is behind the use of "preselected" property of your domain object. Without your View Model it's hard to understand what you are trying to achieve.
Hovewer, let me try to address you:
fill the set (pickedItemset) in the init method, and let zk handle that set.
remove " selected="#bind(item.preSelected)" " from you template. If you like
checkboxes, add "checkmark=true" as a listbox property
(http://books.zkoss.org/wiki/ZK_Component_Reference/Data/Listbox#Multiple_Selection).
As an example, try this View Model ( "SignOption" is a bean with a single member valore). The "Salva" button will print out the set of selected list items.
// a bunch of imports
public class MultiSelectionVM {
private String opzioneSelezionata = "firma";
private Set<SignOption> opzioniFirma = new HashSet<SignOption>();
private Set<SignOption> pickedItemSet = new HashSet<SignOption>();
private boolean pickedUser = true;
#Init
public void init(){
SignOption opt1 = new SignOption();
opt1.setValore("opt1");
SignOption opt2 = new SignOption();
opt2.setValore("opt2");
SignOption opt3 = new SignOption();
opt3.setValore("opt3");
//Init list model
opzioniFirma.add(opt1);
opzioniFirma.add(opt2);
opzioniFirma.add(opt3);
//Init selected Items
pickedItemSet.add(opt2);
}
#Command
public void salvaPersonalizzazioneUtente(){
System.out.println(pickedItemSet);
}
//Getters and setter for all members
}
Hope this helps!
Problem:
In my application I have provide the user a selection screen for something in several places (that is, the same selection screen has to be used in several actions).
Solution:
I've come up with the following solution: pass the return action and controller to action which handles the entity selection.
Example:
Suppose that there are several places in the application where the user has to select an instance of SomeEntity, so I added the following action to that entity controller:
public class SomeEntityController : Controller
{
/* ... */
public ViewResult Select(string returnAction, string returnController)
{
var selectableEntities = ...;
return View(
new SelectionViewModel<SomeEntity>
{
Entities = selectableEntities,
ReturnAction = returnAction,
ReturnController = returnController,
});
}
}
In the view for that action (Views/SomeEntity/Select.aspx) I put something like this:
<table>
<tr>
<th>Select</th>
<th>SomeProperty<th>
</tr>
<% foreach (var entity in Model.Entities) { %>
<tr>
<td>
<%: Html.ActionLink("Select", Model.returnAction, Model.returnController, new { entityId = entity.id }) %>
</td>
<td><%: entity.SomeProperty %></td>
</tr>
<% } %>
</table>
Then, if I need the user to select a SomeEntity in other controller I can do this:
public class OtherController : Controller
{
public ActionResult SelectSomeEntity()
{
return RedirectoToAction("Select", "SomeEntity", new { returnAction = "ActionThatNeedsAnEntity", returnController = "Other" });
}
public ActionResult ActionThatNeedsAnEntity(int entityId)
{
// here I can use the selected entity
}
}
The last piece of code is just an example of how to use the SomeEntity selection action. Instead of the SelectSomeEntity action, there could be a more complex action which performs some checks to see if an entityId is already selected (e.g. stored in the session) and then decide whether to call SomeEntity/Select or not
Question:
The above works fine, but I’m new to ASP.Net MVC 2 so I don’t know if there is other (standard) solution for this.
Is this approach correct/neat? Have you solve this same situation differently?
I could be misunderstanding your problem, but I think that Partial Views would be the "standard" solution you're looking for.
Partial Views are just that, small views that can be inserted into other views. Things like entry forms or displays of data can be put into a partial view and added to the regular view. They greatly simplify code.
They're simple to make. When you go to make a regular view, just check the "partial view" box in the window (i. e. after right-clicking in the solution explorer and selecting the "add view" option). You can then throw this into any full view by using <%: Html.Partial("myPartialView") %>. You can easily pass a Model to the partial view as well by doing <%: Html.Partial("myPartialView", Model) %>
I have a masterpage on which i displays groups that user can access now i want to gets its selected value in many controllers for saving with the records. I want to know if it is possible in asp.net mvc 2 and if not then what is the way around for it
What you are trying is possible and there are different techniques to achieve it. The best approach would depend on how you are invoking your controller actions. Whether you are using normal hyperlinks, submitting standard <form> or using AJAX. So if you are using standard action links you could add some javascript which binds to the onclick event of each link and adds the selected value of the group. Example:
$(function() {
$('a').click(function() {
// everytime a link is clicked
// add the value of the selected group to the url
var selectedGroup = $('#IdOfYourDdl').val();
if (this.href.indexOf('?') > 0) {
window.location = this.href + '&selectedGroup=' + selectedGroup;
} else {
window.location = this.href + '?selectedGroup=' + selectedGroup;
}
// cancel the default action as it doesn't contain the selectedGroup
// parameter in the request
return false;
});
});
and in your controller action you could have this additional parameter:
public ActionResult Foo(string selectedGroup)
{
...
}
Another example is if you use AJAX you could setup a default data in the master page which will ensure that the value of the dropdown will be sent along each AJAX request you are performing:
$.ajaxSetup({
data: { selectedGroup: $('#IdOfYourDdl').val() }
});
Now whenever you send an AJAX request to your server:
$.get('/foo', { someParam: 'someValue' }, function(result) {
});
the following request will be sent: /foo?someParam=someValue&selectedGroup=123 so you will be able to fetch the value of the selected group back in the controller action.
I hope I understand your question since no code-example is supplied.
You can do this using a viewmodel on the page which contains your display groups. Another option is to get the value from the FormCollection when the page is posted.
For example:
public ActionResult MyAction(MyViewmodel viewModel)
{
//value from your viewmodel, strongtype
var value = viewModel.group;
}
OR
public ActionResult MyAction(FormCollection collection)
{
//value as a string
var value = collection.getValue("MyKey").AttemptedValue;
}
If this answer doesn't statisfy you then please be more clear in your question and i'll try to help you further.
As long as your drop down list is a descendant of the <form> that is submitted, it will be subjected to standard model binding, which means you can include it as a parameter on your action. Ensure the name attribute of the drop down list matches the name of the action parameter.
Final rendered HTML:
<form action="http://.../MyAction" method="post">
<select name="dropDownList">
<option value="a">Option A</option>
<option value="b">Option B</option>
...
</select>
...
</form>
Controller:
[HttpPost]
public ActionResult MyAction(string dropDownList, MyActionModel model)
{
// dropDownList = value attribute of selected <option>
...
}
Having multiple forms in one page, when i submit one of them, how can i tell wich one was submitted?
I thought about generating uniqe ids for each from, and saving them as hidden fields and to the user-session - while this is a solution, the problem with it is that there is no good place to remove old ids from the session.
Any better ideas how to solve this problem?
Thanks in advance!
First of all: have you considered sending the two forms to two different actions? That way you can handle each form separately in an action each. This should be the "best-pratice" if you're using the Zend MVC component.
The other option is to check for the value of the submit button which will be included in the request, e.g.
<input type="submit" name="save" value="form1" />
// in PHP:
// $_POST["save"] will contain "form1"
<input type="submit" name="save" value="form2" />
// in PHP:
// $_POST["save"] will contain "form2"
Be careful as the value-attribute will be rendered as the button's label.
So perhaps you want to distingush the forms by different submit-button names:
<input type="submit" name="save-form1" value="Submit" />
// in PHP:
// $_POST["save-form1"] will contain "Submit"
<input type="submit" name="save-form2" value="Submit" />
// in PHP:
// $_POST["save-form2"] will contain "Submit"
EDIT:
During the comment-dialog between the OP and myself the following seems to be a possible solution:
class My_Form_Base extends Zend_Form
{
private static $_instanceCounter = 0;
public function __construct($options = null)
{
parent:: __construct($options);
self::$_instanceCounter++;
$this->addElement('hidden', 'form-id',
sprintf('form-%s-instance-%d', $this->_getFormType(), self::$_instanceCounter);
}
protected _getFormType()
{
return get_class($this);
}
}
class My_Form_Type1 extends My_Form_Base
{
public function init()
{
// more form initialization
}
}
class My_Form_Type2 extends My_Form_Base
{
public function init()
{
// more form initialization
}
}
some errors in you code, shoudl be something like this:
class Application_Form_Idee_Base extends Zend_Form
{
private static $_instanceCounter = 0;
public function __construct($options = null)
{
parent::__construct($options);
self::$_instanceCounter++;
$this->addElement('hidden', 'form-id', array(
'value' => sprintf('form-%s-instance-%s', $this->_getFormType(), self::$_instanceCounter))
);
}
protected function _getFormType()
{
return get_class($this);
}
}