Visualforce / Apex: Access two objects with one controller - html

I'm forcing the problem that I have to set up a visualforce page rendered as pdf, which outputs a automatically generated invoice. Because of intern workflows this page has to be set up to the Opportunity object.
Most of the fields used are taken from the Opportunity object itself and work fine.
But I also need access to the OpportunityLineItem fields to display the products on the invoice.
How can this be realized? Do I have to write a controller extension in apex or is it possible without?
As an alternative, would this eventually be possible with cross formula fields referring from Opportunity to OpportunityLineItem? I tried this, but could not find any possibility to select OpportunityLineItem in a formula field in the Opportunity object.
Any help is much appreciated. Thanks!!

Below is a sample page accessing the OpportunityLineItems for a given Opportunity using the standard controller ammended from this doc reference.
<apex:page standardController="Opportunity">
<table border="0" >
<tr>
<th>Description</th><th>Quantity</th>
<th>Unit Price</th><th>Name</th>
</tr>
<apex:repeat var="oli" value="{!Opportunity.OpportunityLineItems}">
<tr>
<td>{!oli.Description}</td>
<td>{!oli.quantity}</td>
<td>{!oli.unitprice}</td>
<td>{!oli.Name}</td>
</tr>
</apex:repeat>
</table>
</apex:page>
With respect to formula fields, you cannot access child fields in a formula on the parent for the simple reason that it is a one to many relationship. The parent Opportunity would not know which of the children to lookup to.
The best you can do is make a regular (text or whatever) field, run a Process Builder triggered by a change to the relevant field(s) on the parent (opportunity) and trigger a Flow to loop over the children (LineItems) and make the changes to the parent based on some condition you specify.

Related

Is there a way to access the first element in a column on a website using VBA?

Here is a screenshot of a column in a website page.
It is located in that way in the website page :
As you can see, all the rows have a 'Completed' button you can pres and followed by a number of lines. These rows refer to exports. So the columnis not static and is constantly changing.
However, everytime i run the macro i want to access the first row of the column.
Here is a sample code of he HTML code of the first 'Completed' button in the screenshot above:
I have many that have the same class name. Look at the highlighted rows as an example in the picture below:
I really have no idea how to write a VBA code to always access the first 'Completed' bytton in this column.
PS: In the HTML code, in the tag "a", the onclick="....." is constantly changing. So i cannot use this as an argument to access the desired field and click on the desired button.
Please if anyone could help me figure out how to do this, i would really be happy.
Thank you :)
If you want to click the 'Completed' button in the first column, you can use the code below:
Set doc = objIE.Document
doc.getElementsByTagName("tr")(0).getElementsByTagName("td")(0).getElementsByTagName("a")(0).Click
The code get the first <tr> then get the first <td> then get <a> in it.
<tr> tags are rows, <td> tags are cells inside those rows. You did not provide enough code to show the entire table, but generally speaking to access the first row of a table, you would need to refer to the collection object and use the index number you want.
.getElementsByTagName("tr")(0)
This will refer to the first row of a table. Same with getting the first column in the first row of your table:
.getElementsByTagName("tr")(0).getElementsByTagName("td")(0)
Once you tracked down the particular cell, now you are wanting to click the link. You can use the same method as above.
.getElementsByTagName("tr")(0).getElementsByTagName("td")(0).getElementsByTagName("a")(0).Click
And a final note, the first row of a table could be a header, so you may actually want the 2nd row (1) instead.
Thanks for updating with more HTML code. I am going to slightly switch gears and use querySelector() to grab the main table.
doc.querySelector("#divPage > table.advancedSearch_table > tbody"). _
getElementsByTagName("tr")(3).getElementsByTagName("td")(3).Children(0).Click
See if this works for you.

HTML/Bootstrap Table Sorting and Sort Direction Indicator

I am using bootstrap to display and sort a table. I was wondering how/if I could implement a temporary arrow(or something) in each header in the table to indicate which direction it is being sorted.
Yes this is possible. For the header, add the following...
<table>
<thead>
<tr>
<th>Column 1 <span class="glyphicon glyphicon-sort"></th>
...
</tr>
</thead>
</table>
EDIT: I assume you actually want the icon to sort the table, as well.
This is dynamic behavior, so you won't be able to do this in pure HTML/CSS: you will need to use JavaScript. Here are the general steps that you would do to make this happen:
Store all of the table rows inside of a JavaScript variable
Inside the <th>, place another element, like a <span> or <img> that contains your arrow image.
Attach a click handler to the arrow, that sorts the array of table rows
After the array is sorted, use DOM API functions to remove the old table, create a new table, and then insert a new table in its place. Bootstrap usually is used with jQuery, so you can look at some jQuery functions to remove the table, build a new one (by going through the rows), and then render the built table to the page, in place of the old one.
There are a variety of libraries that do this, but you can accomplish it more simply by doing it yourself.

Nested ng-repeat with attribute from parent ng-repeat

I have a JSON object (tbls) which contains an array called sections. This array contains titles (n) and IDs (viewid) of "rooms" that are also a part of the JSON object. This means you can do tbls.[roomid] and get the array that contains the objects of each room. I have a hard time making this work in Angular.
It was built this way because it makes it easy to work with when it comes to UITableViews in iOS (where it's implemented and works). Therefore I cannot change the data. I tried below solution, but that gives me an error. Is there an effective way to do this in Angular?
<tbody data-ng-repeat="section in tbls.sections">
<tr>
<td>{{::section.n}}</td>
</tr>
<tr data-ng-repeat="table in tbls.{{section.viewid}}">
<td>{{::table.n}}</td>
</tr>
</tbody>
JSON JSFiddle: https://jsfiddle.net/Lu2ocqku/
Edit: removed tableObj as it's not relevant to the question and doesn't match data example exactly. Same logical problem though.
Edit: Since I asked this question I have changed it to be properly nested with an array of sections containing what is in that section as well. Don't do what I did in this question, originally.
You just need to use standard [] javascript object syntax:
<tr data-ng-repeat="table in tbls[section.viewid]">

How to Disable (Not Hide) Table Rows

I need to disable (not hide) a single table row in a table with at least two rows. I've been searching for how to do it, but everything I've found tells me how to hide the row. I need to actually disable it so that the result is not submitted.
I'm using a template row and cloning when users add rows. On submit, the hidden template and the rows with actual data are all submitted. The database save fails because the hidden row doesn't pass validation.
<tr class="template" style="display:none">
<!-- This is the row to be copied and unhidden to add to the table -->
<td>company</td>
<td>department</td>
<td>line</td>
<td>account</td>
</tr>
It looks to me like you are going to duplicate the table row over and over again to create the table structure with javascript or something. Options:
You could remove the row from the DOM before submission or
jQuery('tr.template').remove();
you could select all the rows except it to submit
jQuery('table tr').not('tr.template').submit();
I personally do not think it is possible to have a table without rows, perhaps you mean you want to stylise your website without using a table?
If that is the case, then if your not already, set up a css file, with this you can edit and manipulate blocks for your website. ( I would post screenshots but my reputation isn't up yet ^-^ )

Should I use one form on page or generate a form per item?

I want to display a list of items. Each item would have an edit and a delete icon next to it.
For obvious reasons I want to trigger the delete action with HTTP POST.
With jQuery, I would bind links to trigger form.submit.
However I'm not sure if I should generate a form next to each item or use just one form.
Below are pros and cons of two approaches as I see them.
Form Per Item:
easy to generate;
no need to fiddle in JS to set action and input value.
Single Form:
makes more sense semantically;
requires client JS to set hidden input;
requires client JS to set form action (e.g. id + '/delete/).
What is there to add? What is the preferred pattern in modern HTML apps?
I have used checkboxes in the past. This is better for usability, and each checked checkbox can pass its own ID to the form processing script.
The main disadvantage I see in having a single form enclosing all list elements is that you can end up with a huge POST if the list is long. As an advantage, you could mark multiple elements for deletion (checkboxes, for instance) and perform a single delete request.
I'd go for either
A single form for each list element. This would make deletion of multiple elements impossible, but would keep POST sizes minimal.
Using a single form, but in a way that doesn't include all the list elements. For instance, having a delete only form with a single hidden element in it, into which you would put all the id's marked for deletion with JS manipulation.
As a side note, you could also skip forms and perform the needed interactions through ajax. This would improve user experience notably. Take into account that forms would still be needed to provide fallback mechanisms in case it was required.
In the end, I decided to go with AJAX via jQuery.ajax.
The reason is semantically I don't even have forms—I have buttons.
Therefore, jQuery is an easier solution as it allows to keep posting logic in one place (as opposed to scattering it across HTML and JS).
I assigned row class to each semantical row and put corresponding database IDs in HTML5 data attribute called data-row-id for each row.
<div class="row" data-item-id="{{ product.id }}">
<!-- ... --->
<img src="/img/delete.png" alt="Delete">
</div>
Then I have something alone the lines of
$('.delete-btn').click(function() {
var row = $(this).closest('.row');
var id = row.data('item-id');
$.ajax({
url: id + '/delete/',
type: 'POST'
});
row.fadeOut().slideUp();
return false;
}
in my $() load handler.
This solution scales beautifully across the whole codebase because you only have to set row class and data-item-id attribute and the buttons will “just work”.