Freemarker: Iterate over a LinkedHashMap - freemarker

I have following piece of code -
public class Result {
private Map<String, String> dataPoints = new LinkedHashMap<String, String>();
public Map<String, String> getData() {
return Maps.newHashMap(data);
}
public Set<Map.Entry<String, String>> getDataEntries() {
return data.entrySet();
}
public void addData(final String key, final String value) {
this.data.put(key, value);
}
}
I am using LinkedHashMap as I want to maintain insertion order. I am trying to iterate over the map in my freemarker code as below. However, I get an exception.
<#if (result.dataPoints?keys?size > 0) >
<#list result.getDataEntries() as entry>
<tr>
<td width="35%">
<div>${entry.key}</div>
</td>
<td width="45%">${entry.value}</td>
<td width="19%"> </td>
</tr>
</#list>
</#if>
Exception:
Expression result.getDataEntries is undefined on line 50, column 24 in settings/settings-
diagnostics.ftl. The problematic instruction: ---------- ==> list result.getDataEntries()
as entry [on line 50, column 17 in settings/settings-diagnostics.ftl] in user-directive
printDiagnosticResult [on line 64, column 25 in settings/settings-diagnostics.ftl] in
user-directive printDiagnosticResult [on line 76, column 13 in settings/settings-
diagnostics.ftl] in user-directive layout.landingbase [on line 1, column 1 in
settings/settings-diagnostics.ftl] ---------- Java backtrace for programmers: ----------
freemarker.core.InvalidReferenceException: Expression result.getDataEntries is undefined
on line 50, column 24 in settings/settings-diagnostics.ftl. at
freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:124) at
freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:134) at
freemarker.core.MethodCall._getAsTemplateModel(MethodCall.java:114) at
freemarker.core.Expression.getAsTemplateModel(Expression.java:89) at
freemarker.core.IteratorBlock.accept(IteratorBlock.java:94) at
freemarker.core.Environment.visit(Environment.java:208) at
If I replace above code with:
<#if (result.dataPoints?keys?size > 0) >
<#list result.dataPoints?keys as key>
<tr>
<td width="35%">
<div>${key}</div>
</td>
<td width="45%">${result.dataPoints[key]}</td>
<td width="19%"> </td>
</tr>
</#list>
</#if>
Any idea how do I iterate over the map so that I get the same order?

This should do the trick:
<#if result.dataPoints?has_content >
<#list result.dataPoints.entrySet() as entry>
<tr>
<td width="35%">
<div>${entry.key}</div>
</td>
<td width="45%">${entry.value}</td>
<td width="19%"> </td>
</tr>
</#list>
</#if>
You may also need set object wrapper for freemarker template configuration. Like this:
BeansWrapper beansWrapper = (BeansWrapper) ObjectWrapper.BEANS_WRAPPER;
beansWrapper.setExposeFields(true);
config.setObjectWrapper(beansWrapper);
Where config is freemarker.template.Configuration.
If you using Spring Framework then extends FreeMarkerConfigurer:
public class FreeMarkerBeanWrapperConfigurer extends FreeMarkerConfigurer {
#Override
protected void postProcessConfiguration(Configuration config) throws IOException, TemplateException {
super.postProcessConfiguration(config);
BeansWrapper beansWrapper = (BeansWrapper) ObjectWrapper.BEANS_WRAPPER;
beansWrapper.setExposeFields(true);
config.setObjectWrapper(beansWrapper);
}
}

Related

asp.net core mvc, make view that all come from string object's html code as a string

I want to make a model that takes all the html codes from dynamic string object. Like this:
Model for dynamic html:
public class PageHtmlModel
{
public string HtmlCode { get; set; }
}
Entity Model
public class Entity
{
private int _ID;
private string _Module;
private string _Explanation;
private string _Situation;
private string _Personel;
private string _PersonelsNotes;
private string _EndDate;
public int id { get => _ID; set => _ID = value; }
public string module { get => _Module; set => _Module = value; }
public string explanation { get => _Explanation; set => _Explanation = value; }
public string situation { get => _Situation; set => _Situation = value; }
public string personel { get => _Personel; set => _Personel = value; }
public string personels_notes { get => _PersonelsNotes; set => _PersonelsNotes = value; }
public string end_date { get => _EndDate; set => _EndDate = value; }
}
DataAccesLayer:
public static string html()
{
PageHtmlModel pageHtmlModel = new PageHtmlModel();
//Thats All html page comes from string
pageHtmlModel.HtmlCode = "#model deneme100.Models.Entity <html> <head> <link href='~/css/invoice.css' rel='stylesheet' /> </head> <body> <div class='index-box'> <table cellpadding='0' cellspacing='0'> <tr class='top'> <td colspan='2'> <table> <tr> <td class='title'> <img src='~/img/logo.png' style='width:100%; max-width:300px;' /> </td> <td> #Html.DisplayNameFor(model => model.id):#Html.Raw(Model.id) <br>#Html.DisplayNameFor(model => model.module):#Html.Raw(Model.module) <br>#Html.DisplayNameFor(model => model.explanation):#Html.Raw(Model.explanation) </td> </tr> </table> </td> </tr> <tr class='information '> <td colspan='2 '> <table> <tr> <td> #Html.DisplayNameFor(model => model.situation):#Html.Raw(Model.situation) <br>#Html.DisplayNameFor(model => model.end_date):#Html.Raw(Model.end_date) </td> <td> </td> </tr> </table> </td> </tr> <tr class='heading '> <td> #Html.DisplayNameFor(model => model.personels_notes) </td> <td></td> </tr> <tr class='item'> <td> #Html.Raw(Model.personels_notes) </td> </tr> <tr class='total '> <td></td> <td> #Html.DisplayNameFor(model => model.personel):#Html.Raw(Model.personel) </td> </tr> </table> </div> </body> </html>";
return (pageHtmlModel.HtmlCode);
}
This is My Index Page For Open The Other Dynamic Model Pages
//This is catching object id for entity object
$('#myTable tbody').on('click', '#pdf', function () {
if (!($(this).closest('tr').hasClass('selected'))) {
table.$('tr.selected').removeClass('selected');
$(this).closest('tr').addClass('selected');
}
obj = {}
obj.id = $('tr.selected td').eq(0).html();
window.location = "/Home/PDF/" + obj.id;
if ($(this).closest('tr').hasClass('selected')) {
$(this).closest('tr').removeClass('selected');
}
})
Controller
public IActionResult PDF(int id)
{
var result = new EntityDataAccess.DataObject();
result.data = EntityDataAccess.OneObject(new Entity() { id = id });
return View(EntityDataAccess.html(), result.data[0]);
}
View => I just want to write this and see my all html page
#model myProject.Models.PageHtmlModel
#{
ViewData["Title"] = "PDF";
Layout = null;
}
thanks for helping from now
Well, you can use #Html.Raw() HTML helpers to bind your dynamic HTML on your view. Here is the example for you.
Controller Action:
[HttpGet]
public IActionResult BindDynamicToHtml()
{
StringBuilder sb = new StringBuilder();
var convertedHtmlBody = "";
sb.Append("<!DOCTYPE html>");
sb.Append("<html>");
sb.Append("<head>");
sb.Append("</head>");
sb.Append("<body>");
sb.Append("<p>Dear Coder,</p>");
sb.Append("<p>Please check the following answer. This is how you can generate dynamic HTML to View</p>");
sb.Append("<div style='max - height:500px; overflow: auto; width: 100 %; border - spacing: 0; '>");
sb.Append("<style> table, th, td { border: 1px solid black; } th{ padding:2px; } </style>");
sb.Append("<table style='width:20%;'>");
sb.Append("<tr>");
sb.Append("<th style='color:red;text-align:left;'>Test Bindings</th>");
sb.Append("<th style='text-align:right'>40</th>");
sb.Append("</tr>");
sb.Append("</table>");
sb.Append("<br />");
sb.Append("<table style='width:20%;text-align:center;'>");
sb.Append("<tr style='color:red;'>");
sb.Append("<th style='text-align:center'>Name</th>");
sb.Append("<th style='text-align:center'>Violations</th>");
sb.Append("<th style='text-align:center'>Details</th>");
sb.Append("</tr>");
sb.Append("</table>");
sb.Append("</div>");
sb.Append("<hr/>");
sb.Append("<p><strong style='color: red'>Note:</strong> For more details please check details: <a href='https://stackoverflow.com/users/9663070/md-farid-uddin-kiron'>Details</a></p>");
sb.Append("</body>");
sb.Append("</html>");
convertedHtmlBody = sb.ToString();
ViewBag.bindToHtmlInView = convertedHtmlBody;
return View(); ;
}
View:
#{
ViewData["Title"] = "BindDynamicToHtml";
}
#Html.Raw(ViewBag.bindToHtmlInView)
Output:
Note: If you would like to learn more about power of HTML helper you could refer to our official document here and this one
Hope it would help you to resolve your problem.

DropdownlistFor in a loop, null model on submit

I am having an issue with the values selected in multiple dropdownlistfor(s) being available in the controller when the form is submitted. The model is always blank. I know there are issues with mvc having dropdowns in loops but I thought I have solved for this. Let me know what you think.
View
#model DataDictionaryConversion.Models.FinalResults
#{ using (Html.BeginForm("SaveMapping", "Home", FormMethod.Post, null))
{
#Html.AntiForgeryToken()
<table class="table table-striped">
<thead>
<tr>
<th>Converted to Name</th>
<th>Your Project Name</th>
<th><input type="button"
onclick="checkAll()"/></th>
</tr>
</thead>
<tbody>
#{for (int x = 0; x < Model.DDObjects.Count(); x++)
{
var isSelection = false;
<tr>
<td class="filterable-cell">#Model.DDObjects[x].ObjectName</td>
<td class="filterable-cell">
#Html.DropDownList(Model.DDObjects[x].ObjectName, new
SelectList(Model.ProjectObjects, "ObjectName", "ObjectName"),
htmlAttributes: new { #id = "ddlObject", #class = "js-example-basic-single" })</td>
</td>
<td>
<input type="checkbox" id="NoValue-
#Model.DDObjects[x].ObjectName" name="NoValue-
#Model.DDObjects[x].ObjectName" onclick="byPassObject(this)" /> Object
Not
Used
</td>
</tr>
}
}
</tbody>
<tfoot>
<tr>
<td style="text-align:right; height:20px"><input
type="submit" class="btn btn-warning" value="Generate Conversion Mapping"
/></td>
</tr>
</tfoot>
</table>
}
}
Controller
[HttpPost]
public ActionResult SaveMapping([FromServices]ApplicationDbContext context, FinalResults model)
{
return View("Mapping");
}
Model
public class FinalResults
{
public IList<FinalObjectModel> ProjectObjects { get; set; }
public IList<Conversion_CSD_ObjectNameLearningModel> DDObjects {
get; set; }
FinalResults model is null
You're using Html.DropDownList. The first param there is a string, which should correspond with the name you're binding to. However, you're passing the value of Model.DDObjects[x].ObjectName, not literally something like "DDOjbects[0].ObjectName".
Instead, you should be using Html.DropDownListFor like so:
#Html.DropDownListFor(m => m.DDObjects[x].ObjectName, ...)
Then, the select list will be bound correctly.

Passing image to JSP in Spring MVC java with mango

Hi I am reading image from MongoDB and trying to pass that to JSP page but it is not passing properly from my controller. i am thinking i am almost edge to the solution but not getting exactly where i am doing mistake. Please let me know if you find any mistake.
here insertMedia method reading image from file and storing into DB and then returning back that image.
i am passing userMediaSave as image value to JSP, you can get that at tag like
img src=${userMediaSave} alt="Profile images"
My Controller:
#RequestMapping(value = "/userMediaSave", method = RequestMethod.GET)
public ModelAndView mediaLoadSuccess(HttpServletRequest request,HttpServletResponse response,
#ModelAttribute("mediaBean") MediaBean mediaBean) throws IOException, ServletException {
ModelAndView model = null;
File filePart = mediaBean.getMediaImage();
if (filePart != null) {
InputStream inputStream = new FileInputStream(filePart);
GridFSDBFile imageForOutput = null;
try {
imageForOutput = loginDelegate.insertMedia(inputStream, request.getContentType(), filePart.getName());
mediaBean.setExistedMedia(imageForOutput);
OutputStream out= null;
if(imageForOutput!=null){
InputStream is = imageForOutput.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
byte[]imagenEnBytes = buffer.toByteArray();
buffer.flush();
response.setContentType("image/jpg" );
response.setContentLength(imagenEnBytes.length);
model = new ModelAndView("userMedia");
request.setAttribute("userMediaSave", imagenEnBytes);
return model;
} else {
System.out.println("inside uploadMedia page -ve");
}
} catch (SQLException e) {
e.printStackTrace();
} finally{
//out.close();
}
}
return model;
}
JSP is:
<body onload="checkMessage()">
<form:form id="mediaForm" method="get" action="userMediaSave" modelAttribute="mediaBean">
<table border="1" cellpadding="1" cellspacing="1"
style="width: 500px;" align="center">
<tbody>
<tr>
<td colspan="4" align="center">Name : Welcome to Media App</td>
</tr>
<tr>
<td rowspan="3">Profile Image</td>
<td>Upload Images</td>
<td><input type="file" name="mediaImage" /></td>
</tr>
<tr>
<td> </td>
<td><input name="upload" type="submit" value="Upload" /></td>
</tr>
</tbody>
</table>
<table border="1" cellpadding="1" cellspacing="1"
style="width: 500px;" align="center">
<tbody>
<tr>
<td>User has some existed Media Album</td>
</tr>
<tr>
<td>
<img src=${userMediaSave} alt="Profile images" style="width:100px;height:100px;">
</td>
</tr>
</tbody>
</table>
</form:form>
am i passing image from controller to JSP properly? if not please let me know which way i have to pass it.

'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' 'object' does not contain a definition for 'intEmployeeId'

I am getting an exception when i trying to display the values of viewbag. I have joined two tables and stored that data in viewbag using Linq.
This is my controller action method
public ActionResult HRSeparationDetails()
{
//List<trnEsSeparationDetail> separationlist = (from list in db.trnEsSeparationDetails
// select list).ToList();
ViewBag.SeparationList = (from list in db.trnEsSeparationDetails
join R in db.mstEsEmpReasonForSeparations
on list.ReasonForSeperationId equals R.intSeperationId
select new
{
intEmployeeId = list.intEmpId,
ReasonForSeparation = R.txtReasonForSeperation,
ResiganationDate = list.dtResignationDate,
RelievingDate = list.dtRequestedRelievingDate,
SeparationRemarks = list.txtRemark
}).ToList();
return View();
}
This is my viewpage
#model IEnumerable<EMPApp.Models.trnEsSeparationDetail>
#{
ViewBag.Title = "HRSeparationDetails";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>HRSeparationDetails</h2>
<div>
#if (ViewBag.SeparationList == null)
{
<div style="color:green"><h3>#ViewBag.SeparationerrorMessage</h3></div>
}
else
{
<table class="grid" cellpadding="0" cellspacing="0">
<tr>
<th>
<b>Employee Id</b>
</th>
#*<th>
<b>ReasonForSeparationId</b>
</th>*#
<th>
<b>Reason For Separation</b>
</th>
<th>
<b>Resignation Date</b>
</th>
<th>
<b>Relieving Date</b>
</th>
<th>
<b>Separation Remarks</b>
</th>
</tr>
#foreach (var item in ViewBag.SeparationList)
{
<tr>
<td>
#item.intEmployeeId
#*#{
Session["SeparationEmpId"] = item.intEmpId;
}
#Html.ActionLink(Session["SeparationEmpId"].ToString(), "EmployeeDashboard", "HRAdmin", new { id = #item.intEmpId }, null)*#
</td>
#*<td>
#item.ReasonForSeperationId
</td>*#
<td>
#item.ReasonForSeparation
</td>
<td>
#item.ResiganationDate
</td>
<td>
#item.RelievingDate
</td>
<td>
#item.SeparationRemarks
</td>
</tr>
}
</table>
}
Any help will be appreciated. Thanks..
ViewBag is a dynamic object and your setting the property to a collection of anonymous objects. In you foreach loop
#foreach (var item in ViewBag.SeparationList)
item is typeof object and object does not have a property intEmployeeId (or any of the other properties your define in the anonymous object). One way to handle this is to create a view model with the properties you want to display
public class SeparationDetailVM
{
public int intEmployeeId { get; set; }
public DateTime ResiganationDate { get; set; }
....
}
and in the controller
var details = (from list in ....
select new SeparationDetailVM
{
intEmployeeId = list.intEmpId,
ResiganationDate = list.dtResignationDate,
....
}).AsEnumerable();
return View(details); // no need for ViewBag
and in the view
#model IEnumerable<YourAssembly.SeparationDetailVM>
....
#foreach (var item in Model)
{
....
<td>#item.intEmployeeId</td>
<td>#item.ResiganationDate</td>
....
}

MVC3 The model item passed into the dictionary is of type '_320.Models.MyViewModel', but

I am passing a viewmodel into a view containing a foreach loop. This viewmodel contains two lists. These lists are filled using Linq.
With the following code, I get the following error: The model item passed into the dictionary is of type '_320.Models.MyViewModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[_320.Models.MyViewModel]'.
I want to reach properties contained in the two lists in the ViewModel in my view's foreach loop.
UPDATE
I have been able to display the view by modifying the end of my controller code to:
List<MyViewModel> MyList = new List<MyViewModel>();
MyList.Add(_myViewModel);
return View(MyList);
However, it is an empty view with nothing but headers. When I attempt to change my fields in my view from something like #Html.DisplayFor(modelItem => item.rx.Rx_ID) to #Html.DisplayFor (modelItem => item.Rxes.rx.Rx_ID) it is labeled red. Is it impossible to access a property located that far down in a list?
END OF UPDATE
Model
public class MyViewModel
{
public Patient patient { get; set; }
public Rx rx { get; set; }
public Fill fill { get; set; }
public List<Rx> Rxes { get; set; }
public List<Fill> Fills { get; set; }
Controller
public ActionResult AllFilled()
{
MyViewModel _myViewModel = new MyViewModel();
List<Fill> FillList = db.Fills.Where(p => p.Status == "Filled").ToList();
List<Rx> RxList = new List<Rx>();
Rx myRx = new Rx();
foreach (var item in FillList)
{
myRx = db.Rxes.Single(p => p.Rx_ID == item.Rx_ID);
RxList.Add(myRx);
}
_myViewModel.Fills = FillList;
_myViewModel.Rxes = RxList;
return View(_myViewModel);
}
}
View
#model IEnumerable<_320.Models.MyViewModel>
#{
ViewBag.Title = "AllFilled";
}
<h2>AllFilled</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
NDC
</th>
<th>
Rx_ID
</th>
<th>
Fill_ID
</th>
<th>
Status
</th>
<th>
Filled Date
</th>
<th>
Filled By
</th>
<th></th>
</tr>
{
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.rx.NDC)
</td>
<td>
#Html.DisplayFor(modelItem => item.rx.Rx_ID)
</td>
<td>
#Html.DisplayFor(modelItem =>item.fill.Fill_ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.fill.Status)
</td>
<td>
#Html.DisplayFor(modelItem => item.fill.Filled_Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.fill.Filled_By)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id=item.rx.Rx_ID })
</td>
</tr>
}
</table>
Your view is expecting a model of type IEnumerable<_320.Models.MyViewModel> due to the first line in the view.
#model IEnumerable<_320.Models.MyViewModel>
If you want to use a model object of type MyViewModel (as coded in your controller), change this line to
#model _320.Models.MyViewModel

Resources