I would like to create a helper to return a text one character below the other. Something like that:
S
A
M
P
L
E
The purpose of this helper is to have a table with a heading of only 1 character wide. As you can see on the picture below this is ugly:
Example below looks nice:
I would like something like:
#Html.DisplayVerticalFor(x => x.MyText)
Any idea?
Thanks.
You can create an HTML helper DisplayVertical. (I am not adding the steps of how to create html helpers). The DisplayVertical will first split your text in character array and wrap each character inside a div or any other block level element, which can be inserted desired place.The implementation of DisplayVerticalFor can be something like this :
public static MvcHtmlString DisplayVertical (this HtmlHelper helper, string text)
{
string OutputString = "";
string assembleString = "<div>{0}</div>";
char[] textarr = text.ToCharArray();
foreach( char a in textarr )
{
OutputString += String.Format(assembleString, a);
}
return new MvcHtmlString(OutputString);
}
and in razor it will placed like this :
<div class="style-to-adjust-width-n-height"> #Html.DisplayVertical ("Sample") </div>
If you want to pass on a lambda expression to this html helper like this #Html.DisplayVerticalFor(x => x.MyText) then you need to add lambda expression parsing code to find out the text.
Lastly, this is a very rough code however you can add "TagBuilder" etc to make it more neat and clean.
Related
I have a large amount of numerical data to spit out in a table from a List of complex objects 'Dto'. Each property in the Dto object needs a row in the table, for example...
|dtos[0]|dtos[1]|dtos[2]|dtos[4]
prop1| w | x | y | z
prop2| a | b | c | d
Ideally I'd call a helper something like this...
#RenderTr("prop 1", model.Dtos, x => x.prop1);
#RenderTr("prop 2", model.Dtos, x => x.prop2);
...and it would loop through the Dtos list and spit out a td for each of the designated properties. Resulting in the following html...
<tr><td>prop 1</td><td>w</td><td>x</td><td>y</td><td>z</td></tr>
<tr><td>prop 2</td><td>a</td><td>b</td><td>c</td><td>d</td></tr>
I've tried looking into templated Razor delegates, helpers with fun and expression args but can't quite get my head around it.
Updated question to make more sense.
Best approach would be a custom extension method on HTMLHelper - passing in the row header, list of dtos and a member expression to let the method know which property you're after.
public static MvcHtmlString TableRowForProperty(this HtmlHelper htmlHelper, string rowName, IEnumerable<Financial> modelList, Expression<Func<Financial, decimal>> propertySelector)
{
var sb = new StringBuilder();
sb = sb.Append("<tr>");
sb.Append($"<td>{rowName}</td>");
foreach (var model in modelList)
{
var memberExpression = (MemberExpression)propertySelector.Body;
var propertyInfo = (PropertyInfo)memberExpression.Member;
var value = propertyInfo.GetValue(model);
sb.Append($"<td>{value}</td>");
}
sb = sb.Append("</tr>");
return new MvcHtmlString(sb.ToString());
}
You could make this a lot more generic, but this should be enough to get going with :)
I know how to split the string within a Controller or Domain class.
But i want to split the string inside the GSP.
My string will look like:
ASD25785-T
I want to be able to split this into 2 strings inside the GSP view.
String a = ASD25785
String b = T
Is it possible to do that inside the GSP?
How about something like this:
<%
String[] tokens = "ASD25785-T".split("-")
String b = tokens[0]
String c = tokens[1]
%>
NB. use try catch because you may get ArrayOutofBoundException
It depends if you have a predefind format or you want something generic.
Without try/catch and using the regex find method in String:
<%
String s="ASD25785-T"
String a,b
s.find(/(.+)-(.+)/) { fullMatch, first, second -> [
a=first
b=second
}
%>
If you are certain that there will always be a match, then it is a cute one-liner:
<%
String s="ASD25785-T"
def (a,b) = s.find(/(.+)-(.+)/) { fullMatch, first, second -> [first,second]}
%>
Source:
http://naleid.com/blog/2009/04/07/groovy-161-released-with-new-find-and-findall-regexp-methods-on-string
NB: However, if you want to use it in your view, you should create a tag. Grails taglibs are almost trivial to write, and much better to use in GSP code.
http://grails.github.io/grails-doc/2.4.x/ref/Command%20Line/create-tag-lib.html
http://grails.github.io/grails-doc/latest/guide/single.html#taglibs
Here's a string manipulation taglib
class StringsTaglib {
def split = { attrs, body ->
String input= attrs.input
String regex= attrs.regex
int position= attrs.index as Integer
out << input.split(regex)[position]
}
}
you could then use it like this:
a:<g:split input="ASD25785-T" regex="-" index="0"/>
b:<g:split input="ASD25785-T" regex="-" index="1"/>
I am using the entity framework with MVC3 and am trying to do a search on a description field but the problem is that description field has HTML in it eg "< div class="section" />". Can i do a funky search that searches only the stuff outside of the HTML tags?
return context.Categories
.Where(i =>
i.Name.Contains(searchText)
&& i.Description.Contains(searchText)
)
Thanks in advance!
Give HtmlAgilityPack a go. It has methods for extracting the text out of an HTML Document.
You basically just need to do the following:
var doc = new HtmlDocument();
doc.LoadHtml(htmlStr);
var node = doc.DocumentNode;
var textContent = node.InnerText;
Or the much less awesome method:
public static string StripHTML(string htmlString)
{
string pattern = #"<(.|\n)*?>";
return Regex.Replace(htmlString, pattern, string.Empty);
}
All together
return StripHTML(context.Categories.Where(i => i.Name.Contains(searchText)&& i.Description.Contains(searchText)))
I'm having trouble converting text to a hyperlink in a controller, then sending it to the view.
So far, I have:
Controller:
foreach (dynamic tweet in Timeline())
{
string text = tweet["text"].ToString();
const string pattern = #"http(s)?://([\w+?\.\w+])+([a-zA-Z0-9\~\!\#\#\$\%\^\&\*\(\)_\-\=\+\\\/\?\.\:\;\'\,]*)?";
Regex regexCheck = new Regex(pattern);
MatchCollection matches = regexCheck.Matches(text);
for (int i = 0; i < matches.Count; i++)
{
text = string.Format(#"<a href={0}>{1}</a>", matches[i].Value, matches[i].Value);
}
timeline.Add(text);
}
View:
#Html.DisplayFor(model => model.Timeline)
But It keeps displaying the literal text!
Display: <a href=http://t.co/fm0ruxjVXe>http://t.co/fm0ruxjVXe</a>
Could anyone please show me how this is done? I am quite new to MVC.
since you are sending out html already, try
#Html.Raw(Model.Timeline)
Another option is to send out just the url and the text and build the a tag in the view
#Model.Timeline.Text
That will involve changing your timeline property to being an object with two properties, text and url .
The #Html.DisplayFor helpers in Razor automatically encode the output
If you want to just output the content of model.Timeline, try just using Response.Write
I am trying to add multiple spaces in my var but it get's cut down to one space or it renders out & nbsp; as is. I have tried using & nbsp; and %20 any one have any other ideas?
ViewBag.Subheading = "Bringing to light";
I want it to look like this
Bringing to light
ViewBag.Subheading = "Bringing to light".Replace(" ", " ");
And
#Html.Raw(ViewBag.Subheading)
Or you could do something like:
public static MvcHtmlString DisplayAndRetainSpaces(this HtmlHelper html, string value)
{
return MvcHtmlString.Create(value.Replace(" ", " "));
}
Then call it like:
#Html.DisplayAndRetainSpaces(ViewBag.Subheading)
Use the entity for that: for each space you want.
EDIT: If you already tried and didn't work, there's an helper for outputing html, which should work with the entity:
#MvcHtmlString.Create(" ");