Splitting output of select box (Checkboxlist) in Umbraco using Razor - razor

I am trying to output the checked values of a checkBoxList on a view but keep getting an error when using the .split() method.
That's my loop with nothing separating the items:
#foreach (var item in Model.Content.GetPropertyValue<IEnumerable<string>>("robots"))
{#item}
But the output is as follow:
itemitem
And I would like it to be:
item, item
I have tried adding the .split() method but keep getting the error...
CS0117: 'System.Collections.Generic.IEnumerable<string>' does not contain a definition for 'Split'

I have also added some field to it but I dont see this as a decent solution, and it adds a coma at the end of the whole thing which is not ideal.
#foreach (var item in Model.Content.GetPropertyValue<IEnumerable<string>>("robots")){#item<text>,</text>}

Related

How to add an offset to an index in a *ngFor angular directive?

I want to display some data from a json but i can't simply add an offset to the index and show all te data from a certain offset but get
ERROR TypeError: Cannot read property 'id' of undefinedand the text in the div doesn't appear.
I have already tried to directly add a fixed number in the html file and it works (see the code below). But when it comes to use a variable "offset" (type:number) from typescript that is supposed to be updated with an input, the return type becomes undifined and the error appears. I also tried to use a method in my typescript file instead of doing the addition in the html file, and return the new index but it doesn't work and show the error. I also tried to call the method using {{addition(i,offset)}} and put the result in a variable that I use as an index but it still showing the error.
For exemple, this html file is working fine :
<ng-container *ngFor="let article of data; let i = index">
<ng-container *ngIf="i<(nbElements)">
<div (click)="checkArticle(data[(i+3)].id)">
<p class="text-center"> {{data[(i+3)][dataKey]}}</p>
</div>
</ng-container>
</ng-container>
The div reacts to my click and the text appears.
However, this html file is not working, even if the offset is set as 3 (as the html above) using an input in the parent component :
<ng-container *ngFor="let article of data; let i = index">
<ng-container *ngIf="i<(nbElements)">
<div (click)="checkArticle(data[(i+offset)].id)">
<p class="text-center"> {{data[(i+offset)][dataKey]}}</p>
</div>
</ng-container>
</ng-container>
The error appears.
The offset (type:number) is defined in my typescript file this way, and is changed by the parent component and can easily be displayed by the child component using console.log(offset):
export class AppColumnComponent implements OnInit {
#Input() offset : number ;
I expect the output to be texts showing the articles of my data json, but as I change the offset using an input like that data[(i+offset)] the result is an error, maybe it's impossible to use an other index using an other variable that a fixed number ?
Thank you for your support, it's my first post on stackoverflow i hope i did it well ! :)
If you want to make a pagination component, you should not rely solely on your HTML and some bindings.
Your component should have an "advanced" logic, in the sense that it should be able to know when it reaches the end/start of the collection (among other things).
Basically, this goes as follow :
Get the full collection (let's say 100 items)
Splice it to your item per page number (let's say 10, so results range is 0-10)
Test if items exist before the range
Test if items exist after the range
Allow/block page changing based on those variables.
This leaves you with
1 variable for the collection
1 variable (or 1 pipe) for the subset of the collection
1 variable for the items per page number
1 variable for the offset
2 booleans to disable pagination buttons.
Try working with this, and if you still have issues, then please provide a stackblitz with what you have tried !
You are accessing an index out of bounds.
data[(i+offset)] will be undefined for the last offset amount of elements in your data array so you are basically trying to do undefined.id which leads to your error.
You should change your method signature to only recieve the index as parameter and handle that case in your component.ts file

Need Validation on html dropdownlist with data from Viewbag

I know I'm not supposed to use the Viewbag and that I should build a menu using Html.DropDowlListFor() so that i can add attribute bound to the members of the model, BUT, that would involve a pretty extensive code rewrite....
I have a custom controller with a menu:
*.ASCX
<%: Html.DropDownList("CityIDs", new SelectList(ViewBag.cities, "Id", "Name"), "--Select--", new { style = "width:200px" })%>
<%= Html.ValidationMessage("CityIDs") %>
The List populates just fine and I can default to the top item to "--Select--"
The prbolem is that I want the validation error to occur on anything that is not from the viewbag.... how can I achieve this?
Validation for dropdown lists only ensures that something was posted. If you want to ensure that the value that was posted is actually one of a set of "allowed" values, then you'll have to manually do that in your post action:
var cityIds = db.Cities.Select(m => m.Id);
if (!cityIds.Contains(model.CityIDs))
{
ModelState.AddModelError("CityIDs", "You must select one of the available choices.");
}
if (ModelState.IsValid)
{
...
Two things:
Notice that I'm pulling the city ids straight from the database (the actual code you'd need here, of course, depends on your specific implementation). The important thing, though, is that ViewBag only survives a single request, so you can't look for them in ViewBag after posting.
Despite the pluralized name of CityIDs, using the DropDownList helper ensures that only a single selected value will exist. If this is actually supposed to be a multiselect, then you need to use ListBox instead, and update this conditional here to account for check for multiple values.
Populates the top item with Text = "--Select--" and Value = ""
which will post a blank value for CityIDs and cause an error in ModelState.

Accessing ListBox selected item via UiApp.getActiveApplication().getElementByID()

Currently I am using UiService to create a form and I uses ListBox, from what I understand to pass a value via handler will be something like e.parameter.[Name of ListBox] to access the selected item.
Does anyone know is it possible to use like app.getElementById([Name of ListBox]) to access the selected item. The reason I am using this method is because my list of ListBox-es are dynamic.
I spent some time looking for this answer as well, but finally I tried one idea and it worked.
You can use e.parameter as an array so you can these two will give the same:
e.parameter.LIST_BOX_NAME
and
e.parameter['LIST_BOX_NAME']
So in the second sample any dynamic list box ID can be used. I use same handler for all added dropdown list and have this code to check what dropdown was changed and what value it has now:
if (e.parameter[e.parameter.source] == 'a'){
To change the content of the listBox you can use app.getElementById('ID of the listBox'), from there you can clear() and addItems again but you cannot read the listItems.
When I need to do this I usually store the list of items somewhere else, in a place that I can read anytime, for example the list of items can be stored as a string in the listBox tag itself so I have all items at hand to repopulate the listBox after I have clear it.

Wordpress - Consecutive Nested Shortcode Execution Fails Without Line Breaks

If I have multiple items nested at the same level, such as a list and a enter it as such into the content of the page:
[list]
[list_item]My Item[/list_item]
[list_item]My Item[/list_item]
[list_item]My Item[/list_item]
[/list]
It renders fine. If I do the same and format it like this:
[list][list_item]My Item[/list_item][list_item]My Item[/list_item][list_item]My Item[/list_item][/list]
Every second list_item doesn't render properly. Does anyone know why this is and how to fix it?

How to print a tree using Razor

I'm trying to print a simple HTML tree structure, consisting of ul and li elements. I want to be able to pass the view an IEnumerable<T> where T has some hiearchy information (e.g. parent). Now I want the view to output the Tree control much like ASP.NET's Tree used to work. Is there any way to do this in MVC3 using Razor?
I've so far ended up doing it like this:
#PrintCategoryTree(Model.Where(x => !x.ParentCategoryID.HasValue))
#functions{
public IHtmlString PrintCategoryTree(IEnumerable<Aurora.Models.Category> levelCategories) {
if (levelCategories.Count() == 0) { return new HtmlString(String.Empty); }
System.Text.StringBuilder sb = new System.Text.StringBuilder();
TagBuilder childBuilder = new TagBuilder("li");
foreach(var item in levelCategories.OrderBy(x => x.Name)) {
childBuilder.Attributes.Clear();
childBuilder.Attributes.Add("id", item.CategoryID.ToString("N"))
var sub = PrintCategoryTree(Model.Where(x => x.ParentCategoryID == item.CategoryID));
childBuilder.InnerHtml = item.Name + sub.ToString();
sb.AppendLine(childBuilder.ToString());
}
TagBuilder tagBuilder = new TagBuilder("ul")
{
InnerHtml = sb.ToString()
};
return Html.Raw(tagBuilder.ToString());
}
}
The reason being, this is still in the Razor View. And I can keep my presentation logic in my view. It's not exactly what I'd hoped, but I thought I'd share it with you guys here anyway.
Sure it's possible. :) You can acctually go about this in a few ways.
Use something like jsTree and only output the first level of the tree. When a user expands a node, jsTree issues an AJAX callback to get more, and that's just a matter of loading the nodes underneath whatever they opened. I know that's not exactly what you asked, but I wanted to mention it.
If you can either modify the query or do a bit of pre-processing on the data before passing it to razor, change each item in the IEnumberable so that it also includes it's "level" in the tree (1 for a root node, 2 for it's child, 3 for a child of a child, etc). Outputting it at that point is pretty easy. Create a variable in the view holding the current level. When you go to the next row, check if the new level is the same as the old one. If it's not, either open or close enough <ul> tags that you get to the right one for that element.
If you can't do that either, you'll need to keep track of the nodes as you see them in razor. The reason why is that when you find a child from a node that isn't the last one you saw, you'll need to get that node back to figure out how many </ul> tags you need to add to get to the right level. Off the top of my head you could do that by having the view create a Hashtable with the row's key and level for each row you hit. Then when you hit an element and don't know where to put it, look up its parent in the hashtable (since you'll have already seen the parent assuming these are ordered correctly).
Far as I'm aware there's no "display this blob of stuff as a tree" command, so you need to write some logic to get the number of tags to build the levels correct. But hopefully that will help you get started. :)