ExactTarget - How to add dynamic user created content in an Email Template - asp.net-mvc

We have an email currently being created in back end code (C#) and sent through the ExactTarget API. I want to move this into a template in ExactTarget so that we don't have to maintain HTML written in StringBuilder() in C#. The issue is the content of the email is determined by what a user inputs. The user fills out a form of what samples they want then an email is sent to a person to fulfill the order.
So an example would be:
<tr>
<td>Product Number</td>
<td>Quantity</td>
</tr>
<tr>
<td>Product Number</td>
<td>Quantity</td>
</tr>
The maximum number of samples that can be ordered is 16. Is there a way to loop through content posted to ExactTarget to create the correct number of rows instead of hard coding 16 rows into the template and half of them being blank.
Please let me know if I need to be more specific about anything

You try just creating a Partial View as below,
#model IEnumerable<CartItems>
<table>
#foreach(var item in Model)
{
<tr>
<td>#item.Number</td>
<td>#item.Quantity</td>
<tr>
}
</table>
Call it from your C# Code as He suggested Here. Render a view as a string

As jordanm mentioned, here is an example in the ExactTarget documentation that covers this. You pass the custom input as XML during your triggered send and parse it / inject it into the HTML with AMPscript.
http://help.exacttarget.com/en/documentation/exacttarget/content/ampscript/using_ampscript_with_the_web_service_api/passing_content_to_a_triggered_send_message_at_send_time/

Related

Submit cell data from table in thymeleaf template

I have following code snippet:
<table class="table">
<thead>
<tr>
<th>Type</th>
<th>Title</th>
</tr>
</thead>
<tbody>
<tr th:if="${list.isEmpty()}">
<td colspan="2">No Media Available</td>
</tr>
<tr th:each="media : ${list}">
<form th:action="#{/pages}" method="post">
<td><span th:text="${media.getType()}">Type</span></td>
<td><span th:text="${media.getTitle()}">Title</span></td>
<td><input name="submit" type="submit" value="add"/></td>
</form>
</tr>
</tbody>
Now to my question: How can I submit the content from the rows?
Another question: Is my approach to creating a form for each row makes sense at all?
If you want to have user-entered data sent to the server, then replace this:
<td><span th:text="${media.getTitle()}">Title</span></td>
with this:
<td><input name="title" th:value="${media.title}"></td>
Assuming the ${media.title} evaluates to "War and Peace" This will use the name field to submit data as title=War and Peace (with URL encoding for the spaces in the title: War%20and%20Peace).
Note the use of ${media.title} instead of ${media.getTitle()}. You should be able to refer to the field name, rather than the get method. Thymeleaf will use the getFoo() method for a field called foo, based on naming conventions.
There are other approaches, for example:
use a visible input field, but styled to look and behave like regular text (cannot be edited, and has no surrounding box).
use JavaScript to replace the default form submission process, and read your row data from the vanilla table, without a form - instead, with a button using a click event handler.
If you create one form for the entire table, you're going to get all the table's data submitted at once (arrays of title data, and so on).
Alternatively, if you have one form per table row, you have to consider what happens if a user edits multiple rows of data before hitting submit for one row. All those other unsent changes will potentially be lost.
A common solution is to avoid this problem, by forcing users to update records one at a time: The table does not use forms. Each row's button click opens a new modal dialog containing the data for only that one row (in a form) - which can then be edited and submitted.

jsrender/jsreport - How to print a variable an all the pages

I'm using jsreport and using jsrender engine to generate PDF reports.
I want to print some variables on all the pages (but not in the page header or footer), and also a header of a table should appear on all pages. How Can I specify to print something on all pages ?
Thank you.
This could be potentially do-able with thead tag, which by default prints on each page of the long table
<table>
<thead>
<tr><td>Repeated thing here</td></tr>
</thead>
<tbody>
<tr>....</tr>
</tbody>
</table>
Unfortunately this is very buggy in all printing engines, so you may have problems with it, some workarounds are mentioned here https://github.com/ariya/phantomjs/issues/10927

Find and act on links based on value in a cell with Mechanize in Rails

I am trying to act on links found in a specific row in an HTML table.
The table has a column for a date and a column for city names which act as links. I need to find row with specific date and then cycle through the links found from the next cell on same row one after the another.
I reach the target page with Mechanize from the previous page (link to page is generated at previous page so direct link is not possible) and I am able to select the said table with this:
agent.page.search("//table[#class='calendar']")
But, after that, I am at a loss how to select the correct row based on the date in Date-column and click each of the links in turn (and naturally do stuff before moving on to the next city).
EDIT
I managed to make some progress. I am now able to get contents of correct cell in correct row IF I hardcode the date in. But I can't figure out how to use variable in place of hardcoded date and I also need to find a way to use just the date and not to include weekday as text in there as well.
agent.page.search("//table[#class='calendar']/tbody/tr/td[#class='date']
[text()='wed 27.8.2014']/following-sibling::td[1]/ul/li")
Example HTML below:
<table class="calendar">
<tr>
<th>Date</th>
<th>City</th>
</tr>
<tr class="odd">
<td class="date">thu 28.8.2014</td>
<td class="city">
<ul>
<li>London</li>
<li>Paris</li>
<li>Berlin</li>
</ul>
</td>
</tr>
<tr class="even">
<td class="date">wed 27.8.2014</td>
<td class="city">
<ul>
<li>London</li>
<li>Paris</li>
<li>Berlin</li>
</ul>
</td>
</table>
All help is greatly appreciated!
With further research I was able to find the answer my self. Of great help was this question and answer Nokogiri: How to select nodes by matching text? about partial matching in Nokogiri.
Following snippet is what works for me now and I am able to proceed.
date = Date.new(2014,8,27)
agent.page.search("//table[#class='calendar']/tbody/tr/td[#class='date']
[contains(text(),
\"#{date.strftime("%e.%-m.%Y")}\")]/following-sibling::td[1]/ul/li")

How to display some html text from a database in a VIew within a TD cell, but only first 300 chars.....?

Not sure if this is possible, but I have some HTML in a DB column which I want to display in a Table TD cell in a Razor View. However the issue is that I only want the first 300 chars followed by "..."
ie:
<h2>My Test</h2>
<p>My Test description is very long</p>
So if I return the first 25 chars for the purpose of this question plus "...", I would get:
<h2>My Test</h2>
<p>My Tes ...
Which would then upset the containing page, due to the invalid HTML
ie
<table>
<tr>
<td>
<h2>My Test</h2>
<p>My Tes ...
</td>
</tr>
</table>
Is there a way round this?
At the moment I am using:
#Html.Raw(Model.myTestHtml)
to display the test HTML.
Perhaps I can only strip out the text from the HTMl and then .substring this.
Thanks appreciated.
If the html is not dynamic and it always follows same pattern, you may:
Parse the html to xml content
use LINQ2XML and find the node you want in there
edit that text and replace the additional parts with (...)
parse back to html
render it
LINQ2XML is very reliable. I am not sure if you can find dependencies which does same work as it with same level of accuracy and performance. but if you do find it, then you would not need to parsing in the process(to xml and from xml)

Getting table value from view to controller

I have a domain class, Report, with a referenced child class, prompt.
One the edit Report page you are allowed to reorder the order of prompts in a table. Then when the user goes to run the report, on that page the prompts are in said order.
The table on the Report edit.gsp page uses some jQuery to allow drag and dropping of the row, and it updates the display order number, but only on the UI side, nothing is going back to the database yet.
I would like to be able to pass this new order back to my update command, but cannot figure out how to grab the table row data for the life of me.
When searching almost all of the results are how to get data from the controller to the view, not vice-versa.
Here is the snippet of table code
<table id="prompts">
<thead>
<tr>
<th>${message(code: 'prompt.name.label', default: 'Name')}</th>
<th>${message(code: 'prompt.description.label', default: 'Description')}</th>
<th>${message(code: 'prompt.required.label', default: 'Required')}</th>
<th>${message(code: 'prompt.displaySeqno.label', default: 'Display Order')}</th>
</tr>
</thead>
<tbody>
<g:each in="${reportInstance.prompts.sort{it.displaySeqno}}" status="i" var="prompt">
<tr class="${(i % 2) == 0 ? 'even' : 'odd'}" onclick='window.location = "${createLink(controller: "prompt", action: "edit", id: prompt.id)}"'>
<td>${fieldValue(bean: prompt, field: "name")}</td>
<td>${fieldValue(bean: prompt, field: "description")}</td>
<td>${prompt.required}</td>
<td class="displaySeqno">${prompt.displaySeqno}</td>
</tr>
</g:each>
</tbody>
</table>
And then in the controller, I tried
params.list('displaySeqno')
But it would just return an empty array.
How can I get the value of the displaySeqno from within my controller class?
Thanks.
This is one of those time (which happens a lot) where a fundamental understanding of how HTTP / Java EE works would allow you to solve your problem very easily. Forms or no forms, you have to pass a value into the request that goes to the server for it to end up on the server. How is this
<td class="displaySeqno">${prompt.displaySeqno}</td>
ever going to get to the server, form or no form? The answer is, it is not. Assuming a typical form post you would need to store the value in a hidden field
<input type="hidden" name="displaySeqno" value="${prompt.displaySeqno}" />
Then it would make it to the server. If you're processing with Ajax of some sort, you would need to pass it in as a parameter via the API. Assuming jQuery, for example:
pseudo code ahead:
var params = $('#youFormId').serialize();
$.post('some/url/to/post/to', params, function(data) {
});
Bottom line is, if you want to pass something to the server, you have to provide the means for that to happen.

Resources