Razor adding a white space before content - razor

I am outputting an address that I would like to comma separate.
If I don't include any html before outputting the address it is shown correctly without any additional spaces.
Example:
97 Glen Road, Holywood, BT18 0LE
Currently Getting:
97 Glen Road , Holywood , BT18 0LE
My code is:
<p class="no-margin-top">#Html.DisplayFor(modelItem => item.Address1)
#if(!string.IsNullOrEmpty(item.Address2)){
#:, #Html.DisplayFor(modelItem => item.Address2)
}
#if(!string.IsNullOrEmpty(item.Address3)){
#:, #Html.DisplayFor(modelItem => item.Address3)
}
#if(!string.IsNullOrEmpty(item.Town)){
#:, #Html.DisplayFor(modelItem => item.Town)
}
#if(!string.IsNullOrEmpty(item.County)){
#(", ")#("Co. ")#Html.DisplayFor(modelItem => item.County)
}
#if(!string.IsNullOrEmpty(item.Postcode)){
#(", ")#Html.DisplayFor(modelItem => item.Postcode)
}
#if(!string.IsNullOrEmpty(item.Country)){
#(", ")#Html.DisplayFor(modelItem => item.Country)
}
I have tried outputting the comma differently as shown above but still getting the same result.
I have also tried removing all spaces from the code as well as using #Html.Raw.
Would appreciate it if anyone has a fix for this or could suggest a better way of doing it.
UPDATE
Due to changes within the Framework Darin's solution will now produce errors.
You will need to ensure you are using System.Linq
Then amended Darin's code as follows:
public string FormattedAddress
{
get
{
var values = new[] { Address1, Address2, Address3, Town, Postcode, "Co. " + County }.Where(x => !string.IsNullOrEmpty(x));
return string.Join(", ", values);
}
}

WOW, this looks like a terrible mess you've ended up in your view. I would recommend you to use a view model and add the following property to your view model that will take care of properly formatting the address:
public string FormattedAddress
{
get
{
var values = new[] { Address1, Address2, Address3, Town, Postcode, "Co. " + County }
.Where(!string.IsNullOrEmpty);
return string.Join(", ", values);
}
}
and then in your view replace the mess with:
<p class="no-margin-top">
#Html.DisplayFor(modelItem => item.FormattedAddress)
</p>
and if now you tell me that you have violated all good practices and are not using view models, but are passing directly your domain entities to the view, well, other than telling you that this is wrong you could somehow hack it in the view:
<p class="no-margin-top">
#{
var values = new[] { item.Address1, item.Address2, item.Address3, item.Town, item.Postcode, "Co. " + item.County }
.Where(!string.IsNullOrEmpty);
var formattedAddress = string.Join(", ", values);
}
#formattedAddress
</p>
But honestly go use a view model.

Try forcing the comma plus space to be text using a razor text markup. It may be a razor interpretation problem.
{<text>, </text>#Html.DisplayFor(modelItem => item.Address2)}
Good luck

Related

HTML shows special character in the wrong order

I have a string that I want to display in the HTML.
But if the first character is a special character the HTML displays it in the wrong order.
for example if the string is :
#test : Twitter
I see it in the browser as:
I tried to change the direction using SCSS and adding space but still looks the same.
how do I display it correctly?
Thanks for any help :)
edit:
I'm working with Angular 8 and redux.
I'm creating the string in this selector:
const getMediaOutlet = createSelector<InquiryDetailsPartialState, InquiryDetailsState, BasicInfoDictionaryModel>(
getInquiryDetailsState, (state: InquiryDetailsState) => {
const mediaOutlets: MediaOutletsModel[] = JSON.parse(state.data.mediaOutlets);
return mediaOutlets && mediaOutlets.length ? {
titleTranslation: 'INQUIRIES.DETAILS.BASIC_INFO.MEDIA_OUTLETS',
value: mediaOutlets.map<DictionaryValueModel>(item => {
return { data:" "+item.text +" : "+ item.typeName } //<- here i build the string ;
}).filter(source => {
return source.data && source.data.length;
})
} : { value: [], titleTranslation: '' };
});
i used :
<bdi> </bdi>
and it maked at the right order.
you can do it this way using simple HTML. You don't have to mess up with any CSS as you can do with the only HTML
Example:-
<p>Start "&commat;" End.</p>

ES6 curly braces usage when extracting from an object and assigning to another object

I would like to use curly braces to replace this code:
let rUsers = children.map((user) => {
let rUser= {};
rUser.firstName = user.firstName;
rUser.lastName = user.lastName;
rUser.relation = user.patron.relation;
return rUser;
});
This is what I have:
let rUsers = children.map((user) => {
let rUser = {};
({
firstName: rUser.firstName,
lastName: rUser.lastName,
patron.relation: rUser.relation, // I get an error here
} = user);
return rUser;
}
Except for patron.relation, the rest of the extraction works.
Questions:
How should I extract value of user.patron.relation?
Is there a more succint way of writing the above?
Thanks!
How should I extract value of user.patron.relation?
You would use { … patron: {relation: rUser.relation}, … } as the destructuring target.
Is there a more succint way of writing the above?
If the property names don't match there's not much you can do, but in your particular case you can simplify by destructuring the parameter into multiple variables:
const rUsers = children.map(({firstName, lastName, patron: {relation}}) =>
({firstName, lastName, relation})
);
You can use object destructuring like this:
const {firstName, lastName, patron: {relation}} = user
And relation has been set to the value of user.patron.relation.
You can return the object you want like so:
return {firstName, lastName, relation}
I'm seeing a few things wrong with your code.
patron.relation -> patron isn't defined, and can't be used as a key.
In the second example, rUser is used - I think you just want user.
My understanding of what you're trying to do essentially create a clone? If so, you should be able to do something like this.
let rUsers = children.map(user => {
firstName: user.firstName,
lastName: user.lastName,
relation: user.relation
});
Alternatively, it could be simpler to use Object.assign()
let rUsers = children.map(user => Object.assign({}, user));

Nesting HTML in a string with mithril

I would like to generate the following HTML with Mithril's m:
<p>I am a <code>person</code></p>.
I'm currently using m.trust for this:
m.trust("<p>I am a <code>person</code></p>").
But I don't like the HTML string. Is there a better way to do this?
Yes, use m function to do this:
m('p', [
'I am a ',
m('code', 'person')
])
See a whole component here: https://jsfiddle.net/rtkhanas/02adbhkt/
Where the html string come from?
If you are writing your view, then use m('p', ...) instead of m.trust
For example, if only the "person" value is dynamic, you should have something like:
window.WhoAmI = {}
WhoAmI.controller = function(attr) {
var ctrl = this
ctrl.gender = m.prop(attr.gender)
}
WhoAmI.view = function(ctrl) {
return m('p', [
'I am a ',
m('code',
ctrl.gender()
)
])
}
If you get the whole html string from a request, then it's probably a bad thing, and you should try to rewrite your API (if possible) to send only the dynamic value to the client.
You should have something like this:
m.module(document.body, {
view: function() {
return m('p', [
'I am a ',
m('code', 'person')
]);
}
})

Trouble parsing Razor DropdownListFor(m => ListDictionary[key]) upon HTTP POST

I have a view model property to hold a list of dropdown selection values like:
private ListDictionary _claimDropdownValueCollection = new ListDictionary();
public ListDictionary ClaimDropdownValueCollection { get { return _claimDropdownValueCollection; } set { _claimDropdownValueCollection = value; } }
On doing the GET, I am looping over a different ListDictionary also in my view model which contains "dropdown type" names:
#foreach (System.Collections.DictionaryEntry de in Model.CCSetting_ClaimDropdownTypeCollection) {
<div class="formRow">
<label>#EverythingToDoWith_CCSetting_ClaimDropdownTypes.getDropdownTypeName(Model.ccClaim.clientID, Convert.ToInt32(de.Key))</label>
<div class="formRight searchDrop">
#Html.DropDownListFor(m => m.ClaimDropdownValueCollection[#de.Key], (IEnumerable<SelectListItem>) #de.Value, new { #class = "chzn-select", #data_placeholder="Choose an option...", #style="width: 350px;" })
</div>
<div class="clear"></div>
</div>
}
So basically, this loads a bunch of dropdowns, their 'label' is printed as per the key in the dictionary. The 'values' for EACH dropdown are obtained from the VALUE of each dictionary, which contains an IENUMERABLE each.
All good so far. Now the user makes his selection on each dropdown and I do an HTTP POST. In the browser developer tools, I see the following data being posted back:
ClaimDropdownValueCollection[1]:2
ClaimDropdownValueCollection[2]:5
ClaimDropdownValueCollection[3]:
ClaimDropdownValueCollection[4]:11
So that is 4 dropdowns with keys 1,2,3,4 (my keys will be more complicated, simple keys here for my example's sake) and three of the four have selections so I pass back the selected ID's 2, 5 and 11.
But the problem is, I am unable to see this data as part of the view model listdictionary object when I debug inside the [HttpPost] controller method that receives the posted data. That is showing the "ClaimDropdownValueCollection" property to be empty.
I am expecting to be able to say something like:
foreach (DictionaryEntry de in vm.ClaimDropdownValueCollection) {
//do something here with de.Key and de.Value
}
So what am I doing wrong in the RAZOR code?... Help!
The issue was with the HTML helpers and how I was posting back. Here's how I resolved it (thanks to my CTO at work!):
Created my view model property that will serve as the resource to populate from as:
Dictionary<int, List<SelectListItem>> CCSetting_ClaimDropdownTypeCollection
Created another dictionary with the SAME KEYS, whose VALUE will be the users selection:
Dictionary<int, int> ClaimDropdownValueCollection
Now on the RAZOR side, I am doing something like this (note the use of HTML.Hidden, and HTML.Dropdown instead of HTML.DropdownFor):
#foreach (var de in Model.CCSetting_ClaimDropdownTypeCollection) {
<div class="formRow">
<div class="formRight searchDrop">
#Html.Hidden("ClaimDropdownValueCollection[" + #de.Key + "]", #de.Key)
#Html.DropDownList("ClaimDropdownValueCollection[" + #de.Value + "]", #de.Value, new { #class = "chzn-select", #data_placeholder="Choose an option...", #style="width: 350px;" })
</div>
<div class="clear"></div>
</div>
}
Sorry about not wording my question in a better way perhaps, I perhaps posted after hours of frustration and ended up doing a bad job at phrasing it. Getting the 'Tumbleweed' badge for this question motivated me to come back and post the solution. OK to close, hope someone someday runs into this!

(Razor) String length in Html.Helper?

This is a very simple question.
I have a Html.helper:
#Html.DisplayFor(modelItem => item.Text)
How to I cut down the string from item.Text to a specific length? I wish you could do a SubString or something directly on the item.Text.
If youre wondering why I want this, its because the strings are very long, and I only want to show a bit of it in like the index view etc.
I needed the same thing and solved the case with the following lines.
<td>
#{
string Explanation = item.Explanation;
if (Explanation.Length > 10)
{
Explanation = Explanation.Substring(0, 10);
}
}
#Explanation
</td>
If your string is always larger than 10, you can rule out:
if (Explanation.Length > 10)
{
Explanation = Explanation.Substring(0, 10);
}
And directly write:
string Explanation = item.Explanation.Substring(0, 10);
Also I recommend adding .. for strings larger than the limit you give.
There are 3 possibilities that could be considered:
Strip the text in your mapping layer before sending it to the view (when converting your domain model to a view model)
Write a custom HTML helper
Write a custom display template for the given type and then 3 possibilities to indicate the correct display template: 1) rely on conventions (nothing to do in this case, the template will be automatically picked) 2) decorate your view model property with the UIHint attribute 3) pass the template name as second argument to the DisplayFor helper.
You could just add a property onto your view model that does the truncation of the string and display that instead:
// View model
public string TextShort { get { return Text.Substring(0, 10); } }
// View
#Html.DisplayFor(modelItem => item.TextShort)
Change
#Html.DisplayFor(modelItem => item.Text)
to
#Html.Display(item.Text.Length > 10 ? item.Text.Substring(0,10) : item.Text)
Edited : New Answer
what about
#{
modelItem.ShortText= model.Text.Substring(0, ....);
}
#Html.DisplayFor(modelItem => item.ShortText)
The prototype for DisplayFor is :
public static MvcHtmlString DisplayFor<TModel, TValue>(
this HtmlHelper<TModel> html,
Expression<Func<TModel, TValue>> expression
)
And the modelItem is a dynamic I think, so it should be possible to add anew property to the view model.