In my web page I have a text box in which user enters an item name that would be sent to server asynchronously, that message would be sent to CometActor then further it adds additional information to it and in the render method it tries to append a new row to existing table on the page asynchronously. Whenever I add an item always new row is getting placed on top of table rather than as table row, after that if I press refresh it is getting placed properly in the table. Here is
<table cellpadding="0" cellspacing="0" border="1" class="display" id="example">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Time</th>
</tr>
</thead>
<tbody class="lift:comet?type=ProvisionComet">
<tr id="tr_content">
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
LiftActor object
object ItemsServer extends LiftActor with ListenerManager {
private var items = Vector[Item]()
private lazy val date: Box[Date] = DependencyFactory.inject[Date] // inject the date
def createUpdate = items
override def lowPriority = {
case s: String => items :+= new Item(items.length + 1, s, date.map(_.toString)); updateListeners()
case _ => None
}
}
Comet Actor
class ItemComet extends CometActor with CometListener {
private var items = Vector[Item]()
def registerWith = ItemsServer
override def lowPriority = {
case v: Vector[Item] => items = v; reRender()
}
def render = "#tr_content *" #> {
items.map(i => {
<td>{i.sNum}</td>
<td>{i.itemName}</td>
<td>{i.updatedTime.toString}</td>
})
}
The result before refresh is
The result after refresh
How to get the correct result without refreshing?
render method is the place where I am adding rows
Try moving the class attribute from tbody to table:
<table class="lift:comet?type=ProvisionComet" cellpadding="0" cellspacing="0" border="1" class="display" id="example">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Time</th>
</tr>
</thead>
<tbody >
<tr id="tr_content">
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
Related
I have some tabular data with the headers ('Type', 'Name'). I would like to select all items in column 'name', to check if they contain a search string. Each item in that column has the role 'gridcell', and the description 'Name'. See attached image1.
getByRole('gridcell', {description: /name/i}) doesn't work. I've looked through the typescript declarations of the queries and nothing seems helpful. How can one accomplish this?
Use getAllByRole('cell', {description: /name/i}) to retrieve an array containing the cells in column Name.
Check the array contains a certain value using toContain(item).
https://jestjs.io/docs/expect#tocontainitem
An example (using React):
'App.js'
function App() {
return (
<div className='App'>
<table>
<thead>
<tr>
<td id='name'>Name</td>
</tr>
</thead>
<tbody>
<tr>
<td aria-describedby='name'>J Blogs</td>
</tr>
<tr>
<td aria-describedby='name'>J Doe</td>
</tr>
<tr>
<td aria-describedby='name'>J Hancock</td>
</tr>
</tbody>
</table>
</div>
);
}
export default App;
'App.test.js'
import { render, screen } from '#testing-library/react';
import App from './App';
test('retrieves all cells described by name', () => {
render(<App />);
const cells = screen.getAllByRole('cell', {description: /name/i});
const cellValues = cells.map(cell => cell.textContent);
expect(cellValues).toContain('J Doe');
});
I need to dynamically poplulate a table like this. The problem is, it is not a simple table. It has the "rowspan" characteristics.
For a single entry there are multiple fields entries which are being stored in separate rows.
This is a little tricky to populate with Wicket. Any help , advises, suggestions would be great.
This is what the table looks like on the HTML page:
https://jsfiddle.net/sayrandhri/4ktmy6cn/2/
<table>
<tr>
<th>Name</th>
<th>Role</th>
<th>Company</th>
<th>Request</th>
<th>Change</th>
</tr>
<tr>
<td rowspan=2>ABC</td>
<td rowspan=2>User</td>
<td>Y</td>
<td>True</td>
<td>False</td>
</tr>
<tr>
<td>Telecom</td>
<td>True</td>
<td>False</td>
</tr>
<tr>
<td rowspan=3>XYZ </td>
<td rowspan=3>User</td>
<td>O </td>
<td>False</td>
<td>False</td>
</tr>
<tr>
<td>Q</td>
<td>True</td>
<td>True</td>
</tr>
<tr>
<td>R</td>
<td>False</td>
<td>False</td>
</tr>
</table>
You can try following approach:
HTML:
<table>
<tr>
<th>Name</th>
<th>Role</th>
<th>Company</th>
<th>Request</th>
<th>Change</th>
</tr>
<tbody wicket:id="userList">
<tr wicket:id="providerList">
<td wicket:id="userName"></td>
<td wicket:id="roleName"></td>
<td wicket:id="provider"></td>
<td wicket:id="request"></td>
<td wicket:id="change"></td>
</tr>
</tbody>
</table>
Java:
add(new ListView<User>("userList", new PropertyModel<>(this, "users")) {
#Override
protected void populateItem(ListItem<User> listItem) {
final User user = listItem.getModelObject();
listItem.add(new ListView<Provider>("providerList", user.getProviders()) {
#Override
protected void populateItem(ListItem<Provider> listItem) {
final Provider provider = listItem.getModelObject();
Label nameLabel = new Label("userName", user.getName());
Label roleNameLabel = new Label("roleName", user.getRoleName());
listItem.add(nameLabel);
listItem.add(roleNameLabel);
if (user.getProviders().indexOf(provider) == 0) {
AttributeAppender attributeAppender =
AttributeAppender.append("rowspan", user.getProviders().size());
nameLabel.add(attributeAppender);
roleNameLabel.add(attributeAppender);
} else {
nameLabel.setVisible(false);
roleNameLabel.setVisibilityAllowed(false);
}
listItem.add(new Label("provider", provider.getName()));
listItem.add(new Label("request", provider.isRequest()));
listItem.add(new Label("change", provider.isChange()));
}
});
}
});
Be advised that this way user without any providers wont show up on the list at all.
wicket:container solves this problem.
Your html file would look like this:
<wicket:container wicket:id="doubleRow">
<tr>
...
First Row components
...
</tr>
<tr>
...
Second Row components
...
</tr>
</wicket:container>
Assuming you are using a DataTable with Columns:
In the cell that spans several rows you set the rowspan Attribute with a Model. The value in that model will be increased as long as the value of that cell is not changing.
Once you detect a change in the content, you create a new Model with a rowspan value of 1 and assign that again to the current cell.
Something like this might do it, but I cannot test it at the moment:
private IModel<Integer> currentRowSpanModel = new Model<>(0);
...
new AbstractColumn<Object, String>(new Model<>("ColumnWithRowSpan")) {
#Override
public void populateItem(Item<ICellPopulator<Object>> cellItem, String componentId, IModel<Object> rowModel) {
if (/*Content of cell has changed compared to last row*/) {
// write the content to the cell and add the rowspan Attribute
cellItem.add(new Label(componentId, "Content"));
currentRowSpanModel = new Model<>(1);
cellItem.add(AttributeModifier.replace("rowspan", currentRowSpanModel));
} else {
// Hide cell with same content and instead increase rowspan
cellItem.add(new WebMarkupContainer(componentId));
cellItem.setVisible(false);
currentRowSpanModel.setObject(currentRowSpanModel.getObject()+1);
}
}
}
my image..
http://www.4shared.com/photo/Rj_0Ymdt/1111.html
this is my coding in controller
def simpan(){
def banklimit = new BankLimit()
for(int i = 0; i<params.limitPerDay.size();i++) {
def baaa = CurrencyList.list(params)
banklimit.dayLimit = params.limitPerDay[i].toBigDecimal()
banklimit.alertLimit = (banklimit.dayLimit*0.8)
banklimit.currency = CurrencyList.findBySym(baaa.sym[i])
banklimit.save()
}
return banklimit
}
<table>
<thead>
<tr>
<g:sortableColumn property="sym" title="${message(code: 'banklimit.currency.sym.label', default: 'Simbol')}" />
<g:sortableColumn property="limitday" title="${message(code: 'banklimit.dayLimit.label', default: 'Limit/Day')}" />
</tr>
</thead>
<tbody>
<g:each in="${aaa}" status="i" var="bbb">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td id="${bbb.id}"> ${fieldValue(bean: bbb, field: "sym")}</td>
<td id="${bbb.id}" colspan="2"> <g:textField name="limitPerDay" value="${value}" /></td>
</tr>
</g:each>
<tr>
<td></td>
<td><g:submitButton name="save" value="SAVE" /> <g:actionSubmit action="back" value="BACK" /></td>
</tr>
</tbody>
</table>
i want to save the field on coloum limit /day if i click "SAVE" buttons.
based my coding, when i click save, only the last row was save in database...
example : theres 4 row..
row 1,2,3,4 filled, then i click save..why only 4th rows save in database? row 1 ,2,3 arenot saving?
You have just one banklimit = new BankLimit() but saving it 4 times. it's one object saved 4 times with different values in loop.
You need:
for(int i = 0; i<params.limitPerDay.size();i++) {
def banklimit = new BankLimit()
//.... fill with values
banklimit.save()
}
For client side it's better to make:
<g:each in="${aaa}" status="i" var="bbb">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
<td>${fieldValue(bean: bbb, field: "sym")}</td>
<td colspan="2"><g:textField name="limitPerDay[${i}]" value="${value}" /></td>
</tr>
</g:each>
I have ajaxRadio ineach row of a table.
when this Radio is selected, I want scala function to get two parameters:
1st one is the selected radio, 2nd one is the data key of the row.
my source is as follows:
val radioList = List("wideArea", "oldArea","newArea")
def liftForm(xhtml: NodeSeq): NodeSeq = {
var areaList = newOrderList.map(values =>{
<li id={values(1)} >
<table>
<thead></thead>
<tbody>
<tr class = "real">
<td class="listImage">
<img class="areaImage" src={values(6)}/>
</td>
<td style="vertical-align:top;">
<tr><p class="areaName">{values(4)}</p></tr>
<tr><p class="areaComment">{values(5)}</p></tr>
</td>
<td class="listCheck" >
{ajaxButton(S.?("delete"), () => doDelete(values(1)), "class" -> "button delete")}
</td>
</tr>
<tr>
<td></td>
<td>
{
val it = ajaxRadio[String](radioList,Box.legacyNullTest(values(2)),doRadioChange _).toForm.grouped(4)
for(i <- it)yield(<tr>{i.flatMap(y => <td> {y} </td>)}</tr>)
}
</td>
</tr>
</tbody>
</table>
</li>})
bind("list",xhtml,"areaList" -> <ul>{areaList}</ul>)
By doRadioChange _, I can only get selected radio. How can I get the the 2nd parameter: data key of the row. ie values(1)?
Your functions can close over all of the local state at that point in the function. You should be able to replace doRadioChange _ with:
doRadioChange(_, values(1))
Assuming, of course, that doRadioChange accepts the proper parameters.
everyone, I encounter a problem when I try to filter the drop down list.
The situation is I wish to filter the Agent dropdown list by using the Company dropdown list in same view/form. Since I need to display the Agents that only belong to the selected Company. But I have no idea to do that.
Any solution, please?
First add Method in Controller as follows
MvcApplication2.Models.MySampleDBEntities db = new Models.MySampleDBEntities();
public ActionResult SearchNames(string ddlcontent)
{
var list = new List<string>();
var nameqry = from n in db.Images
select n.PlayerName;
list.AddRange(nameqry.Distinct());
ViewBag.ddlcontent = new SelectList(list);
var names = from m in db.Images
select m;
if (string.IsNullOrEmpty(ddlcontent))
return View(names);
else//Filter content basedon dropdownlist selected item
return View(names.Where(s => s.PlayerName.Contains(ddlcontent)));
}
then bind it to view as follows
#model IEnumerable<MvcApplication2.Models.Image>
#{
ViewBag.Title = “SearchNames”;
}
<h2>SearchNames</h2>
#using (#Html.BeginForm(“SearchNames”, “Names”, FormMethod.Get))
{
#Html.DropDownList(“ddlcontent”, “All”)<input type=”submit” value=”Filter” />;
}
<table border=”4″ style=”border: medium dashed #FF0000″>
<tr>
<th>
PlayerName
</th>
<th>
Play
</th>
<th>
CountryName
</th>
<th>
Image
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.PlayerName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Play)
</td>
<td>
#Html.DisplayFor(modelItem => item.CountryName)
</td>
<td>
<img src=”#item.ImagePath” height=”100″ width=”100″/>
</td>
</tr>
}
</table>
2 options really...either split the server-based form post into multiple steps, or use jquery to handle this behavior JIT