Spring WebFlux+Thymeleaf How to display reactive collection size - spring-webflux

I am developing a spring boot service to manage a REST server.
The service displays a reactive list on one of the forms.
It is very simple code.
Table in thymeleaf template
<table>
<thead>
<tr>
<td>ID</td>
<td>Name</td>
<td>Alive</td>
</tr>
</thead>
<tbody>
<tr th:each="item : ${items}">
<td th:text="${item.counterpartID}" />
<td th:text="${item.counterpartName}" />
<td th:text="${item.alive}"/>
</tr>
</tbody>
</table>
Controller
#GetMapping("/counterparties")
public String init(Model model) {
IReactiveDataDriverContextVariable reactiveDataDrivenMode =
new ReactiveDataDriverContextVariable(
webClient
.get()
.uri(uriBuilder -> uriBuilder
.path("/findAllCounterpart")
.build())
.retrieve()
.bodyToFlux(Counterpart.class)
, 1);
model.addAttribute("items", reactiveDataDrivenMode);
return "counterparties.html";
}
Now I want to display collection size (numbers of rows in table).
I added to the html temlate tag
<label th:text="'total rows: ' + ${#lists.size(items)}">rows number in table</label>
And I got an unexpected result
total rows: 1
How to display the real number of rows in a reactive collection ?
Thanks.

I decided to use javascript.
<script language="JavaScript">
function countLoadedRows() {
var table = document.getElementById('tableId');
var tbodyRowCount = table.tBodies[0].rows.length;
console.log('total rows: ' + tbodyRowCount);
document.getElementById('totalRowsId').textContent = tbodyRowCount
}
document.addEventListener('readystatechange', countLoadedRows)
</script>
and html tags is
<input type = "button" onclick = "countLoadedRows()" value = "Total rows: "><label id="totalRowsId">???</label>
<table id="tableId">
...
</table>

Related

How can I fix this issue with my table?

I'm trying to replicate a one rowed table with a form, such that when I press the '+' button - I would like another table form to drop down below it exactly the way it is - however, when I do that and add the same element as the table with the HTML code, I get something different...
I got screenshot images to the form below and after that I got the code indented -
The code for the above images is listed below - the first being the forms and the second being the Javascript function
<body>
<form>
<div id="container1">
<table border="1" cellspacing="0" style="margin-top:12px width="900"">
<colgroup>
<col span="1">
</colgroup>
<tr>
<td valign="top">
<label for="company" size="3">Company:</label> <input type="text" id="company" name="company" maxlength="15" size="15">
</td>
<td valign="top">
<label for="position1" size="3">Position:</label> <input type="text" id="position1" name="position1" maxlength="20" size="12"> </td> <td valign="top"><label for="tasks" size="3"> Tasks: </label></td><td> <textarea id="tasks" name="tasks" maxlength="1000" cols="25" rows="1"></textarea></td>
<td valign="top"><label for="from1" size="3"> From: </label><input type="text" id="from1" name="from1" size="4" ></td> <td valign="top">To: <input type="text" id="to1" name="to1" size="4"> <td valign="top"><label for="location" size="3">Work Location: </label><input type="text" id="location" name="location" size="20" maxlength="25"> + <br></td>
</tr>
</table><br>
</div>
</form>
</body>
the javascipt code is posted below:
function aFields1(){
var container1 = document.getElementById("container1");
var table = document.createElement("table");
table.border=1;
table.cellspacing=0;
var tr = document.createElement("tr");
var td = document.createElement("td");
td.valign = "top";
var label = document.createElement("label");
label.for = "company";
label.size = 3;
container1.appendChild(document.createTextNode("Company: "));
container1.appendChild(label);
var company = document.createElement("input");
company.type = "text";
company.id = "company";
company.name = "company";
company.size = 15;
company.maxlenth = 15;
//append the company input element to the td element
td.appendChild(company);
tr.appendChild(td);
table.appendChild(tr);
//append the td element to the container1 element
//container1.appendChild(tr);
container1.appendChild(table);
Can anyone please tell me why the table is not showing up?
There should be a border with at least one cell with the company label and input bar INSIDE it - but as you can see from the image the Company label is on the top and the input bar with the border is below it...
where'd I go wrong? and why are the borders for the cell much much more different from what came out of the HTML code?
Part of the problem is that you're appending the label element to the DIV directly instead of appending it to the new td. This is why it's showing up outside of the Table.
From your last comment, it seems like what you really want to do is just append a cloned TR to the existing table. Ok, there are multiple ways to do this. You can completely re-build a duplicate tr in javascript, OR you can just clone the first table row and append it to the table. This is trivial with jQuery, but can be done with pure javascript.
First, let's add an id attribute to the table element. like so:
<table id="my_table" border="1" cellspacing="0" style="margin-top:12px;width:900px">
.....snip rest of your table....
</table>
Then your javascript cloning can work like this (note: code is untested):
function aFields1() {
var table, tr, cloned_row, inputs_to_clear;
// find the table
table = document.getElementById('my_table');
// find the first tr element
tr = table.querySelectorAll('tr')[0];
// clone the first tr using deep = true option to copy all children
tr_cloned = tr.cloneNode(true);
// NOTE: the values in the cloned row will already be prefilled, so you probably want to clear input-field values as well
inputs_to_clear = tr_cloned.querySelectorAll('input');
foreach (var input in inputs_to_clear) {
inputs_to_clear[input].value = '';
}
// append the new row
table.appendChild(cloned_row);
}

Display the first row of view data in razor

I have a a ViewData with 8 rows. The ForEach loop works fine, but I need to extract the very first row before the foreach.
I need to extract only the first row to inject the default video in the iframe.
<iframe name="myFrame" width="800" height="500" src="#item.ID?wmode=transparent" allowfullscreen="True"></iframe>
Here is the foreach that works 100%
#foreach (var item in (List<VideoModel>)ViewData["Videos"])
{
<tr class="sep">
<td>#item.DisplayNumber</td>
<td>
#Html.ActionLink("Play Video", "IframeRedirect", "Home", new { ContentID = item.ID }, new { target = "someFrame", #class = "cbutton" })
</td>
<td>#item.Time #item.Hd</td>
<td><b>#item.Title</b><br />#item.Description</td>
</tr>
<tr>
<td></td>
<td></td>
<td></td>
<td><b>Author:</b> #item.Author <br />Subscribe to youtube channel</td>
</tr>
}
you can get the first row like following:
var firstRow = ((List<VideoModel>)ViewData["Videos"]).First();
If your model is a IEnumerable
You can get the first like following:
var first = Model.First();

how to create cart content as pdf output in PRESTASHOP

I have to print the cart content in a pdf file and download.
I have try some code using pdfinvoicecontroller.php
I have created new controller - controllers/front/CartprintController.php
class CartprintControllerCore extends FrontController
{
protected $display_header = false;
protected $display_footer = false;
public $content_only = true;
protected $template;
public $filename;
public function postProcess()
{
if (!$this->context->customer->isLogged() && !Tools::getValue('secure_key'))
Tools::redirect('index.php?controller=authentication&back=cartprint');
}
public function display()
{
$displayproducts = $this->context->cart->getProducts();
$pdf = new PDF($displayproducts, PDF::TEMPLATE_INVOICE_CART, $this->context->smarty, $this->context->language->id);
$pdf->render();
}
public function getTemplate()
{
$template = _PS_THEME_PDF_DIR_.'/cartprint.tpl';
return $template;
}
}
Added
const TEMPLATE_INVOICE_CART = 'Cartprint';
line in classes/pdf/PDF.php
3.then created a HTML template file in pdf/cartprint.tpl
<table id="cart_summary" class="std">
<thead>
<tr>
<th class="cart_product first_item">{l s='Product'}</th>
<th class="cart_description item">{l s='Description'}</th>
<th class="cart_unit item">{l s='Unit price'}</th>
<th class="cart_quantity item">{l s='Qty'}</th>
<th class="cart_total item">{l s='Total'}</th>
</tr>
</thead>
{foreach $displayproducts item=prodpef name=prodpef }
<tr>
<td class="cart_product first_item">{$prodpef.name}</td>
<td class="cart_description item">{$prodpef.description_short}</td>
<td class="cart_unit item">{$prodpef.price}</td>>
<td class="cart_quantity item">{$prodpef.cart_quantity}</td>>
<td class="cart_total item">{$prodpef.total}</td>>
</tr>
{/foreach}
</table>
4.in shopping cart page i have created a link
<img src="{$img_dir}icon/pdf.gif" alt="{l s='Invoice'}" class="icon" />
but still i am not getting pdf output .
Any help ?
First it will be better to override PDF class and second you need to create a HTMLTemplateCartPrint.php file in classes dir or override classes dir in order to generate pdf file.
Best regards.

How to close dojox.grid.DataGrid

I have a grid that populates from a search event and I'd like the option of being able to close the grid by simply adding an X in the top right corner, similar to how you close any browser or window. I thought it would be as easy as adding the X, styling it to my liking and then creating an onclick event that would close or hide the grid... but I can't seem to get that working. Any help would be appreciated.
My JS is:
dojo.require("dojox.grid.DataGrid"); //FindTask
dojo.require("dojo.data.ItemFileReadStore"); //FindTask
dojo.require("esri.tasks.find"); //FindTask
var findTask, findParams;
var grid, store;
var searchExtent;
function doFind() {
//Show datagrid onclick of search button and resize the map div.
esri.show(datagrid);
dojo.style(dojo.byId("content"), "height", "83%");
searchExtent = new esri.geometry.Extent ({
"xmin":-9196258.30121186,"ymin":3361222.57748752,"xmax":-9073959.055955742,"ymax":3442169.390441412,"spatialReference":{"wkid":102100}
});
map.setExtent(searchExtent);
//Set the search text to the value in the box
findParams.searchText = dojo.byId("parcel").value;
grid.showMessage("Loading..."); //Shows the Loading Message until search results are returned.
findTask.execute(findParams,showResults);
}
function showResults(results) {
//This function works with an array of FindResult that the task returns
map.graphics.clear();
var symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([98,194,204]), 2), new dojo.Color([98,194,204,0.5]));
//create array of attributes
var items = dojo.map(results,function(result){
var graphic = result.feature;
graphic.setSymbol(symbol);
map.graphics.add(graphic);
return result.feature.attributes;
});
//Create data object to be used in store
var data = {
identifier: "Parcel Identification Number", //This field needs to have unique values. USES THE ALIAS!!!
label: "PARCELID", //Name field for display. Not pertinent to a grid but may be used elsewhere.
items: items
};
//Create data store and bind to grid.
store = new dojo.data.ItemFileReadStore({ data:data });
var grid = dijit.byId('grid');
grid.setStore(store);
//Zoom back to the initial map extent
map.setExtent(searchExtent);
}
//Zoom to the parcel when the user clicks a row
function onRowClickHandler(evt){
var clickedTaxLotId = grid.getItem(evt.rowIndex).PARCELID;
var selectedTaxLot;
dojo.forEach(map.graphics.graphics,function(graphic){
if((graphic.attributes) && graphic.attributes.PARCELID === clickedTaxLotId){
selectedTaxLot = graphic;
return;
}
});
var taxLotExtent = selectedTaxLot.geometry.getExtent();
map.setExtent(taxLotExtent);
}
and my HTML is:
<div id ="datagrid" data-dojo-type="dijit.layout.AccordionPane" splitter="true" region="bottom"
style="width:100%; height:125px;">
<table data-dojo-type="dojox.grid.DataGrid" data-dojo-id="grid" id="grid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px'">
<thead>
<tr>
<th field="Parcel Identification Number" width="10%">
Parcel ID
</th>
<th field="Assessing Neighbornood Code" width ="20%">
Neighborhood Code
</th>
<th field="Property Class Code" width="10%">
Property Class
</th>
<th field="Site Address" width="100%">
Address
</th>
</tr>
</thead>
</table>
</div>
This is my best guess at what to add:
<tr>
<td align="right">
<div class="divOk" onclick="dijit.byId('tocDiv').hide();">
OK</div>
</td>
</tr>
I wound up creating a work around for what I want by creating a new column and putting a close icon within the header. I connected it to an function so that when I click it, the grid closes and the map resizes:
function closeGrid() {
esri.hide(datagrid);
dojo.style("map", {"height": "100%"});
}
HTML
<th field="" width="2%"> <div class="GridCloseIcon" title="Close Grid" onclick="closeGrid();"></div>
How about this?
(assuming the OK line actually appears)
HTML
<tr>
<td align="right">
<div class="divOk" onclick="hideGrid();">OK</div>
</td>
</tr>
JS
function hideGrid() {
var widget = dijit.byId('datagrid');
dojo.fadeOut({
node: widget.domNode
}).play();
dojo.style(widget.domNode, 'display', 'none');
}

how to save FormBean values in List & Iterate over JSP

I want to save FormBean values in List, wants to save it in Session and again wants to iterate list for different FormBean values over JSP using <logic:iterate>.
I am able to iterate list or FormBean values <logic:iterate> but not able to do it with combination of both.
I have tried for this eg.
<table width="75%" border="0" cellspacing="1" cellpadding="0">
<logic:iterate id="myId" name="sessionData" property="getInsuredPhoneList">
<tr>
<td width="25%"> <bean:write name="myId"/> </td>
</tr>
</logic:iterate>
</table>`
Action class for showing JSP:
List<String> getInsuredPhoneList = new ArrayList<String>();
getInsuredPhoneList.add("");
getInsuredPhoneList.add("");
getInsuredPhoneList.add("");
getInsuredPhoneList.add("");
getInsuredPhoneList.add("");
sessionData.setGetInsuredPhoneList(getInsuredPhoneList);
Action class for processing JSP:
InsuredPhoneFormBean partyForm1=(InsuredPhoneFormBean)actionForm;
String type=partyForm1.getPhoneTypeCode();
String area=partyForm1.getAreaCode();
String landlineNumber=partyForm1.getLandlineNumber();
String mobileNumber=partyForm1.getMobileNumber();
String email=partyForm1.getEmailAddress();
SessionData sessionData=getSessionData(request);
List<String> getInsuredPhoneList = new ArrayList<String>();
getInsuredPhoneList.add(type);
getInsuredPhoneList.add(area);
getInsuredPhoneList.add(landlineNumber);
getInsuredPhoneList.add(mobileNumber);
getInsuredPhoneList.add(email);
sessionData.setGetInsuredPhoneList(getInsuredPhoneList);
My Output is:
Residential 9988009988 abc#gmail.com
I want here is getInsuredPhoneList will save multiple instances of FormBean values (Residential 9988009988 abc#gmail.com, Office 9970009988 xyz#yahoo.com ) and i want to iterate it through getInsuredPhoneList,
Such that
<table>
<logic:iterate id="myId" name="sessionData" property="getInsuredPhoneList">
<tr>
<td width="25%"> <bean:write name="myId" property="abc"/> </td>
</tr>
<tr>
<td width="25%"> <bean:write name="myId" property="xyz"/> </td>
</tr>
<tr>
<td width="25%"> <bean:write name="myId" property="pqr"/> </td>
</tr>
</logic:iterate>
</table>
(property="pqr" means One of the property of FormBean)
and Output Like:
Residential 9988009988 abc#gmail.com
Office 9970009988 xyz#yahoo.com
You code is so messed up that I can't really follow and understand exactly what you are asking. But this is the general concept:
1) Populate Objects and add them to List in Action Class(Suppose you have an Object Contacts that has 3 properties - office, tel, mail)
//in Action class
Contacts myContact = new Contacts();
myContact.setOffice("office1");
myContact.setTel("123454");
myContact.setMail("xx#xx.com");
List<Contacts> myList = new ArrayList<Contacts>();
myList.add(myContact);
//You can add more Objects to List here
2) Set the list Object in request so you can access it in the JSP later
request.setAttribute("PHONE_LIST",myList);
3) In JSP you have to get the List from the request and iterate over it to show results
//in JSP
<table>
<logic: iterate id="dataObject" name="myForm" property="PHONE_LIST">
<tr>
<td><bean: write name="dataObject" property="office" /></td>
<td><bean: write name="dataObject" property="tel" /></td>
<td><bean: write name="dataObject" property="mail" /></td>
</tr>
</logic: iterate>
</table>
Hope this helps