I need to add an attribute display-name to <td> with values as wicket id.
<tbody>
<tr wicket:id="result" class="bgalternate1">
<td wicket:id="values">
<span wicket:id="value">Value</span>
</td>
</tr>
</tbody>
Expected result is
<tbody>
<tr class="bgalternate1">
<td display-name="<attribute_name>"> <!--attribute is column header -->
<span wicket:id="value">Value</span>
</td>
</tr>
</tbody>
I have tried using below java code, however unable to achieve the desired result, i.e unable to append the attribute "display-name" to <td>. I have initially used SimpleAttributeModifier as it is deprecated, used AttributeModifier.
public ReportResultPanel(final String id, final IModel<AdHocReportSetup> model)
{
super(id, model);
setOutputMarkupId(true);
final IModel<Paging> pagingModel = new Model<Paging>(new Paging());
resultModel = createResultModel(model, pagingModel);
addResults(this, "result", resultModel);
}
private ListView<AdHocReportResult> addResults(final MarkupContainer parent,
final String id,
final IModel<ReportResultModel> model)
{
final IModel<List<AdHocReportResult>> resultsModel = new PropertyModel<List<AdHocReportResult>>(model, "results");
final ListView<AdHocReportResult> result = new ListView<AdHocReportResult>(id, resultsModel) {
private static final long serialVersionUID = 1L;
#Override
protected void populateItem(final ListItem<AdHocReportResult> item)
{
addResultValues(item, "values", item.getModel());
AdHocPage.applyParityClass(item.getIndex(), item);
final Behavior behavior = AttributeModifier.append("display-name", "red");
for (final Component next : item)
{
next.add(behavior);
}
}
};
parent.add(result);
return result;
}
private ListView<AdHocReportResultAttribute> addResultValues(final
MarkupContainer parent, final String id,
final IModel<AdHocReportResult> model)
{
final IModel<List<AdHocReportResultAttribute>> attributesModel = new PropertyModel<List<AdHocReportResultAttribute>>(
model, "attributes");
final ListView<AdHocReportResultAttribute> result = new ListView<AdHocReportResultAttribute>(id, attributesModel) {
private static final long serialVersionUID = 1L;
#Override
protected void populateItem(final ListItem<AdHocReportResultAttribute> item)
{
addValueLabel(item, "value", item.getModel());
}
};
parent.add(result);
return result;
}
You are adding the AttributeModifier to the ListView but you really need to add it to its ListItems.
...
item.add(AttributeModifier.append("display-name", "red"));
addValueLabel(item, "value", item.getModel());
...
Related
I am a newbie at Spring and I am writing a rental system for movies. I have a Controller where I can get a list of all movies which are still rented (marked by digit "1" as a status in my Database) and which are already have been returned(marked as "0").
Now currently, when I call the page I see all the rented movies with the current status "1" or "0" as well as already returned movies which can still be returned and have a checkbox (which shouldn't be possible.
My question is, how can I change the HTML in the following way:
The status "1" or "0" changes to "rented" and "returned"
I want to remove the checkbox on all movies which already have been returned.
My code:
#Controller
public class MovieController {
#Autowired
private MovieService movieService;
#GetMapping("/home")
public String home(Model model) {
return "index";
}
#GetMapping("/movieList")
public String listAllMovies(Model model) {
model.addAttribute("listMovies", movieService.findNotRented());
return "movies";
}
#GetMapping("/search")
public String findByOption(Model model, #RequestParam(value = "search") String search,
#RequestParam("options") String options) {
if (options.equals("movie")) {
model.addAttribute("listMovies", movieService.findByName(search));
} else if (options.equals("actor")) {
model.addAttribute("listMovies", movieService.findMovieByActor(search));
} else if (options.equals("genre")) {
model.addAttribute("listMovies", movieService.findMovieByGenre(search));
}
return "movies";
}
#GetMapping("/rentedList")
public String findRentedMovies(Model model) {
model.addAttribute("listMovies", movieService.findRentedMovies());
return "rented";
}
#GetMapping("/rentMovie")
public String rentMovie(Model model, #RequestParam int id) {
model.addAttribute("listMovies", movieService.rentMovie(id));
return "index";
}
#GetMapping("/deleteRentedMovie")
public String deleterentedMovie(Model model, #RequestParam int id) {
model.addAttribute("listMovies", movieService.deleteRentedMovie(id));
return "index";
}
#GetMapping("/rentMovie2")
public String rentMovie2(Model model, #RequestParam("idChecked") List<Integer> id) {
if (id != null) {
for (Integer idInt : id) {
model.addAttribute("listMovies", movieService.rentMovie(idInt));
}
}
return "index";
}
#GetMapping("/deleteRentedMovie2")
public String deleterentedMovie(Model model, #RequestParam("idChecked") List<Integer> id) {
if (id != null) {
for (Integer idInt : id) {
model.addAttribute("listMovies", movieService.deleteRentedMovie(idInt));
}
}
return "index";
}
}
Thymeleaf
<h1>Movie List</h1>
<form action="/deleteRentedMovie2">
<table>
<tr>
<th>Title</th>
<th>Time rented</th>
<th>Status</th>
<th>Select</th>
</tr>
<tr th:each="movie : ${listMovies}">
<td th:text="${movie.title}"></td>
<td th:text="${movie.date}"></td>
<td th:text="${movie.status}"></td>
<td><input type="checkbox" th:name="idChecked" th:value="${movie.id}"></td>
</tr>
</table>
<input type="submit" value="Return Movie">
</form>
Thank you in advance and sorry for my bad English
For the status I would something like:
<td>
<span th:if="${movie.status == 1}">rented</span>
<span th:if="${movie.status == 0}">returned</span>
</td>
You could also use the Elvis operator but it is maybe less readable.
For the checkbox:
<td><input th:unless="${movie.status == 0}" type="checkbox" th:name="idChecked" th:value="${movie.id}"></td>
I want to use a LazyDataModel List inside a SelectOneMenu, but the selectoneMenu doesn't show anything . this is my code
public void show() {
beneficiaries = new LazyDataModel<Fournisseur>() {
private static final long serialVersionUID = 1L;
private List<Fournisseur> list;
#Override
public List<Fournisseur> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters){
list = service.getAll((String)filters.get("benef.intitule"),first, pageSize);
this.setRowCount(service.count((String)filters.get("benef.intitule")));
return list;
}
#Override
public Object getRowKey(Fournisseur obj) {
return obj.getCpt();
}
#Override
public Fournisseur getRowData(String rowKey) {
Fournisseur o=null;
if(rowKey != null) {
for (Fournisseur obj : list) {
if(rowKey == obj.getCpt()) {
o = obj;
}
}
return o;
}else {
return null;
}
}
};
}
this is my html code
<p:selectOneMenu id="beneficiary" value="#
{documentController.doc.beneficiary}" converter="#
{beneficiaryConverter}" panelStyle="width:160px" required="true" >
<f:selectItem itemLabel="Selectionner" itemValue="" />
<f:selectItems value="#{beneficiaryController.beneficiaries}"
var="beneficiary" itemLabel="#{beneficiary.intitule}" itemValue="#
{beneficiary}" />
</p:selectOneMenu>
i've tested the list out side the selectOneMenu and it's work fine.
You are using PrimeFaces and want to allow the user to select one out of very many options. As Melloware mentioned, LazyDataModel is ment for use with DataTable or other components that support pagination this way ( e.g. DataGrid)
For your use case p:autoComplete seemes to be the best way to go.
dropdown="true" makes it look like a selectOneMenu, and you can limit the number of items show using maxResults="5".
<p:autoComplete dropdown="true" maxResults="5" value="#{autoCompleteView.txt6}"
completeMethod="#{autoCompleteView.completeText}" />
You'll need to write a custom autoComplete method that finds matches for given user search input:
public List<String> completeText(String query) {
List<String> results = new ArrayList<String>();
// fill the result matching the query from user input
return results;
}
If I remove the div tag from the source code below my application runs with no error. But it displays an empty cell (which is correct). I just want to hide this if the cells are empty.
Thymeleaf html
<div th:object="${AppPortModel.Status}" th:if="${AppPortModel.Status} == 'CRITICAL'">
<h3>
MONITORING
</h3>
<table id ="apCritTable">
<thead>
<tr>
<th> Status </th>
<th> HostName </th>
<th> Port Name</th>
<th> Port Listening Count </th>
</tr>
</thead>
<tbody>
<tr th:each="AppPortModel, iterStat : ${showap}" th:if="${AppPortModel.Status == 'CRITICAL'}">
<td th:text ="${AppPortModel.Status}"></td>
<td th:text="${AppPortModel.host}">${AppPortModel.host}</td>
<td th:text="${AppPortModel.portOwner}"></td>
<td th:text="${AppPortModel.count}"></td>
</tr>
</tbody>
</table>
</div>
AppPortModel
public class AppPortModel implements Comparable {
private String Status;
private String host;
private String portName;
private String plCount;
//getters and setters
#Override int compareTo(Object o) {
return //stuff
}
Controller
#Controller
public class IndexController {
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView getdata() throws IOException {
ModelAndView model = new ModelAndView("index");
model.addObject("showap", apList);
return model;
}
AppPortList
#Component
public class AppPortList {
#Value("#{'$APP_SERVERS_PORT}'.split('#!')}")
private String[] apServerArray;
#Value("#{'${APP_SERVER_MONITORING_LIST}'.split('#!')}")
private String[] appServerPortsList;
#PostConstruct
public List<AppPortModel> getAppPortList() {
final int MYTHREADS = 80;
ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
ApplicationPort.resetData();
try {
for (int z = 0; z < apServerArray.length; z++) {
String apServer = apServerArray[z];
String[] portListArray=appServerPortsList[z].split(",");
ApplicationPort apWorker = new ApplicationPort(apServer, portListArray);
executor.execute(apWorker);
}
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("ArrayIndexOutOfBoundsException in AppPortList");
}
finally {
executor.shutdown();
while (!executor.isTerminated()) {
}
logger.info("\nFinished all threads in App Port. ");
}
return ApplicationPort.getData();
}
Snippet of Class App
static List<AppPortModel> apData = new ArrayList<AppPortModel>();
public static List<AppPortModel> getData() {
return apData;
}
public static void setData(List<AppPortModel> apData) {
ApplicationPort.apData = apData;
}
public static void resetData(){
apData = new ArrayList<AppPortModel>();
}
public ApplicationPort(String apServer, String[] portListArray) {
this.apServer = apServer;
this.portListArray = portListArray;
}
This table will populate if AppPortModel.Status is CRITICAL. I am trying to hide this table if there is no values in this table. If I just have a regular div tag my code will run but I will have a awkward head and table row heads on my page with empty cells.
Attempt
I tried adding some th logic into my div tag, but I receive an null error.
<div th:object="${AppPortModel.Status}" th:if="${AppPortModel.Status == 'CRITICAL'}">
Attempt 2
<div th:if="${Status} == 'CRITICAL'">
This script would hide my div tag. Even if I have Status = to CRITICAL it would still hide the table.
You can check whether the list is empty using the following condition expression. Assuming the object showap is a List type,
<div th:if="${not #lists.isEmpty(showap)}">
--content--
</div>
Your h3 tag and table goes inside this div.
#lists is a thymeleaf utility class. Refer http://www.thymeleaf.org/apidocs/thymeleaf/2.0.2/org/thymeleaf/expression/Lists.html for more options. You can alternatively use size() method and check for list length.
Ok so after alot of research i have concluded that passing a data table to a view is a bad idea ,so how do i pass my data table to a Model and then be able to access each row and column in the view?Sorry i am new to MVC
I start with a simple SQL statement
StringBuilder sbSQL = new StringBuilder();
//// define a list of CustomerModel objects
DataSet tempDS = new DataSet();
//string xSQL = "SELECT PropertyAddress,PropertyTypeDesc,PropertyID FROM KDOR_vwPropertyGeneral ORDER BY PropertyAddress";
System.Data.SqlClient.SqlDataAdapter DbCmd = new System.Data.SqlClient.SqlDataAdapter();
string sqlWhereCont = " WHERE ";
sbSQL.Append("SELECT ");
sbSQL.Append("PropertyAddress As PropertyAddress,");
sbSQL.Append("PropertyTypeDesc As PropertyTypeDesc,");
sbSQL.Append("PropertyID as PropertyID");
sbSQL.Append(" FROM [KDOR_vwPropertyGeneral] ");
if (!string.IsNullOrEmpty(user.Address))
{
sbSQL.Append(sqlWhereCont + "(PropertyAddress) LIKE '" + user.Address + "%'");
sqlWhereCont = "AND ";
}
sbSQL.Append(" ORDER BY ");
sbSQL.Append(" PropertyAddress ");
string MyConnectionString = ConfigurationManager.ConnectionStrings["WLConnection"].ConnectionString;
System.Data.SqlClient.SqlConnection cnn = new System.Data.SqlClient.SqlConnection(MyConnectionString);
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sbSQL.ToString(), cnn);
cmd.CommandTimeout = 30000;
DbCmd.SelectCommand = cmd;
move the data to a DataSet and Data Table
DbCmd.Fill(tempDS, "ResultSet");
DataTable resultSet = tempDS.Tables["ResultSet"];
Add items to Model
var vm = new List<BedroomModel>();
foreach (DataRow dr in tempDS.Tables[0].Rows)
{
vm.Add(new BedroomModel {PropertyAdd = dr.ItemArray[0].ToString() });
vm.Add(new BedroomModel { PropertyDesc = dr.ItemArray[1].ToString() });
vm.Add(new BedroomModel { PropertyID = dr.ItemArray[2].ToString() });
}
Now how to i Access each Item and loop through them in a view? Cause i get an error here is a look at my view
#model DataBaseTest.Models.BedroomModel
#{
ViewBag.Title = "Result";
}
<h2>Result</h2>
#{
ViewBag.Title = "Result";
}
<table border ="1">
<thead>
#* <tr>
#foreach (var col in Model.Columns) {
<th>
#col.ColumnName
</th>
}
</tr>*#
<tr>
<th>Property Address</th>
<th>Property Description</th>
<th>Property ID</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.PropertyAdd)
{
<tr>
<td>#Model.PropertyAdd</td>
</tr>
}
</tbody>
Model
namespace DataBaseTest.Models
{
public class BedroomModel
{
public string Address { get; set; }
public string PropertyAdd { get; set; }
public string PropertyID { get; set; }
public string PropertyDesc { get; set; }
public IEnumerable<BedroomModel> BedroomModels { get; set; }
}
}
Again Sorry i am new to MVC
Any advice Would be Greatly Appreciated.
You are telling your view that it should look for a single BedroomModel object, when you actually want to pass it a List<BedroomModel> object.
#model List<DataBaseTest.Models.BedroomModel>
As a result, your Model property will be the list itself, so your foreach loop only needs to loop through the Model, not Model.BedroomModels.
#foreach (var item in Model)
{
<tr>
<td>#item.PropertyAdd</td>
<td>#item.PropertyDesc</td>
<td>#item.PropertyID</td>
</tr>
}
Because of this change, you can remove the BedroomModels property from your BedroomModel class.
public class BedroomModel
{
public string Address { get; set; }
public string PropertyAdd { get; set; }
public string PropertyID { get; set; }
public string PropertyDesc { get; set; }
}
That would fix your problem, but I also noticed that when populating your vm list, you are adding three items into the List, where you should only be adding one BedroomModel object. Your foreach loop should look like this:
var vm = new List<BedroomModel>();
foreach (DataRow dr in tempDS.Tables[0].Rows)
{
vm.Add(new BedroomModel
{
PropertyAdd = dr.ItemArray[0].ToString(),
PropertyDesc = dr.ItemArray[1].ToString(),
PropertyID = dr.ItemArray[2].ToString()
};
}
You must also make sure that you are sending the ViewModel into the View. Your Action should return:
return View(vm);
Add this to your view at the top.
#model DataBaseTest.Models.BedroomModel
This will make the view a strongly typed view. Meaning that it knows what model it will be using to display the data and what properties are available.
Then assign your collection in your controller method prior to your view rendering.
I edited this portion. I just now noticed that you were adding a new object for each property instead of assigning the properties to one object and then adding them. Then you will get a null reference.
public ActionResult MyView()
{
BedroomModel lModel = new BedroomModel();
lModel.BedroomModels = new List<BedroomModels>();
DataSet tempDS = CallToBLLOrDAL(); //Do what you need to do to get your data.
//Assign your values to the ViewModel (Aka lModel in this instance).
foreach (DataRow dr in tempDS.Tables[0].Rows)
{
//I am unsure exactly why you are calling ItemArray and adding a new Model for each column.
//Your way.
lModel.BedroomModels.Add(new BedroomModel { PropertyAdd = dr.ItemArray[0].ToString() });
lModel.BedroomModels.Add(new BedroomModel { PropertyDesc = dr.ItemArray[1].ToString() });
lModel.BedroomModels.Add(new BedroomModel { PropertyID = dr.ItemArray[2].ToString() });
//Try this
lModel.BedroomModels.Add(new BedroomModel { PropertyAdd = dr.ItemArray[0].ToString(), PropertyDesc = dr.ItemArray[1].ToString(), PropertyID = dr.ItemArray[2].ToString()});
}
return View(lModel);
}
Then in your view.
#foreach (BedroomModel lBedroomModel in Model.BedroomModels)
{
<td>
#lBedroomModel.PropertyAdd
</td>
}
Debugging tips.
You can set a break point in your view inside of your foreach. Drag your Model down to your watches. You should be able to see the population of your model and all of the values within the current scope.
I am unsure why the coloring is off on the view code snippet.
Let me know what you think.
Please set as answer if this helps.
i have this listView and textBox:
<table>
<tr><td>Reciver:<table><tr>
<asp:ListView ID="showRecivers" runat="server"><td><%# Eval("name")%></td> </asp:ListView>
</tr></table>
<asp:TextBox ID="reciver" runat="server" OnTextChanged="style_Recivers" AutoPostBack="true"></asp:TextBox>
</td></tr></table>
the list the listview is bound to:
public List<Reciver> recivers = new List<Reciver>();
and the function style_Recivers:
protected void style_Recivers(object sender, EventArgs e)
{
string[] separator = new string[] { "," };
string[] reciversArray = reciver.Text.ToString().Split(separator, StringSplitOptions.None);
reciversArray = reciversArray.Distinct().ToArray();
for (int i = 0; i < reciversArray.Length; i++)
{
recivers.Add(new Reciver(reciversArray[i]));
}
this.showRecivers.DataSource = recivers;
this.showRecivers.DataBind();
}
and class Reciver:
public class Reciver
{
public string name;
public Reciver(string name)
{
this.name = name;
}
public string getName()
{
return this.name;
}
public void setName(string name)
{
this.name = name;
}
}
what my idea is, that when a couple of names eneted to the textBox with a , saperator, the style_Reciver function is activated and each name is shown in the ListView right away.
but it doesnt work, it gives me the error
ASP.NET runtime error:code blocks are not supported in this context
and marks this line:
<asp:ListView ID="showRecivers" runat="server"><td><%# Eval("name")%></td> </asp:ListView>
for starter. probably more thing wont work but this is the first thing.
how can i fix it? Thanks for the help
EDIT:
it works after i added <ItemTemplate>
now it gives me a different bug:
Reciver' does not contain a property with the name 'name'
whhat is the problem now?
The List View content here should be wrapped into ItemTemplate:
<asp:ListView ID="showRecivers" runat="server">
<ItemTemplate>
<td><%# Eval("name")%></td>
</ItemTemplate>
</asp:ListView>
Update. Also there is a problem with your class declaration. Here is how it should be declared in C# conventional way:
public class Reciver
{
public string _name;
public Reciver(string name)
{
this.name = name;
}
public string name
{
get { return this._name; }
set { this._name = value; }
}
}