Display only x numbers of items in index.cshtml - c#

I'm making a newsfeed project in Visual Studios, MVC 3, Razor engine and I'm trying only to display, let's say 10, number of feeds at once.
Currently while I was getting the database going I used this index.cshtml:
#model IEnumerable<NyjiGrunnur.Models.Article>
#{
ViewBag.Title = "NewsFeed";
}
<h2>#ViewBag.Message</h2>
#foreach (var item in Model)
{
<div id="eitt">
<fieldset>
<legend>#Html.ActionLink( item.Name, "Edit", new { id=item.Id } )</legend>
<div>#item.Subject, #item.Created</div>
<p>#Html.Raw(item.Content.Replace(Environment.NewLine, "<br/>"))</p>
</fieldset>
</div>
}
The foreach takes every single item and I was wondering if I could use a for loop or something similar to display only the 10 newest feeds.
Thanks in advance.

You can keep a counter variable and check it before displaying the data
#{
int counter=0;
}
foreach (var item in Model)
{
counter++;
if(counter<=10)
{
<div id="eitt">#item.Name</div>
}
}
But it is better to do this at your Action method and return only 10 items to the view so that you don't need to contaminate your view by adding the if statement. You can use the Take method from LINQ to get the 10 items.
public ActionResult Newsfeed()
{
List<Article> articleList=new List<Article>();
articleLsit=GetListOfItemsFromSomewhere();
//now get only 10. you may apply sorting if needed
articleList=articleList.Take(10);
return View(articleList);
}

it will be better
#foreach (var item in Model.Take(10))
{
<div id="eitt">
<fieldset>
<legend>#Html.ActionLink( item.Name, "Edit", new { id=item.Id } )</legend>
<div>#item.Subject, #item.Created</div>
<p>#Html.Raw(item.Content.Replace(Environment.NewLine, "<br/>"))</p>
</fieldset>
</div>
}

Related

Unable to submit List of model in MVC [duplicate]

This question already has answers here:
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 7 years ago.
I am displaying a list of items in a Collection in edit mode in a view. after editing the documents, I want to submit. But I am unable to postback the list. List shows null.
here is my View
#model List<NewsLetter.Models.NewsLetterQuestions>
#using (Html.BeginForm("GetAnswersfromUser", "NewsLetter", FormMethod.Post, null))
{
#Html.AntiForgeryToken()
foreach (var item in Model) {
<div>
#Html.DisplayFor(modelItem => item.Question)
</div>
<div>
#Html.TextAreaFor(modelItem => item.Answer)
</div>
}
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Submit" class="btn btn-default" />
</div>
</div>
}
Here is my Controller
public ActionResult GetAnswersfromUser(string id)
{
id = "56c5afc9afb23c2df08dd2bf";
List<NewsLetterQuestions> questions = new List<NewsLetterQuestions>();
var ques = context.NewsLetterQuestionCollection.Find(Query.EQ("NewsLetterId", id));
foreach(var x in ques)
{
questions.Add(x);
}
return PartialView(questions);
}
[HttpPost]
public ActionResult GetAnswersfromUser(List<NewsLetterQuestions> nql)
{
string id = "56c5afc9afb23c2df08dd2bf";
foreach (var item in nql)
{
var query = Query.And(Query.EQ("NewsLetterId", id), Query.EQ("Question", item.Question));
var update=Update<NewsLetterQuestions>
.Set(r => r.Answer, item.Answer);
context.NewsLetterQuestionCollection.Update(query,update);
}
return RedirectToAction("NewsLetterIndex");
}
When i hit submit it throws error.
System.NullReferenceException: Object reference not set to an instance of an object.
In the line
foreach (var item in nql)
which means that nql is null.
In order for the model binder to be able to bind the posted data, all your input names need to be in the format of [N].Property, where N is the index of the item within the list. In order for Razor to generate the input names properly, then, you need to pass it an indexed item, which means you need a for loop, rather than a foreach:
#for (var i = 0; i < Model.Count(); i++)
{
...
#Html.TextAreaFor(m => m[i].Answer)
...
}
You're never passing the list back to the controller's Post handler. You need to route the list back to the controller.
You should be doing something similar to this untested code :)
Html.BeginForm("Index", "Home", new { #nql=Model }, FormMethod.Post)
Take a look at this post as well. It is similar to your issue: Pass multiple parameters in Html.BeginForm MVC4 controller action and this Pass multiple parameters in Html.BeginForm MVC

How to dynamically create several ActionLinks from the Controller in MVC?

I'm using MVC where I have a list of strings that I would like to point to a new page. I'm using Razor and am very new to MVC and cannot seem to find the answer to my question through google.
My list could contain of the following:
"hello"
"goodbye"
"seeya"
I know how to insert strings from the controller to the html page using ViewBag, and I would use the following actionlink if I had a fixed set of strings:
#Html.ActionLink("viewedName", "ChemicalClass", new { mystring = "hello" })
#Html.ActionLink("viewedName", "ChemicalClass", new { mystring = "goodbye" })
#Html.ActionLink("viewedName", "ChemicalClass", new { mystring = "seeya" })
As I understand it, this would generate 3 links that would redirect to the subpage "ChemicalClass", and it would contain the one of the 3 parameters, depending on the link that was clicked.
My quesiton is, how can I do the same, but have the ActionLinks created dynamically, since I won't know how many links are going to be created, nor the content of the strings. My goal is to show these links on the webpage in (preferabely) a list form, e.g.:
<ol>
<li>
hello
</li>
<li>
goodbye
</li>
<li>
seeya
</li>
</ol>
Where each element in the list is a link and not just a string.
Create a view model that stores a collection of links
Model
public class ViewModel
{
public IList<string> Links { get; set; }
}
populate that model in your controller
Controller
public ActionResult Index()
{
var model = new ViewModel
{
Links = new List<string>
{
"Hello",
"Goodbye",
"Seeya"
}
};
return View(model);
}
and finally your view
View
#model MvcApplication1.Models.ViewModel
<ol>
#foreach (var item in Model.Links)
{
<li>
#Html.ActionLink("viewedName", "ChemicalClass", new { mystring = item })
</li>
}
</ol>
Your class holds your collection of strings and razor loops over them to produce your links.
you can use something like this.
<ul>
#foreach (var x in Model)
{
<li>#x.myString </li>
}
</ul>
I have something like this in one of my Views:
#foreach (var item in Model.MyList)
{
<li>
#Html.ActionLink("Select", "ActionName", "Chemical", new {id = item.AdmNum}, new { #class = "label label-info"})
</li>
}

How can I make sure that the newest items added to the list variable gets placed in the top and not in the bottom when it get displayed in html?

I am using MVC + EF
I have a Feed xml file url that gets updated every 7 minute with items, every time a new item gets added I retrieve all the items to a list variable and then I add these varible to my database table. After that I fill a new list variable which is my ViewModel from the database table. Then I declare the ViewModel inside my view which is a .cshtml file and loop throught all of the objects and display them.
How can I make sure that the newest items get placed on the top and not in the bottom?
This is how I display the items inside my cshtml note that I use a ++number so the newest item needs to be 1 and so on.. :
#model Project.Viewmodel.ItemViewModel
#{
int number = 0;
}
}
<div id="news-container">
#foreach (var item in Model.NewsList)
{
<div class="grid">
<div class="number">
<p class="number-data">#(++number)</p>
</div>
<p class="news-title">#(item.Title)</p>
<div class="item-content">
<div class="imgholder">
<img src="#item.Imageurl" />
<p class="news-description">#(item.Description) <br />#(item.PubDate) | Source</p>
</div>
</div>
</div>
}
</div>
This is how I fill the viewmodel which I use inside the .cshtml file to iterate throught and display the items
private void FillProductToModel(ItemViewModel model, News news)
{
var productViewModel = new NewsViewModel
{
Description = news.Description,
NewsId = news.Id,
Title = news.Title,
link = news.Link,
Imageurl = news.Image,
PubDate = news.Date,
};
model.NewsList.Add(productViewModel);
}
Sorry for the paint lol :P
Any kind of help is appreciated
#foreach (var item in Model.NewsList.OrderByDescending(n => n.PubDate)

Can I use IEnumerable<> inside a View?

In _Layout.cshtml
#model DynaPortalMVC.Models.Page
#using System.Linq
<ul>
#IEnumerable<model.Page> pages = model.Where(x=>x.CompanyID == 1);
#foreach (var item in pages)
{
<li>item.Title</li>
}
</ul>
In view iam trying to filter the model object called 'page' and get a list of pages whose id is 1. I need to iterate through this to show the menu.
Code inside Controller
public ActionResult Menu(string PageName)
{
//
return View(PageName, db.Pages);
}
Please tell me, how to filter out this model object to a list? I get errors on using IEnumerable.
Solved
I changed the model object to IEnumerable in view page.
#model IEnumerable<DynaPortalMVC.Models.Page>
You can skip assigning the result of your query into an IEnumerable variable unless you will use it somewhere else on the page. So you can just do this:
#model DynaPortalMVC.Models.Page
#using System.Linq
<ul>
#foreach (var item in model.Where(x=>x.CompanyID == 1))
{
<li>#item.Title</li>
}
</ul>
You need
# {IEnumerable<model.Page> pages = Model.Where(x=>x.CompanyID == 1);}
#model IEnumerable<DynaPortalMVC.Models.Page>
#{
ViewBag.Title = "Page";
}

Model Binding with variable number of items in List<T>

I have a model that can have a variable amount of items in a List<T>
In my view I then have the following:
#using (Html.BeginForm())
{
int count = Model.Data.Filters.Count;
for(int i = 0; i < count; i++)
{
<div>
#Html.TextBox("filtervalue" + i)
#Html.DropDownList("filteroptions"+i,Model.Data.Filters[i].FilterOptions)
</div>
}
#Html.Hidden("LinkID", Url.RequestContext.RouteData.Values["id"])
}
Is there a way in my controller so I can set up the POST action method to bind to a model with variable items in it?
Also how would I construct the model to cope with this?
Thanks
You coud use editor templates, it will be much easier:
#using (Html.BeginForm())
{
#Html.EditorFor(x => x.Data.Filters)
#Html.Hidden("LinkID", Url.RequestContext.RouteData.Values["id"])
}
and inside the editor template (~/View/Shared/EditorTemplates/FilterModel.cshtml) which will be automatically rendered for each element of the Model.Data.Filters collection:
#model FilterModel
<div>
#Html.TextBoxFor(x => x.FilterValue)
#Html.DropDownListFor(x => x.SelectedFilterOption, Model.FilterOptions)
</div>
Now your POST controller action will simply look like this:
[HttpPost]
public ActionResult Foo(SomeViewModel model)
{
// model.Data.Filters will be properly bound here
...
}
Thanks to editor templates you no longer have to write any foreach loops in your views or worry about how to name your input fields, invent some indexed, ... so that the default model binder recognizes them on postback.

Categories

Resources