Dynamic table with razor - c#

hello I have a question following the advice of you Razor View dynamic table rows, I made my table with foreach but not and could manage to make you create new columns, if I add a record is put in the same column, does not make a jump for another column, What can I do in this case? So I have my view on razor
<div>
<table>
<tr>
#foreach (var item in product)
{
<td>
<div class="card" style="width: 18rem; margin-top:3rem; margin-right:3rem; margin-bottom:2rem; margin-left:3rem; position:initial">
<img src="https://scontent.fntr8-1.fna.fbcdn.net/v/t1.0-9/107865247_704094323779323_2201784036865521556_n.jpg?_nc_cat=101&_nc_sid=8bfeb9&_nc_ohc=FwSgbE0cEAAAX92rcFt&_nc_ht=scontent.fntr8-1.fna&oh=4ec8b36ac7d0080b2f2bb3096b7b38cc&oe=5F37D400" class="card-img-top" alt="...">
<div class="card-body">
<h2 class="card-title">#item.ProductName</h2>
<p class="card-text">#item.Description</p>
<h4 class="card-text">Stock</h4>
<p class="card-text">#item.UnitInStock</p>
<h4 class="card-text">Color</h4>
<p class="card-text">#item.Color</p>
<h3 class="card-text" style="align-content:center">$#item.Price</h3>
<p class="card-text">#item.CreationDate.ToShortDateString()</p>
<AuthorizeView>
<Authorized>
Editar
<button class="btn btn-danger" #onclick="#(() => EliminarProduct(item.Id))">Eliminar</button>
</Authorized>
<NotAuthorized>
</NotAuthorized>
</AuthorizeView>
</div>
</div>
</td>
count++;
if (count % 3 == 0)
{
#:</tr>
#:<tr>
}
}
</tr>
</table>
</div>

I have a bit of difficulty understanding your question; I am sure you are doing your best to explain your problem.
So excuse me if this does not answer your question.
I think I see what you are trying to do there; placing 3 blocks in a row then followed by 3 other blocks.
One of the problems I foresee is that when you have exactly %3 items (so you have for instance 6 items), the last one will add a to your html and then the loop will end and add one more . So rather than checking %3 you should also check if you aren't at the last item; So something like this
if (count % 3 == 0 && count != product.Count())
May I make a suggestion that you use divs instead of a table? Just generate a div for each block and use css to style them. Depending on your solution you could even number your divs with a different class name (like: class1, class2, class3) and give them each a specific css or you could add float: left to each div and add clear: both; to the first one in your row.
The best way however would be using css where you would place any number of objects on a row as much as the width of the page permits you.
One more thing; if you want to list items in blazor it is wise to add the #key tag to each div or tr.

Related

Bootstrap SelectPicker Extends Past Panel Heading

I am currently using Bootstrap's SelectPicker and am trying to display it inside a panel heading, aligned to the right, next to a few Bootstrap buttons. My problem is that the Bootstrap dropdown is too wide. It extends past where the panel heading ends. I have attempted to change the width to the dropdown, and by using other options such as float: right and drop-down-menu right instead of pull-right, but no cigar. I have attempted to change the CSS for the selectpicker and have tried to change it's position with Jquery, but it remains the same width and does not change. Here is a sample of my code below:
#if (Model.Customers != null && Model.Customers.Any())
{
<select name="custDropdown" id="custDropdown" class="selectpicker pull-right" title="Select a Customer...">
#foreach (var customer in Model.Customers)
{
<option value="#customer.UserName">#customer.FirstName #customer.LastName</option>
}
</select>
}
else
{
<select class="selectpicker pull-right" title="No Users for this Customer" disabled></select>
}
<div class="panel panel-default">
<div class="panel-heading">
Claim Activity
</div>
</div>
I haven't included my other buttons in this code sample, but they all have the class pull-right associated with them too. I've done a ton of research into this, but I haven't found any useful articles or threads with people trying to do this with a select statement, only with dropdown buttons. I know dropdowns act weirdly in comparison to buttons when trying to apply pull-right to them, but it doesn't make sense to me why it would extend past the panel heading. I know that it doesn't have to do with how long the name is inside of the dropdown. The names being displayed now are relatively short and the width does not change no matter how long or short they are. If anyone has any suggestions or know what I could do to fix this, that would be great. Here is an image for reference of what I'm talking about below:
I ended up solving the issue. Turns out, the problem was with the CSS of the SelectPicker. I was just looking in the wrong place when trying to modify the CSS before. The width was set at 100%, and I had to shorten it down to 82.5%.
.bootstrap-select > .dropdown-toggle {
width: 82.5%;
padding-right: 25px;
z-index: 1;
}

Retrieving deep nested values looping through a HTML page using HTMLAgilityPack C#

I'm trying to use the HTMLAgilityPack to retrieve various specific values from a web page. The web page is always the same an the data I want to scrape from it is always in the same place (same divs/classes/attributes etc).
I've tried to loop through and get the values, but I always mess up somewhere. I'd provide some code to help but honestly I've tried 5 times and each time I don't get results close to what I want to - I'm well and truly in a pickle.
I have written the main chunk of HTML:
<div id ="markers">
<div class="row">
<div class="span2 filter-pane ">
<div class="teaser teaser-small">
<h1 class="teaser-title">
...
</div>
<p> Value4 </p>
</div>
</div>
<div class="span2 filter-pane ">
</div>
<div class="span2 filter-pane ">
</div>
</div>
<div class="row"></div>
<div class="row"></div>
</div>
Basically the values (1-4) are the values I want to extract from the data.
The <div id="markers"> is ONE div on the page, all the information I need is in this div.
There are multiple <div class="row"> divs, I need to loop through all of these.
Inside each of these divs, there are three or less <div class="span2 filter-pane "> divs. I need to loop through these 3 divs also.
My data is inside here - Value3 is here in the <p>...</p>. And the other values can be found within the <h1 class="teaser-title"> node, where they are attributes in an <a> element.
I hope somebody can provide me with a solution, or at least some good guidance to accessing all pieces of data I want. I've tried various things but I don't get the results I want.
Thanks.
Here are some hints for you. So first you need to get div#markers because you mentioned that it contains all your info you need.
string mainURL = your url;
HtmlAgilityPack.HtmlWeb web = new HtmlAgilityPack.HtmlWeb();
HtmlAgilityPack.HtmlDocument doc = web.Load(mainURL);
var markerDiv = doc.DocumentNode.Descendants("div").FirstOrDefault(n => n.Id.Equal("markers');
//Check if marketDiv is null or not
//Same idea, get list of row divs
var rows = marketDiv.Descendants("div").HasClass("row") //I will provide .HasClass function or you can write your own, it's simple;
//Iterate throw your rows object
//for each row object
var aElement = row.Descendants("a").FirstOrDefault()//you can have more criteria here if it has more than 1 a element
aElement.GetAttributeValue("data-lat", "") //will return Value1 here, do the same thing for other attributes and p.
Hope it helps

MVC 6 Best way to send parameters to view

I would like to know what is the best way to send a parameter to a view.
This is my first time with MVC.
I have a menu and I would like to change the item menu class depending which item menu is selected.
For example I have a menu with Home, Products, About.
<div class="nav-main-item">
<a asp-controller="Home" asp-action="About">
<div class="top-solid-line selected"></div>
<div class="row nav-item">
<div class="item-line-1">
Home
</div>
</div>
</a>
</div>
<div class="nav-main-item">
<a asp-controller="Home" asp-action="Products">
<div class="top-solid-line"></div>
<div class="row nav-item">
<div class="item-line-1">
Products
</div>
</div>
</a>
</div>
<div class="nav-main-item">
<a asp-controller="Home" asp-action="About">
<div class="top-solid-line"></div>
<div class="row nav-item">
<div class="item-line-1">
About
</div>
</div>
</a>
</div>
If I select Products I want to add the class 'selected' to it, and remove the class selected to the item menu was selected before an so on.
I know how to do it in jquery, is very simple, but the thing is when I click one of the items menu the selected class continue in the home item menu, that is because I initialize the selected on the Home item menu.
I need some kind of parameter to pass to the view and depending on that value add the class selected to the item menu selected.
I know should be very simple, any help will be appreciate it!
Thanks.
In the controller you can use return View(model), where model is some variable or object. In the cshtml file you can then declare #Model int for instance, when passing an integer and access it like a normal variable as model. For instance: #if (model == 1){ your code here }.
EDIT: you can also add parameters to the ViewBag (google it, there are lots of examples) but I would use the model since it is strongly typed.
ASP.NET MVC Send Multiple Data to View
My opinion
ViewBag, ViewData,TempData is basic solution method exm: (alert, message, script vb. other run client-side code and single data) but write a long code line this dirty and complexible. But using ViewModel property is best solve so your code is not complexible and full compatible Object Oriented Programming architecture.
Understanding ViewModel

umbraco 7: get property value

I am using umbraco 7 ASP.NET C# MVC 4.
Im trying to use the new umbraco, so far its been ok, but i need to get a property of one of my pages i set up.
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var homePage = CurrentPage.AncestorsOrSelf(1).First();
var menuItems = homePage.Children.Where("isMenu == true");
}
<!-- Nav -->
<div class="row">
<div class="col-md-12 top-menu-container">
<ul>
#* If the Url of the current page is "/" then we want to add the class "current_page_item" *#
#* Otherwise, we set the class to null, that way it will not even be added to the <li> element *#
<li>
<div onclick="location.href='/';" class="col-md-2 metro-container" style="background-color:##Model.Content.GetPropertyValue("navigationColor")" >
<img class="menu-img" src="../../media/1001/home.png" alt="" />
Home
</div>
</li>
#foreach (var item in menuItems)
{
#* If the Id of the item is the same as the Id of the current page then we want to add the class "current_page_item" *#
#* Otherwise, we set the class to null, that way it will not even be added to the <li> element *#
<li>
<div onclick="location.href='#item.Url';" class="col-md-2 metro-container" style="background-color:##item.Content.GetPropertyValue("navigationColor")" >
<img class="menu-img" src="../../media/1001/home.png" alt="" />
#item.Name
</div>
</li>
}
</ul>
</div>
</div>
So the first "li" outside the loop i simply get the models content Getproperty method which surely enough gets me any property i tell it too.
However the loop i have although goes through the current pages children, i cant seem to get a specific property.
Makes it worse is intellicense Isn't working as its all runtime.
The line in question is
<div onclick="location.href='#item.Url';" class="col-md-2 metro-container" style="background-color:##item.Content.GetPropertyValue("navigationColor")" >
I need to get the color that was set on the page from the navigationColor control.
What am i doing wrong here?
Big derp on my side.
The item var in the foreach loop already has property's contained in the item.
all you need to do is
item.NameofYourPropertyAlias
and that should do it.
The following code works for me:
item[index].GetProperty("name").Value
Makes it worse is intellicense Isn't working as its all runtime.
The problem is that you're using dynamic model instead of the strongly typed kind.
Instead of using CurrentPage you can use Model.Content.
So instead of:
var homePage = CurrentPage.AncestorsOrSelf(1).First();
Use:
var homePage = Model.Content.AncestorOfSelf(1);
Intellisense will then work after you type a stop after homePage.
I would also strongly recommend inputting using Umbraco.web with the rest of your using statements at the top of the template. This should further improve intellisense, and allow you to see methods such as .GetPropertyValue<T>(string alias).
You should then be able to use item.GetPropertyValue<string>("navigationColor").
item.NameofYourPropertyAlias
this is the proper use of item while looping

How do I create a two-column snaking layout in ASP.NET MVC?

I have about a hundred short-text data items (this number can vary substantially) that I would like to put in a page and have the browser manage that into three columns within a surrounding div, arranged with the items going down and then across, like this:
A F L
B G M
C H N
D I O
E K ...
Is there a way to render this out as li's (or maybe just individual lines), and have the browser automatically collate it into three equal-height columns, possibly using CSS?
Are there any browser compatibility issues?
Without browser compatibility issues:
<% var rows = source.Count() % 3 == 0 ? source.Count / 3 : (source.Count / 3) + 1; %>
<table>
<% for(int i=0; i<rows; i++) { %>
<tr>
<td><%= source.Skip(i).FirstOrDefault() %></td>
<td><%= source.Skip(i+rows).FirstOrDefault() %></td>
<td><%= source.Skip(i+rows*2).FirstOrDefault() %></td>
</tr>
<% } %>
</table>
We use the modulus operator to let us know if the division is even or not... if it is not, we're not going to add an extra row for the leftover columns. For more information, see http://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx
For example look at https://stackoverflow.com/users HTML source - it uses <table>
In the CSS world this is the only way I know to do three columns outside of a table of course.
<html>
<div style="width:100px">
<div style="float:left; width:33%;">a</div>
<div style="float:left; width:33%;">bsdf</div>
<div style="float:left; width:33%;">c</div>
<div style="float:left; width:33%;">d</div>
<div style="float:left; width:33%;">e</div>
<div style="float:left; width:33%;">f</div>
<div style="float:left; width:33%;">g</div>
</div>
</html>
Clearly you wouldn't use all those style tags, instead you'd use an actual style. Notice the 33% as the width.
I tried this in IE and FirFox and no probs on either.
After Xandy suggested Javascript, I did some googling for jQuery plugins, and found this:
Newspaper Columns JQuery Plugin
http://www.webmeisterei.com/petznick/2007/05/16/newspaper-columns-jquery-plugin/
Usage:
You need a Container with Elements like
<div id="npContainer">
<div class="npItem">Item1</div>
<div class="npItem">Item2</div>
</div>
...and you need the Columns
<div id="npColumn1"></div>
<div id="npColumn2"></div>
<div id="npColumn3"></div>
In Javascript just call:
jQuery().npColumns();
A web page that uses the plugin
http://www.bregenzerwald-news.at/?classifieds=1
<div style="float: left">A</div>
<div style="float: left">B</div>
<div style="float: left">C</div>
<div style="float: left">D</div>
<div style="float: left">...</div>
Then place these into a div that has its width correctly set.
html can be (actually doesnt really matters):
<div class="3col_vert">
<div>a</div>
<div>b</div>
<div>c</div>
<div>d</div>
...
</div>
In javascripts (example in jquery in particular), you have to wrap them with cols, so that the resulting html (after manipulation of javascript) will become:
<div class="3col_vert">
<div class="col_left">
<div>a</div> ...
</div>
<div class="col_centre">
<div>e</div> ...
</div>
<div class="col_right">
<div>g</div> ...
</div>
</div>
Jquery to mainpulate will be:
var vert_divs = $(".3col_vert div");
// Remove them from parent
$(".3col_vert").empty()
.append("<div class='col_left'></div>") // append the wrapper cols to parent
.append("<div class='col_center'></div>")
.append("<div class='col_right'></div>");
// Now place them to the wrappers
var totalDivs = vert_divs.length; // count number of match divs
vert_divs.each(function(i) {
if (i < totalDivs / 3)
$(this).appendTo(".3col_vert div.col_left");
else if (i<totalDivs * 2/3)
$(this).appendTo(".3col_vert div.col_center");
else
$(this).appendTo(".3col_vert div.col_right");
});
The code above isn't too optimised ( I am sure lots of better algorithm can do), but the idea is there, you use javascript to manipulate the html into something like the above one, by putting the first 1/3 to left column, second 1/3 to center, and the rest to right. The last job is use CSS to make them into 3 columns, which I am not going to cover here but there's tons of tutorials out there, for instance, this one is one of those examples.
You can't do this in CSS alone - though #griegs has shown how to do across then down.
If you always want 3 columns this should be easy with a little server side code and CSS - basically for each item you write something like:
<li>item</li>
Then at count/3 and count*2/3 add:
</ul><ul>
So you end up with something like:
<style>
.three-column-panel > ul {
float:left; width:33%; list-style-type: none; text-indent:0; }
</style>
<div class="three-column-panel">
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
<ul>
<li>d</li>
<li>e</li>
<li>f</li>
</ul>
<ul>
<li>g</li>
<li>h</li>
</ul>
</div>

Categories

Resources