EJS conditional statement change CSS - css

I have loop in EJS and I want to set css based on my data:
<% dummies.forEach(function(dummy) { %>
<div class="panel panel-???">
</div>
<% }) %>
my data:
var dummies = [{
type: "funny",
sure: "Yes" // this should generate panel-success
}, {
type: "funny", // this should generate panel-a
sure: "No"
}, {
type: "happy", // this should generate panel-b
sure: "No",
}];
So whenever sure attribute is Yes, it generates panel-success. Otherwise, it generates css based on type attribute.
Please help.

First create object like this:
<%
let cssClass = {
funny: {
Yes: "success",
No: "a"
},
happy: {
No: "b"
}
}
%>
Then you should just output value in template:
<% dummies.forEach(function(dummy) { %>
<div class="panel panel-<%= cssClass[dummy.type][dummy.sure] %>">
</div>
<% }) %>

Try using this code...
<% dummies.forEach(function(dummy) { %>
<div class="panel panel-
<% if (dummy.sure==="yes") { %>
success
<% else %>
<%= dummy.type %>
>
</div>
<% }) %>
You can just wrap your logic inside the EJS operators. It looks a little messy but it is what it is. Depending on how your server side is set up, you could also pass in parameters from the server side, instead of doing the logic on the client side.
The best way would depend on where the heavy lifting is done as far as trips to the database and any other logic going on.

I think this code will help :
<a class="<%= 1==2 ? 'active' : '' %>" href="#"></a>

Related

Rails: Embed child in submit_tag

I have this form:
= form_tag(path, name: "name") do |f|
= hidden_field_tag "abc", content
= submit_tag "" do
%i.icon.ion-android-sync
As you can see, I am trying to put an Ionicon inside the Form Submit tag.
I've tried a bunch of ways, none of which worked.
With the given example I get an empty button with an approximate width of 3px.
Is it possible to embed a child in a submit_tag? If, how would you go about doing so?
Thanks a lot for each answer!
The short answer is "no". However, you can make a button with type of "submit" that'll do the same thing and allow you to put content in it:
%button{type: "submit"}
%i.icon.ion-android-sync
No the Rails submit helper won't let you do that.
I use a custom submit helper in my app :
# Render a form submit button
# === Params
# +value+:: Value of the input/commit button, used for route constraints
# +text+:: Text for the button
# +:html_options+::
def submit(value=nil, text=nil, html_options={})
text ||= 'Submit'
html_options[:name] ||= 'commit'
html_options[:type] = 'submit'
html_options[:data] ||= {}
html_options[:data][:disable_with] ||= 'Please wait'
html_options[:autocomplete] = "off" # https://github.com/rails/jquery-ujs/issues/357
content_tag(:div, class: 'form-submit-wrapper') do
button_tag(html_options){ block_given? ? yield : text }
end
end
You can just pass whatever HTML you want in a block (sorry this is ERB, I'm not really familiar with HAML)
<%= submit do %>
<i class="icon ion-android-sync"></i>
<% end %>
The first two params are only helpful if you have several submit buttons for your form
<%= submit('preview_action', 'Preview result') do %>
<i class="icon ion-android-sync"></i>
<% end %>
<%= submit('really_do_action', 'Do it for real') do %>
<i class="icon ion-android-sync"></i>
<% end %>

Add class for css in ejs by node

Please mind the environment of this Application. I'm using
Windows
NPM ,Express
MySQL
This is the code in ejs template. example.ejs
<% if (message) { %>
<p class="alert " id="errorMessage">
<%= message %>
</p>
<% } %>
I want to add class to p.
This is what I am doing but didn't work.
messages = "Password Successfully Changed";
jQuery('#errorMessage').addClass('successMessage');
res.render('profile',{page_title:"My Profile",data:rows,message: messages});
I got the answer.
var messageData = {
message : "Password Successfully Changed",
class : "successMessage"
};
res.render('profile',{page_title:"My Profile",data:rows,message: messageData });
then on template side.
<% if (globalMessage) { %>
<p class="alert <%= globalMessage.class %>" id="errorMessage">
<%= globalMessage.message %>
</p>
<% } %>

silverstripe function to return menu level

I'm trying to write a function that returns what menu levels are visible on the page...at the moment I'm using <% if %> statements in the template, ie:
<div class="<% if Menu(1) %>navA<% end_if %> <% if Menu(2) %>navB<% end_if %> <% if Menu(3) %>navC<% end_if %>">...</div>
Which, if there are 3 menu levels on a page, returns <div class="navA navB navC">
What I want is a function that returns just the lowest level menu on the current page, ie <div class="navC">
Thanks
that's perfectly possible.
just add the following to your Page_Controller class:
function LowestLevel() {
$i = 1;
while($this->getMenu($i)->count() > 0) $i++;
return 'level'.($i-1);
}
now you can call it in your template like so:
<div>lowest level: $LowestLevel</div>
$LowestLevel will print 'level1', 'level2' etc.
in case your class names have to be like 'navA', 'navB'... you need to do some matching like 'level1'->'navA', which shouldn't be too hard - come back to me if you need any help on this.
What about the following (untested):
<div class="<% if Menu(3) %>navC<% else_if Menu(2) %>navB<% else %>navA<% end_if %>">...</div>
You might want to consider using some custom code in the Controller for logic-heavy stuff, but this should get you going...

I've created the worst tag soup of all time (ASP.NET MVC 2)

I am staring at the worst mess, my monitor isn't tall enough to see what is going on, and VS 2010 is no help at all.
I do not have any idea how to refactor this trash.
It's 11 AM and I feel like pouring a drink already.
Is this just the final proof that I have no business coding? Be honest.
<div id="followedFriends">
<% if (Model.FollowedFriends.Count() > 0)
{
foreach (var friend in Model.FollowedFriends)
{ %>
<div id="friendContainer">
<div class="followedFriend">
<div class="userName">
<%= Html.ActionLink(friend.FoFriend.UserName, "Visitor", "Home", new {userID = friend.FoFriend.UserId}, null)%></div>
Currently reading:
<br />
<div class="bookLinks">
<% if (friend.BookCount != 0)
{ %>
<% if (friend.BookCount <= 5)
{ %>
<%= friend.BookLinks%>
<%}
else
{ %>
<%:Html.ActionLink(friend.BookCount + " different books.", "Visitor", "Home", new {userID = friend.FoFriend.UserId}, null)%>
<%}
}
else
{ %>
Nothing, it appears...
<%}%>
</div>
<%if (friend.ReviewCount != 0)
{%>
New review for:
<div class="reviewLinks">
<%if (friend.ReviewCount <= 5)
{ %>
<%= friend.ReviewLinks%>
<%}
else
{%>
<%: friend.ReviewCount %>
different books
<%}%></div>
<%}
if (friend.QuoteCount != 0)
{%>
<span class="highlight">&#9656</span>
<%: friend.QuoteCount%>
new
<%if (friend.QuoteCount != 1)
{ %>quotes
<%}
else
{ %>
quote
<%} %>
<%}%>
</div>
</div>
<%}
}%>
</div>
<%} %>
Update
Since someone was asking, here is the pertinent portion of the View Model:
public class FollowedFriend
{
public aspnet_User FoFriend { get; set; }
public string BookLinks { get; set; }
public int BookCount { get; set; }
public string ReviewLinks { get; set; }
public int ReviewCount { get; set; }
public int QuoteCount { get; set; }
public FollowedFriend(Guid userID, DateTime lastVisit)
{
using (var context = new BookNotesEntities())
{
FoFriend = context.aspnet_Users.SingleOrDefault(u => u.UserId == userID);
var reading = context.Books.Where(b => b.UserID == userID && b.CurrentlyReading == true).ToList();
BookCount = reading.Count;
if (BookCount <= 5)
BookLinks = Book.ConvertBooksToLinks("Book/Details", reading);
else
BookLinks = "";
var recentBooks = context.Books.Where(b => b.UserID == userID
&& b.Review.DateCreated >= lastVisit).OrderByDescending(b => b.DateCreated).ToList();
if (recentBooks.Count <= 5)
ReviewLinks = Book.ConvertBooksToLinks("/Book/Details", recentBooks);
else
ReviewLinks = "";
ReviewCount = recentBooks.Count;
QuoteCount = context.Quotes.Count(q => q.UserID == userID && q.DateCreated >= lastVisit);
}
}
}
Let's start with a maxim that was initially proposed by Rob Conery: if there's an embedded "if" somewhere in your View, it's probably an indicator that you should either A.) create an HtmlHelper or B.) retract the logic from the view and insert it into your ViewModel.
By doing so, you can clean up your View to look something like this (you get the idea):
<div id="followedFriends">
<% foreach (var friend in Model.FollowedFriends) { %>
<div id="friendContainer">
<div class="followedFriend">
<div class="userName">
<%: Html.ActionLink(friend.FoFriend.UserName, "Visitor", "Home", new {userID = friend.FoFriend.UserId}, null)%>
</div>
Currently reading:
<br />
<div class="bookLinks">
<%: Html.DisplayBooklinks(friend) %>
</div>
<div class="bookReviews">
<%: Html.DisplayBookReviews(friend) %>
</div>
<div class="bookQuotes">
<%: Html.DisplayQuotes(friend) %>
</div>
</div>
</div>
<% } %>
</div>
At this point, if there's any chance that this piece of UI might be consumed in some other page, you should consider throwing it into a user control. By doing so, your view could now look something like this:
<% Html.RenderPartial("FriendDetails", Model.FollowedFriends); %>
Ultimately, whenever your View starts to look like soup, it's because your view is doing too much thinking. Which, in turn, means: some other layer of your application isn't thinking enough. By pinpointing logic in your Views, and by determining what abstractions might aid you in your attempt to remain DRY, your Views will become much more readable and much more maintainable.
I would factor some of that inline logic to an HtmlHelperExtension method and then create a DisplayTemplate "Friend"
<div id="followedFriends">
<% if (Model.FollowedFriends.Any()) {
foreach (var friend in Model.FollowedFriends) {
<%=Html.DisplayFor(friend) %>
<% } %>
<% } %>
</div>
And your DisplayTemplate "Friend" would look something like this:
<div id="friendContainer">
<div class="followedFriend">
<div class="userName">
<%= Html.ActionLink(friend.FoFriend.UserName, "Visitor", "Home", new {userID = friend.FoFriend.UserId}, null)%></div>
Currently reading:
<br />
<%=Html.BookInformation(friend) %>
<%=Html.BookReview(friend) %>
<%=Html.Quotes(friend) %>
</div>
</div>
</div>
Rather than making HtmlHelperExtensions you could just create more DisplayTemplates and specifically call them: DisplayFor("BookReview", friend)
Let me start by saying, we've all been there...
For your particular problem, I'd consider a few of the following "tools":
Partial Views: when you have a lot of nested <div> tags, for instance, you may want to consider creating some partial views where appropriate.
Use the Controller for Business Logic: Some of your logic should be done in the controller, where it's easier to break things up and call different helper methods to apply the logic. Consider passing to your view a custom object (a ViewModel if you will) that has all the business logic parsed. For example, things like displaying "quote" vs "quotes" could be done in a ViewModel object's "DisplayValue"-type property.
HTML Helpers: These little extensions can help take care of extracting the many if/else statements that you have into an easily readable method - and they could be re-used on other pages if written generally enough.
Lastly, I'd say, go get some fresh air and come back with only one thing in mind: simplify! Often we get caught up with a long list of tasks that need to be done and we get lost in our own soup or spaghetti or what-have-you. You'll need to approach the code with only refactoring in mind, until it's clean enough that you can tell where the next piece of logic should go.
I'm new to ASP.Net MVC, so I try to find coding conventions for me, too:
write <% %> tags in a separate line (except for <%: and <%=)
eliminate sequences of %><% (except for <%: and <%=)
keep C# and HTML indentation separate
indent <%= and <%: as if they where HTML tags (if they do represent HTML tag/s)
I'm not a ASP expert, but like in PHP isn't there a way to echo things? In place of using so much open and close tags? I should place everything above the code, and make variables that you use in your HTML?
In my opinion, this isn't awful. I think the key here would be to try to spend some time walking through it and commenting where blocks start and then their corresponding end tags. It'll be painful now, but it'll save you some time later on.
I'm assuming you're looking for a code review. In that case:
remove the empty ELSE block with the comment "nothing, it appears"
Combine the nested IF conditions into a single check IF( count != 0 && count < 5 )

MVC Html Helper Rendering

I was wondering if it's possible to render an Html Helper in a View inside a codeblock. So instead of:
<% = Html.TextBox("sometextbox", "somethingelse") %>
I want to do:
<%
switch(SomeParameter)
{
case "blah":
Html.TextBox("sometextbox", "somethingelse")
break;
}
%>
And have this render. Of course as it is, it wont render, so is there a way to programically decide if a textbox can be added without having to have a million delimiters in the page to accomplish this?
Thanks in advance!
<%
switch(SomeParameter)
{
case "blah":
%><%=Html.TextBox("sometextbox", "somethingelse")%><%
break;
}
%>
<%= %> is just a shorthand notation for Response.Write() though so the following should work too.
<%
switch(SomeParameter)
{
case "blah":
Response.Write(Html.TextBox("sometextbox", "somethingelse"));
break;
}
%>
All the HtmlHelpers return a string and don't output to the response stream directly by design.
Is this what your looking for?
<% switch (SomeParameter)
{
case "blah": %>
<%= Html.TextBox("sometextbox", "somethingelse") %>
<% break;
} %>

Resources