Does EJS support nested loops? - ejs

The outer loop will not iterate unless I remove the nested loop. Anyone have any ideas?
<% for (var i = 0; i < users.length; i++){ %>
<tr>
<td><%= users[i].firstname %></td>
<td><%= users[i].lastname %></td>
<td><select class="assign_dev"><option value="unassigned">unassigned</option>
<% for (var i = 0; i < developers.length; i++) { %> <!-- nested loop not working -->
<option value="<%= developers[i]._id %>"><%= developers[i].firstname %>
<% } %>
</select></td>
</tr>
<% } %>

I think you're reusing the variable i. Try to rename it to j in the inner loop.

Related

rendering different data values inside an ejs 'Scriptlet' tag

I'm kind of new to ejs ,I have been working on this ejs project we're part of my code involves me having to create a for statement which will loop through data in an object "data1" which is nested together with "data2" as follows
Data 1: var data1 = <%='some data'%> and
Data 2: var data2 = <%='second data'%>.
The code :
<% for (var i in data2.data1) {%>
"some action"
<%}%>
Problem is data2 is not being rendered when you include in the ejs 'Scriptlet' tag <% %>
Full code :
<html>
<body>
<table id="customers">
<tr>
<th align="center">
<% var clss = d2.className %>
<% for (var i in data[0].classes.clss.Monday
) {%>
<% var object = data[0].classes.clss.Monday
%>
<% if (object.hasOwnProperty(i)) { %>
<th><%- object[i][0] %></th>
<%}%>
<%}%>
</th>
</tr>
</body>
</html>

How to send email in Jenkins with groovy template?

I am using Jenkins server for CI and I am trying to send a post-build email using email-ext plugin and groovy template: appsgt.groovy, code below. My default content is empty and my pre send script field is as follows ${SCRIPT, script="managed:appsgt"}.
But I get an error # line 1 column for column 1: unexpected token <
If I change script to template I still get an error for another line, meanwhile email template testing creates nicely formated data.
<STYLE>
BODY, TABLE, TD, TH, P {
font-family:Verdana,Helvetica,sans serif;
font-size:11px;
color:black;
}
</STYLE>
<BODY>
<%
float versionadjust = 103.0f
float newversion = (build.number + 103) / 1000
def realVersion = newversion.round(3)
%>
<TABLE>
<TR><TD align="right"><IMG SRC="${rooturl}static/e59dfe28/images/32x32/<%= build.result.toString() == 'SUCCESS' ? "blue.gif" : build.result.toString() == 'FAILURE' ? 'red.gif' : 'yellow.gif' %>" />
</TD><TD valign="center"><B style="font-size: 200%;">BUILD ${build.result}</B></TD></TR>
<TR><TD>Build URL</TD><TD>${rooturl}${build.url}</TD></TR>
<TR><TD>Project:</TD><TD>${project.name}</TD></TR>
<TR><TD>Project version:</TD><TD>${realVersion}</TD></TR>
<TR><TD>Date of build:</TD><TD>${it.timestampString}</TD></TR>
<TR><TD>Build duration:</TD><TD>${build.durationString}</TD></TR>
</TABLE>
<BR/>
<!-- CHANGE SET -->
<%
def changeSet = build.changeSet
if(changeSet != null) {
def hadChanges = false %>
<TABLE width="100%">
<TR><TD class="bg1" colspan="2"><B>CHANGES</B></TD></TR>
<% changeSet.each() { cs ->
hadChanges = true %>
<TR>
<TD colspan="2" class="bg2"> Revision <B><%= cs.metaClass.hasProperty('commitId') ? cs.commitId : cs.metaClass.hasProperty('revision') ? cs.revision :
cs.metaClass.hasProperty('changeNumber') ? cs.changeNumber : "" %></B> by
<B><%= cs.author %>: </B>
<B>(${cs.msgAnnotated})</B>
</TD>
</TR>
<% cs.affectedFiles.each() { p -> %>
<TR>
<TD width="10%"> ${p.editType.name}</TD>
<TD>${p.path}</TD>
</TR>
<% }
}
if(!hadChanges) { %>
<TR><TD colspan="2">No Changes</TD></TR>
<% } %>
</TABLE>
<BR/>
<% } %>
<!-- CONSOLE OUTPUT -->
<% if(build.result==hudson.model.Result.FAILURE) { %>
<TABLE width="100%" cellpadding="0" cellspacing="0">
<TR><TD class="bg1"><B>CONSOLE OUTPUT</B></TD></TR>
<% build.getLog(100).each() { line -> %>
<TR><TD class="console">${org.apache.commons.lang.StringEscapeUtils.escapeHtml(line)}</TD></TR>
<% } %>
</TABLE>
<BR/>
<% } %>
</BODY>
${SCRIPT, script="managed:appsgt"}
^ That should be:
${SCRIPT, template="managed.template"}
...unless I'm misunderstanding your question.
source: https://wiki.jenkins-ci.org/display/JENKINS/Email-ext+plugin#Email-extplugin-Scriptcontent

Html.LabelFor inside a loop

I have the following code:
<% foreach (var orderDetail in Model.OrderDetails) { %>
<div><%= Html.LabelFor( x => orderDetail.DateOfBirth)%></div>
<div><%= Html.TextBoxFor(x => orderDetail.DateOfBirth) %></div>
<% } %>
The info is being displayed, however, I can't click on the label and go to the text box because the ID attribute is being repeated due to the foreach loop.
<label for="orderDetail_DateOfBirth">DateOfBirth</label>
<input type="text" value="" name="orderDetail.DateOfBirth" id="orderDetail_DateOfBirth">
Does anyone know how to fix this?
UPDATE:
I ended up doing it this way since UpdateModel() didn't work either, any thoughts?
<%
int i = 0;
foreach (var orderDetail in Model.OrderDetails) { %>
<div><label for="DateOfBirth_<%=i %>_">Date of Birth</label></div>
<div><%= Html.TextBox("DateOfBirth[" + i + "]", orderDetail.DateOfBirth) %></div>
<% i++
} %>
have a look at this post from phil haack
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
near the bottom of the article it talks about looping controls and using array indexes and whatnot.
Here's the basic syntax taken from there and adjusted to fit your senario.
<% for (int i = 0; i < Model.OrderDetails.count; i++) { %>
<%: Html.LabelForm(m => Model.OrderDetails[i].DateOfBirth) %>
<%: Html.TextBoxFor(m => Model.OrderDetails[i].DateOfBirth) %>
<% } %>
for the model binder to handle this properly it has to have sequential indexes. But other then that, this should work.
You can create custom id inside of the loop
i would use htmlAttributes to define the id.
Such as:
<%
int i = 0;
foreach (var orderDetail in Model.OrderDetails) {
%>
<div><%= Html.LabelFor( x => orderDetail.DateOfBirth)%></div>
<div><%= Html.TextBoxFor(x => orderDetail.DateOfBirth, new { id = "orderDetailDateOfBirth_" + i++ })%></div>
<% } %>
Or you can use :
jquery to identify object that you had clicked on using $(this)

If statement problem in MVC View

I am trying to show rows of data in a table with the following code. In case there is no data for the table I want a simple message to be printed. My code does print the rows of data as intended when there is data to show but when the list is empty it prints the table headings. How can I get rid of the headings and print the message instead?
<fieldset>
<legend>Department Membership</legend>
<% if(Model.departmentsDisplayCheck) {%>
<table>
<tr>
<th>Name</th>
<th>Type</th>
<th>Age</th>
<th>Gender</th>
<th>Status</th>
</tr>
<% foreach (var dep in Model.departmentsList){ %>
<tr>
<td><%: Html.ActionLink(dep.Name, "Details", "Department", new { id=dep.DepartmentID}, null) %></td>
<td><%: dep.Type %></td>
<td><%: dep.Age %></td>
<td><%: dep.Gender.ToString() %></td>
<td><%: dep.Status %></td>
</tr>
<% } %>
<% } %>
<% else { %>
<p><%: "You are not currently a member of any Department." %></p>
<% } %>
</table>
</fieldset>
First off these kinds of checks don't belong in a View. Instead you should have a property on your controller called something like DisplayDepartmentList and then set it using your checks (and any other business logic that may come up) there.
Then instead you are doing this check..
<% if(Model.DisplayDepartmentList)
<% if(Model.departmentsList != null && Model.departmentsList.Count > 0) {%>
Are you sure that the model is null and not just empty? If it's coming back empty then you'd get the observed behavior.
Try changing it to
<% if(Model.departmentsList != null || Model.departmentList.Count == 0) {%>

MVC : Model does not submit for multiple forms

This is related to ASP.Net MVC 2
I have a model (MoviesForAll) bound to my view and this model has a collection of class ICollection. I want my user to buy single ticket at a time by clicking submit button 'Buy this ticket' so I have placed a button besides each row representing the ticket details. This lead to following sequence
<%#Page Title="title" Language="C#" MasterPageFile="~/Views/Shared/MyMaster.Master"
Inherits="System.Web.Mvc.ViewPage<OnlineBooking.Movies.MoviesForAll>">
<Table>
<% for(i=0; i<Model.Tickets.count; i++)
{ %>
<tr>
<% using (Html.BeginForm(myaction(), FormMethod.Post, new {id="myform"}))
{ %>
<td>
<%= Model.tickets[i].ticketID %>
<%= Html.HiddenFor(m=>m.tickets[i].ticketID) %>
</td>
<td>
<%= Model.tickets[i].seatNo %>
<%= Html.HiddenFor(m=>m.tickets[i].seatNo) %>
</td>
...
...
<td>
<input type="submit" value="buy this ticket" runat="server">
</td>
<% } %>
</tr>
<% } %>
</table>
This creates a form for each row of tickets having single submit button in that form.
The problem is, when I submit first row (having index 0) by clicking the button, it gets submitted properly and I can see the values in controller method. But no other row gets through to controller even if I have used hidden fields to bind it.
Am I missing anything here specific to index or something?
Thanks in advance..
I would suggest having one form for all the rows, then on each row use the button element instead of an input as follows:
<button type="submit" value="<%= Model.tickets[i].ticketID %>" name="buyticket">Buy this ticket</button>
You should have a parameter on your controller action called buyticket and that should have the ticket id of the button which was clicked
How about the following:
<table>
<% for(i = 0; i < Model.Tickets.Count; i++) { %>
<tr>
<% using (Html.BeginForm("myaction", FormMethod.Post, new { id = "myform" })) { %>
<td>
<%= Model.tickets[i].ticketID %>
</td>
<td>
<%= Model.tickets[i].seatNo %>
</td>
...
...
<td>
<%= Html.Hidden("TicketId", Model.tickets[i].ticketID) %>
<%= Html.Hidden("SeatNumber", Model.tickets[i].seatNo) %>
<input type="submit" value="buy this ticket" />
</td>
<% } %>
</tr>
<% } %>
</table>
and then:
public class TicketToPurchaseViewModel
{
public int TicketId { get; set; }
public int SeatNumber { get; set; }
}
and the action:
[HttpPost]
public ActionResult myaction(TicketToPurchaseViewModel ticket)
{
...
}
Remark: notice that I have removed the runat="server" attribute from the submit button as well because this is something that you definitely don't want to see in an ASP.NET MVC application.