String manipulation(ASP.NET MVC) - asp.net-mvc

I have here a code that gets a portion of a record on my database and display it and has a link ("Read More") that renders the viewer to the detailed page of that record..
<% Dim id As Integer = _news.Rows(count).Item("IDnews")%>
<%=_news.Rows(count).Item("newsTitle")%>
<img src='<%= Url.Content("~/NewsPictures/" + _news.Rows(count).Item("newsThumbnail")) %>' alt="" />
<%Dim content As String = _news.Rows(count).Item("newsContent")%>
<%If content.Length > 50 Then%>
<%content = content.Substring(0, 150) & "..."%>
<%End If%>
<%=content%>
<%=Html.ActionLink("Read More", "NewsPublic", "Administration", New With {id}, DBNull.Value)%>
It displays something like:
We assure you that the U... Read More
I would like that the last word be completed before it is cut, or maybe 3 sentences should be displayed before it is cut. The last word in the above sample should be 'University'.

you could do something which finds the first space after the 150th character, or if it cant find a space extends to the end. e.g.
<%content = content.Substring(0, (content.IndexOf(" ", 150) < 0 ? content.Length : content.IndexOf(" ", 150))) & "..."%>
If you know there is a space after the 150 character then:
<%content = content.Substring(0, content.IndexOf(" ", 150)) & "..."%>
would be sufficient

content.Substring(0, content.IndexOf(" ", 150))

Replace the line
<%content = content.Substring(0, 150) & "..."%>
with
<%content = GetStartOfString(content, 150) %>
Then create a function similar to this in a utilities class or wherever you keep code that you reuse.
public static string GetStartOfString(string s, int length)
{
if (s.Length <= length)
{
return s;
}
if(s.IndexOf(" ",length) > 0)
return s.Substring(0, s.IndexOf(" ",length));
return s.substring(0,length);
}
This way you have all the code in one place rather than spread across multiple places. (DRY)
Also you could globalize the length in this method and have it work site wide with just a small change.

An alternative solution would be to have 2 fields in your database. One for the main Content and one for a Headline. The Headline provides a summary of the main Content and be limited to 150 characters. This would avoid any spaghetti code in your View and your content would be better described.

Related

Preserving whitespace / indentation in Rails database column

I have blocks of pseudo-code text stored in a database that get printed off line-by-line and displayed in HTML.
Pseudo-code entered in text column in database:
while (counter <= 10) {
printf("Enter grade: ");
scanf("%d", &grade);
total = total + grade;
counter = counter + 1;
} /* end while */
Controller:
def index
#code = Code.first // just a filler for the time being
end
Index:
- #code.cont.each_line do |line|
- i += 1
.line
%span= i
%li.line= line
- i = 0
Somewhere along the way Ruby automatically strips out any whitespace and just leaves me with the text. I'd like to know how to preserve this so that
This:
while (counter <= 10) {
printf("Enter grade: ");
scanf("%d", &grade);
total = total + grade;
counter = counter + 1;
} /* end while */
Doesn't come out as this:
while (counter <=
printf("Enter grade: ");
scanf("%d", &grade);
total = total + grade;
counter = counter + 1;
} /* end while */
I'm pretty sure your space characters are there, but you can't see them due to the way HTML handles whitespace. Double check this by putting your text into a variable and dumping it to console with a simple puts my_chunk_of_text. If the spaces are there (and I can't see why they wouldn't be, based on the code you posted), you have a couple of alternatives:
1) Sandwich your displayed text with the <pre> tag, which renders preformatted text. You're going to want to do this in your view, like this:
<pre><%= #my_chunk_of_text %></pre>
2) Save the text in HTML format, with non-breaking spaces ( ) wherever you want a space to appear, and <br> where you need a newline. This code can be rendered in your view with the html_safe helper.
<%= #my_chunk_of_text.html_safe %>

Implementing preview for markdown text

I am working on Ruby on Rails project and I have implemented markdown syntax for some text descriptions in my project using redcarpet gem.
It works like charm allowing to convert markdown text to HTML as simply as
<%= markdown some_text_variable %>
But now I want to implement preview feature rendering just small part of the full text.
The following naive construction
<%= markdown some_text_variable[0..preview_length] %>
will not work because it can easily break down MD syntax resulting in confusing constructions (imagine, for example, spliting original string on the half of image link).
I came up with
<%= markdown some_text_variable[0..preview_length].split(/\r?\n/)[0..-2].join("\r\n")) %>
but it does not deal, for example, with code blocks.
Is there any way to implement such kind of preview for MD text?
Using markdown.js and / or showdown should work. Here's a StackO with the same question and answer. I personally have used showdown in an Ember app before to render a live preview of the text as it's being typed (via 2-way data binding), and it worked flawlessly.
In the fiddle below, I wrote a little Showdown parser that takes in a string of markdown, splits it on a newline (returns an array of tags), and iterates through the array. On each iteration, it removes the tags, checks the length of the resulting string, and then compares it to the max character count for the preview. Once the next iteration surpasses the max character count, it returns the preview. The do loop ensures that you will always get at least one blob of html as a preview.
Fiddle
$(function() {
var converter = new Showdown.converter();
var previewMax = 200;
$('button').click(function() {
var content = $('#markdown').val(),
charCount = 0,
i = 0,
output = '';
if (!content) {
return $('div.preview').html("Please enter some text.");
}
var mark = converter.makeHtml(content);
var mark_arr = mark.split('\n');
while (charCount < previewMax) {
var html = mark_arr[i];
var text = htmlStrip(html);
if ((charCount + text.length) > previewMax) {
var overflow = (charCount + text.length) - previewMax;
var clipAmount = text.length - overflow;
html = jQuery.truncate(mark_arr[i], { length: clipAmount });
}
output += html;
charCount += text.length;
i++;
};
$('div.preview').html(output);
$('div.full').html(mark);
});
function htmlStrip (html) {
var div = document.createElement('div');
div.innerHTML = html;
var text = div.textContent || div.innerText || "";
return text;
}
});
REVISION
I updated the function using jQuery Truncate to cut the final string into an elipses so that all your previews are the same length as the others. Also, I realized that the original function returned a long string of undefined' over and over when no text was entered, so there is a check to eliminate that. Since this loop will always return at least one html item now, I changed the do loop to a while loop for easier reading. Finally, if you want your truncation to always end at a word boundary, pass the words: true option when you call it. Obviously, this will not give you the same level of truncation for every preview, but it will improve legibility. That's it!
I want to share my preview version it was quite simple with showdown.js and prism.js syntax highlighting.
Prism.js is syntaxing easily with JavaScript and CSS. All you need to pick specific languages and download it to assets folder. Or you can specify it to specific pages.
This is going to happen in realtime preview, in a form.
In Rails form:
<div class="col-md-12">
<div class="form-group">
<%= f.label :body %>
<%= f.text_area :body, class: "form-control", rows: 10 %>
</div>
</div>
<div class="col-md-12">
<h1> Preview Markdown </h1>
<div class="form-group markdownOutput"></div>
</div>
And add this script right below a form page.
<script>
function mkdown(){
var converter = new showdown.Converter(),
$post_body = $("#post_body");
// This line will keep adding new rows for textarea.
function postBodyLengthDetector(post_body){
var lines = post_body.val().split("\n");
post_body.prop('rows', lines.length+5);
}
// Textarea rows in default '10', when focusing on this. It will expand.
$post_body.focus(function(){
postBodyLengthDetector($(this));
$('.markdownOutput').html(converter.makeHtml($post_body.val()));
});
// All simple magic goes here, each time when texting anything into textarea
//it will be generated to markdown. You are able to see preview right below of textarea.
$post_body.keyup(function() {
postBodyLengthDetector($(this));
var value = $( this ).val(),
html = converter.makeHtml(value);
$('.markdownOutput').html(html);
});
}
$(mkdown);
$(document).on("turbolinks:load", mkdown);
</script>

IOS - unwanted hyperlink in UIWebView

got this html that i insert as string to uiwebview
<div style="font-family: sans-serif;">
<p><p><u>George Barret</u> </p>
<p>Irish,
1728/1732-1784 </p>
<p><b><i>An Extensive Wooded River Landscape
with Fishermen Hauling in their Nets in the Foreground</i></b><b>, </b></p>
<p><b>1760s</b></p>
<p>Oil on canvas<br><span style="font-size: 13.513513565063477px; line-height: 19.988739013671875px;">137 x 195.5 cm</span></p>
<p>Heritage Gift, IIB Bank, 2005</p>
<p><span>NGI.4750</span></p></p></div>
i got a blue hyperlink on "1728/1732-1784"
anyone know why and how can i disable this behavior ?
Thanks
myWebView.dataDetectorTypes = UIDataDetectorTypeNone;
This will prevent your UIWebView from converting anything (phone numbers, links, email addresses) into clickable links. The attribute detectorTypes is a bitmask, and you can specify any or all of the following values OR'd together:
enum {
UIDataDetectorTypePhoneNumber = 1 << 0,
UIDataDetectorTypeLink = 1 << 1,
UIDataDetectorTypeAddress = 1 << 2,
UIDataDetectorTypeCalendarEvent = 1 << 3,
UIDataDetectorTypeNone = 0,
UIDataDetectorTypeAll = NSUIntegerMax
};
For example, to turn only email addresses and phone numbers into clickable links you would use:
myWebView.dataDetectorTypes =
UIDataDetectorTypePhoneNumber | UIDataDetectorTypeAddress;

ASP.NET MVC Razor extra whitespace rendered

In Asp.net MVC, Razor inserts extra space between text blocks. I want to render a list this way: "1, 2, 3" but get "1 , 2 , 3".
#for (int i = 1; i < 3; i++)
{
<text>#i</text>
if (i != 2)
{
<text>, </text>
}
}
Is there any ways to remove extra whitespace ?
I want to render a list this way: "1, 2, 3"
Quick and dirty:
#string.Join(", ", Enumerable.Range(1, 3))
Obviously a custom helper seems more appropriate to the job of formatting something in the view:
public static class HtmlExtensions
{
public static IHtmlString FormatList(this HtmlHelper html, IEnumerable<int> list)
{
return MvcHtmlString.Create(string.Join(", ", list));
}
}
and then simply:
#Html.FormatList(Model.MyList)
You are seeing the extra whitespace between the number and the comma because your razor template includes a line break (which displays as whitespace in the browser) between the number and the comma:
#for (int i = 1; i < 3; i++)
{
<text>#i</text> >LINE BREAK HERE<
if (i != 2)
{
<text>, </text>
}
}
I like Darin's answer, and I would suggest removing your loop and replacing it with a more declarative statement, but if you don't want to go that far, try at least removing the line break:
#for (int i = 1; i < 3; i++)
{
<text>#i</text>if (i != 2){<text>, </text>}
}
Instead of writing out bits of text in different places each time round the loop, you could accumulate all the text in a StringBuilder, then outside the loop do #stringBuilderObject.ToString().
The problem is with the source that is generated. When you look at the actual source you get:
1
,
2
,
3
As you can see there is a lot of white space in there which browsers collapse down to a single space (look at the definition for normal).
Using a StringBuilder or string.Join is the way to fix this if all you're doing is outputting these three numbers. But if you're trying to do something else and this is a simplified example then see this blog post for a way of doing it using ol/ul and lis.
I might assume that it is not issue of Razor, but rather element is rendered with some margings.
Open FireBug (or Chrome or whatever) and see that it is really markup issue.
In you css file try to add
text { margin: 0 }

ActionLink only if a certain condition is met

If s = "N/A" then I don't want to use the ActionLink. In other words, if the inventory item is not currently being used on a project, then don't provide the link (just show N/A instead). Also, how do I send the link to Projects/Details? Right now, it will go to "Nails/Projects/Details" instead, because I'm using the NailsController class.
<td class="table-normal-data">
<% Dim l As Integer = InStr(item.CurrentProject, " [")
Dim s As String = item.CurrentProject
Dim projectID As String = ""
If l > 0 Then
s = Mid(item.CurrentProject, 1, l - 1)
projectID = Mid(item.CurrentProject, l + 2, Len(item.CurrentProject) - l - 2)
Else
s = ""
End If
%>
<%: Html.ActionLink(s, "Projects/Details", New With {.id = projectID}) %>
</td>
I'm much more familiar with MVC3/Razor and C#, but I often do something like this in my views:
#if( Model.Flag )
{
<span>n/a</span>
}
else
{
#Html.ActionLink(....
}
Basically, you output different stuff through the view depending on the state of the model.

Resources