Showing parent and child in one row - laravel

actually I have a table in a laravel website with data from diffrent joined database tables. But this way I get a row for every child and recurring parent data.
Instead I'd like to have one row per parent data and all childs in the same row.
Looks like a basic problem, but actually I've lost sight.
Any idea?
View:
$rechnungen=DB::select(DB::raw("
select
reintern, krenr, krebez, bnrkenn, bubelegnr, aufnr, sacktonr, sacbez, ustkenn,
TO_CHAR(round(bupbetr*(1+ustproz/100),2), '99G999D99', 'NLS_NUMERIC_CHARACTERS = '',.') as brutto,
wiebez, objktext, vektext
from RECHNUNG re
join BUCHUNG bu on bu.REKEY=re.REKEY
...
join BUCHUNGPOS bup on bup.BUKEY=bu.BUKEY and nvl(BUPARTKZ,0)=0 and bup.KREKEY is null
...
where re_status=0
order by bnr.BNRKENN, bu.BUBELEGNR
"));
Controller:
#foreach ($rechnungen as $re)
<tr>
<td></td>
<td>{{$re->wiebez}} {{$re->objktext}} {{$re->ve_ktext}}</td>
<td>{{$re->krektonr}}</td>
<td>{{$re->krebez}}</td>
<td>{{$re->bnrkenn}} {{$re->bubelegnr}}</td>
<td>{{$re->aufnr}}</td>
<td>{{$re->sacktonr}} {{$re->sacbez}}</td>
<td class="text-right">{{$re->ust_kenn}}</td>
<td class="text-right">{{$re->brutto}} €</td>
</tr>
#endforeach

Looks like you just need to create a relation Many To Many https://laravel.com/docs/5.8/eloquent-relationships#many-to-many

In an attempt to understand your issue in English:
You appear to have 3 tables:
Table BILL: Columns REKEY + various data
Table BOOKING: Columns BUKEY + REKEY + various data
Table BOOKINGPOS: Columns BUPKEY + BUKEY + various data
Where BOOKING.REKEY is a foreign key reference to BILL.REKEY and BOOKINGPOS.BUKEY is a foreign key reference to BOOKING.BUKEY.
I assume that each BILL can have multiple BOOKINGs and each BOOKING can have multiple BOOKINGPOSs.
The problem you are having is a display/view issue, not a data/model issue. In pseudo-code, you should implement your view as follows:
{{ $last_rekey="" }}
#foreach( $rows as $row )
#if( $row->rekey != $last_rekey )
#if( $last_rekey != "" )
</tr>
#endif
<tr>
<td>$row->BILLdata1</td>
<td>$row->BILLdata2</td>
...
$last_rekey=$row->rekey
#endif
<td>$row->BOOKINGdata1</td>
<td>$row->BOOKINGdata2</td>
...
<td>$row->BOOKINGPOSdata1</td>
...
#endforeach
</tr>
The idea being that whenever a row of data contains a new BILL, you start displaying a new row in the table, otherwise, you just continue adding cells to the current row.

Related

Cypress: Access the td next to a known one within a table

Can anybody help?
I need to write a cypress locator with a table name and the real name, but click on the checkbox in a td next to the real name label.
so far I have:
cy.contains('[tabletitle]', 'XYZ').should('be.lengthOf', 1)
.closest('table')
.contains('td', 'REALNAME').should('be.lengthOf', 1)
.parentsUntil('tr[name='tr-xyz']')
.get('input[type="checkbox"]').check();
I tried closest instead of parentsUntil, but it always jumps above the table name and then ergo click on all the input checkboxes of all the tables on the page. I want it to stay within a tr and just clicks on the checkbox in the above td (within the table).
Here is a scetch of the page:
<table name='xyz'><div tabletitle>XYZ</div>
<tr name='tr-efg'>
<td><div><div name='td-xyz'><input type="checkbox"></div></div></td>
<td><div someOtherDiffsandTD></div>
<td><div name='realName1'>REALNAME</div></td>
<td ...etc
<tr name='tr-efg'>
...same as first line with different realname
<tr name='tr-efg'>
... etc ...
</table>
<table name='abc'>
<tr name='tr-efg'>
...same as first table with first td containing a checkbox and second td a cell with the realname...
To navigate to the table element after selecting the tile, just use .parent() - assuming the table is the direct parent of the title element.
cy.contains('div[tabletitle]', 'XYZ') // tabletitle div with "XYZ"
.parent() // table
.should('be.lengthOf', 1)
.within(() => { // limit to this table
cy.contains('tr', 'REALNAME') // row with "REALNAME" in one of the columns
.should('be.lengthOf', 1)
.find('input[type="checkbox"]') // find, not get
// otherwise all inputs on page are returned
.check() // ✅
})
I suspect the HTML you show isn't the full picture, there should be a <tbody> around the <tr> and the title is oddly placed, I would expect it to precede the <table>.

Trying to read data from a table by combining the properties of 2 different tables

Here is the HTML for two tables that I am trying to read info from.
Table 1 has the heading that I am looking for:
<div>
<table>
<tbody>
<tr>
<td><h3 id="00Qw000000cxlth_RelatedNoteList_title">**My table**</h3></td> // table Head is stored in this table
</td>
</tr>
</tbody>
</table>
</div>
Table 2 is where the data is present and I read to store all the TD cells data in the string array. Table 2 is present right below table 1 but they are two different tables.
<div>
<div id="00Qw000000cxlth_RelatedNoteList_body" class="pbBody"> //div id changes dynamically everytime for a different record.
<table class="list">
<tbody>
<tr>
<td>Attachment</td>
<td>Requirement info for status</td>
<td>09/07/2014 20:34</td>
<td>John doe</td>
</tr>
</tbody>
</table>
</div>
My question: Is it possible to search for the heading of first table ("My table") and than fetch all the table data from the following table (table 2).
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
List<WebElement> rows = driver.findElements(By.xpath("//table[#class='list']//td"));
int count = rows.size();
System.out.println(rows.size());
String[] array = new String[count];
for (int i = 0; i<count; i++)
{
array[i] = rows.get(i).getText();
System.out.println(array[i]);
}
This gives me all the data from the table 2, but it also gives me all the tables info on the page that has #class = 'list' and not just the table with heading = 'My table'
Tried the following solutions without any luck
//div//table[//h3[contains(text(),'My table')]]//table//td[following-sibling::td] - Gets way more matches than just from one table.
Yes, you can. If your second table and first table are siblings, e.g.
<table>1st table</table>
<table>2nd table</table>
You can locate the first table first then find the second table using xpath, please follow this link to find more information on how to locate an element using sibling. http://scraping.pro/res/xpath-cheat/xpath_css_dom_recipes.pdf
There are many ways to "Uniquely" identify a web element, the link above is my favorite selenium cheat sheet.
Try this...
WebElement table = driver.findElement(By.cssSelector("table.list"));
List<WebElement> rows = table.findElements(By.tagName("tr"));
System.out.println(rows.size());
for (WebElement row : rows)
{
System.out.println(row.getText().trim());
}
This will return the first TABLE that has class = "list". It then loops through all the table rows of that table and prints the innerText.
Use below xpath
//div[table/tbody/tr/td/h3[#id='00Qw000000cxlth_RelatedNoteList_title'] or ./div[#id='00Qw000000cxlth_RelatedNoteList_body']/table[#class='list']/tbody/tr/td]
I have created a html page according to same HTML tags you have provided above.
This xpath return you 1st table heading as well as 2nd table all data. Then extract it all using WebElement List and further you can write your code according to your need.
If it is not working for you then let me know

Selenium IDE: Handle Ajax controls - select drop down values

I am trying to select drop down values using Selenium IDE. Say for example there are three drop down lists Country, State & City. Once you select a country A from the country drop down, the state drop down is populated (empty before) with the corresponding values and so on for the city.
When I record, some hardcoded values get recorded specific to the value selected in first drop down.
I selected the first value in the first drop down. Then selenium records the following for the ajax action:
click | css=option[value="28"]
Here 28 is the id stored in db for the selected value (first item in the drop down). I don't want this hardcoded value in my script as the actual ids in prod will be different.
I tried using waitForCondition but it is not able to populate the drop down values in the second drop down. Adding pause of 10 seconds also didn't help.
The sample recorded code is here:
<tr>
<td>select</td>
<td>id=property1</td>
<td>index=1</td>
</tr>
<tr>
<td>click</td>
<td>css=option[value="28"]</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>id=property2</td>
<td>index=1</td>
</tr>
<tr>
<td>click</td>
<td>css=option[value="12"]</td>
<td></td>
</tr>
<tr>
<td>select</td>
<td>id=property3</td>
<td>index=1</td>
</tr>
<tr>
<td>click</td>
<td>css=option[value="14"]</td>
<td></td>
</tr>
<tr>
The waitForCondition I tried is here
waitForCondition | var value = selenium.getText("//input[#id='some_xyIDHidden']"); value == "" | 10000
I am probably missing a basic step here. Need help.
Thanks
Try using selenium.fireEvent("<locator>","blur") on each and every element
in this condition you have to to store the value in a variable, the while dropdown will appear then you can use that value, for this you have to use the storeEval command to store the value in a variable

HtmlAgilityPack algorithm question

I’m using HtmlAgilityPack to obtain some Html from a web site.
Here is the received Html:
<table class="table">
<tr>
<td>
<table class="innertable">...</table>
</td>
</tr>
<tr>
<td colspan="2"><strong>Contact</strong></td>
</tr>
<tr>
<td colspan="2">John Doe</td>
</tr>
<tr>
<td colspan="2">Jane Doe</td>
</tr>
<tr>
<td colspan="2"> </td>
</tr>
<tr>
<td><strong>Units</strong></td>
<td>32</td>
</tr>
<tr>
<td><strong>Year</strong></td>
<td>1998</td>
</tr>
</table>
The Context:
I’m using the following code to get the first :
var table = document.DocumentNode.SelectNodes("//table[#class='table']").FirstOrDefault();
I’m using the following code to get the inner table :
var innerTable = table.SelectNodes("//table[#class=innertable]").FirstOrDefault();
So far so good!
I need to get some information from the first table and some from the inner table.
Since I begin with the information from the first table I need to skip the first row (which holds the inner table) so I do the following:
var tableCells = table.SelectNodes("tr[position() > 1]/td");
Since I now have all the cells from the first table excluding the inner table, I start doing the following:
string contact1 = HttpUtility.HtmlDecode(tableCells[1].InnerHtml);
string contact2 = HttpUtility.HtmlDecode(tableCells[2].InnerHtml);
string units = HttpUtility.HtmlDecode(tableCells[5].InnerHtml);
string years = HttpUtility.HtmlDecode(tableCells[7].InnerHtml);
The problem:
I’m getting the values I want by hardcoding the index in tableCells[] not thinking the layout would move…unfortunately, it does move.
In some cases I do not have a “Jane Doe” row (as shown in the above Html), this means I may or may not have two contacts.
Because of this, I can’t hardcode the indexes since I might end up having the wrong data in the wrong variables.
So I need to change my approach...
Does anyone know how I could perfect my algorithm so that it can take into account the fact that I may have one or two contacts and perhaps not use hardcoded indexes?
Thanks in advance!
vlince
There is never one unique solution to this kind of problem. Here is an XPATH that seems to do some kind of it though:
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.Load(yourHtmlFile);
doc.Save(Console.Out);
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//tr[td/strong/text() = 'Contact']/following-sibling::tr/td/text()[. != ' ']"))
{
Console.WriteLine(node.OuterHtml);
}
will display this:
John Doe
Jane Doe
32
1998

Using jQuery Validate to ensure there is at least one row in my table

I am using a table in an entry program to allow the user to add one or more rows of information (much like this article).
I need to ensure that there is at least one row in this table. Google is not really turning much up for me on people doing this. Can anyone give me direction on this? Can I do a count based on a class name?
Here is the layout of my table:
<table id="editorRows">
...
<tbody class="editorRow">
<tr class="row1">
</tr>
<tr class="row2" style="display: none;">
</tr>
<tr class="row3" style="display:none;">
</tr>
</tbody>
</table>
A "row" in this case is the tag. Row 2 and 3 get dynamically showen based on options in row 1.
you can use $("#editorRows tr").length > 0

Resources