I'm using ASP.Net MVC3, I've a View in which I'm displaying a simple Table with Model Data as follows:
+-------+---------------+----------------+
| ID | Name | Order |
+-------+---------------+----------------+
| ID | Name | textbox val=1 |
+-------+---------------+----------------+
| ID | Name | textbox val=3 |
+-------+---------------+----------------+
| ID | Name | textbox val=2 |
+-------+---------------+----------------+
+-------+ +--------------+
|submit | | update order |
+-------+ +--------------+
Here, Order column contains Inputbox with Order values (1,3,2 etc.,). I need to Update my Model [Item {ID, Name, Order}]by reading Order column.
Meaning, I need to submit the Order values to Model, by reading a HTML table column. How to do this?
Create a view model for each item:
public class ItemViewModel
{
public string Id { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
And a model for the action:
public class EditViewModel
{
public IEnumerable<ItemViewModel> Items { get;set; }
public int Index { get; set; }
}
Render the rows like this:
#foreach (var item in Model.Items)
{
<tr>
<td><input type="hidden" name="Id[#Model.Index]" value="#item.Id" />#item.Id</td>
<td>#item.Name</td>
<td><input type="text" name="Value[#Model.Index]" value="#item.Value" /></td>
</tr>
#{ Model.Index = Model.Index + 1 }
}
And finally receive the rows as:
[HttpPost]
public ActionResult Edit(ItemViewModel[] items)
{
}
Related
First of all below is my Excel file.
+-----------------+-----------------------------+
| Data | Output |
+-----------------+-----------------------------+
| URL | http://www.gmail.com |
+-----------------+-----------------------------+
| Username | abc123 |
+-----------------+-----------------------------+
| Password | 123abc |
+-----------------+-----------------------------+
In my Initialize class I am calling URL to be navigates.
Then in test class to get data from excel for Username and Password. Below is my code.
My Main class contains
PageObject credLogin = new PageObject();
var fileName = #"path";
string sheetName = "Sheet";
var book = new LinqToExcel.ExcelQueryFactory(fileName);
var users = from x in book.Worksheet<Login>(sheetName)select x;
foreach (var x in users)
{
My.driver.Navigate().GoToUrl(a["URL"]);
credLogin.Login(x["uid"], x["pwd"]);
}
--> My PageObject class contains
namespace Abc13465
{
class PageObject
{
//use using OpenQA.Selenium.Support.PageObjects;
[FindsBy(How = How.Name, Using = "txtuname")]
public IWebElement Username { get; set; }
[FindsBy(How = How.Name, Using = "txtpass")]
public IWebElement Password { get; set; }
[FindsBy(How = How.ClassName, Using = "login_button")]
public IWebElement logbtn { get; set; }
public void Login(string uname, string paswd)
{
Username.EnterText(uid);
Password.EnterText(pwd);
logbtn.Click();
}
PN: URL link and Username/Password are changed to but al functions are same.
My Question:
What am I missing here? Neither, I am not able to get data from excel for username and password. Nor able to navigate to the site
Format that you are using is not correct. I made that same mistake so it was not working. Use below format and It should work.
+----------------------+----------+------------------+
| URL | Username | Password |
+----------------------+----------+------------------+
| http://www.gmail.com | abc123 | 123abc |
+----------------------+----------+------------------+
I have a table
public class Product
public int Id { get; set; }
public string Model_Name { get; set; }
public string Company_Name { get; set; }
public Nullable<int> Price { get; set; }
public string Photo { get; set; }
Now the table contains multipe items so I just want to retrive the name of the company and dispay it. However the column Company_Name contains duplicate values. How do I need to check if it contains duplicate names then also display the value only once.I want to check it within view. Here is the View.
#foreach (var item in Model)
{
<tr>
//Anything extra could be added here to check the duplicate values
<td>#Html.ActionLink(item.Company_Name, "Brand",
new { Company_Name = item.Company_Name })
</td>
</tr
}
Here is how the table looks like
Id Model_Name Company_Name price photo
1 S7862 Samsung 1500 something
2 Galaxy Samsung 1500 something
3 Apple Apple 2000 something
4 Desire HTC 1500 something
5 Desire X2 HTC 1500 something
6 Nokia Lumia Nokia 1500 something
Now in the above table a few records are missing and if I write
#foreach(var item in Model)
{
<tr>
<td>
#Html.ActionLink(item.Company_Name, "Brand", new {Company_Name=item.Company_Name})
</td>
</tr>
}
now here I get the result as
Brand
Samsung
Samsung
Apple
HTC
HTC
Nokia
I want it to be as
Brand
Samsung
Apple
HTC
Nokia
Any ideas will be appreciated. I want the Linq to come within the view.
Try using a Distinct() on that Property:
#foreach (var companyName in Model.Select(m => m.Company_Name).Distinct())
{
<tr>
//Anything extra could be added here to check the duplicate values
<td>#Html.ActionLink(companyName, "Brand",
new { Company_Name = companyName })
</td>
</tr
}
How about Grouping them on Company_Name:
#{
var grouped = Model.GroupBy(x=>x.Company_Name);
}
#foreach (var item in grouped)
{
<tr>
//Anything extra could be added here to check the duplicate values
<td>#Html.ActionLink(item.Key"Brand",
new { Company_Name = item.Key })
</td>
</tr
}
I can't understand why I can't find anything that clearly explains how to do this with MVC. Seems like a pretty routine issue:
I have three tables:
PackageName: PackageNameID,PackageName
Food: FoodID,Food
PackageContent: PackageContentID, PackageNameID, FoodID, Qty
The application is supposed to describe packages of food. For example, a package named "A" might contain 4 onions and 3 peppers. Another package, "B", might contain 2 rolls and 2 onions.
Currently I have a custom view model ("PackageNameModel") that collects the data:
public ViewResult Index() {
var viewModel =
from pn in db.PackageNames
from pc in db.PackageContents
.Where(p => p.PackageNameID == pn.PackageNameID).DefaultIfEmpty()
from f in db.Foods
.Where(f => f.FoodID == pc.FoodID).DefaultIfEmpty()
select new PackageFoodModel { PackageName = pn, PackageContent = pc, Food = f };
return View( viewModel );
}
This returns the data correctly, but what do I do with it so that the view is actually one that is useful for the application?
Using this in my view:
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.PackageName.PackageName1 ) ,
#Html.DisplayFor(modelItem => item.Food.Food1)=#Html.DisplayFor(modelItem => item.PackageContent.Qty)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.PackageName.PackageNameID }) |
#Html.ActionLink("Details", "Details", new { id = item.PackageName.PackageNameID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.PackageName.PackageNameID })
</td>
</tr>
}
I am able to display the following:
- A , Onions=4 Edit | Details | Delete
- A , Peppers=3 Edit | Details | Delete
- B , Rolls=2 Edit | Details | Delete
- B , Onions=2 Edit | Details | Delete
This is not very useful. What I'm trying to do is display something like this:
- A (Onions=4,Peppers=3) Edit | Details | Delete
- B (Rolls=2,Onions=2) Edit | Details | Delete
Eventually, the next page down after navigating to the "Edit" action would provide an editable name for the package as well as a table of all available foods and an adjacent quantity box so that the foods/quantities within each package may be updated.
Can anyone explain how this is done within the MVC framework?
All the tutorials I have seen on the web/in books deal with data that is much simpler. Can anyone point me to some sample code / tutorials that deal with something like this?
Thanks in advance!
You need to aggregrate your results.
Create a view model like this
public class PackageViewModel
{
public int ID { set;get;}
public string Name { set;get;}
public List<FoodItem> FoodItems { set;get;}
public PackageViewModel()
{
FoodItems=new List<FoodItem>();
}
}
public class FoodItem
{
public string FoodName { set;get;}
public int Quantity { set;get;}
}
and in your Get action, You need to do the aggregate the data from your data which is ccoming from your data access layer and fill to the ViewModel List
public ActionResult IndeX()
{
List<PackageViewModel> listVM=new List<PackageViewModel>();
//Get your data and do aggregation and fill in listVM
return View(listVm)l
}
and in our view,
#model List<PackageViewModel>
#foreach(var item in Model)
{
<tr>
<td>#item.Name</td>
<td>
foreach(var food in item.FoodItems)
{
#food.FoodName - #food.Quantity
}
</td>
<td>
#Html.ActionLink("Edit","Edit",new {#id=item.ID})
</td>
</tr>
}
I want to do a grid of checkboxes that contain products/categories. The products and categories could be dynamic (I mean, the count of products/categories can change). I'm able to create the grid and save the data when I check a box. My problem is to use ajax properly.
Here is my model :
public class ProductModel
{
public List<List<ProductItemGrid>> ProductItemGrid { get; set; }
public List<string> ProductNameList { get; set; }
public List<string> CategoryNameList { get; set; }
}
public class ProductItemGrid
{
public int ProductID { get; set; }
public int CategoryID { get; set; }
public bool ProductInCategory { get; set; }
}
Part of my view, (I use the list of list to populate it) :
#for (int i = 0; i < Model.ProductNameList.Count(); i++)
{
<tr class=#(i % 2 == 0 ? "even" : "odd")>
<td style="font-weight: bold;">
#Html.DisplayFor(x => x.ProductNameList[i])
</td>
#foreach (var result in Model.ProductItemGrid[i])
{
string ckBoxName = result.ProductID.ToString() + result.CategoryID.ToString();
<td id='<%=ckBoxName%>'>
#using (Ajax.BeginForm("UpdateProductItem", "Product", new AjaxOptions() { InsertionMode = InsertionMode.Replace, UpdateTargetId = ckBoxName }))
{
#Html.Hidden("p_CategoryID", result.CategoryID)
#Html.Hidden("p_ProductID", result.ProductID)
#Html.CheckBox("<%=ckBoxName%>", result.ProductInCategory, new { onclick = "test" })
}
</td>
}
</tr>
}
Right now the view contain some error, but Im sure you get the main idea. With the ajax form, Im able to update my database, but my main problem is to update the checkbox itself after doing the C# part. Also, I'm trying to name the < td> to be able to update the ckbox by giving him a name as ProductID_CategoryID (so it would be easier for me to know which one Im updating). Thks.
Have you checkout http://knockoutmvc.com it has a very nice integration with ASP.NET MVC3 and it looks like the type of library that can help you easily achieve what you need.
I have one form when I return all products. And next to everyone product I have TextBox.
View form:
|ID|Product|TextBox (amount of product)
|3 |Carrot | 20
|4 |Potatos| 5
|7 |Tomato | 10
In this textbox I write a amount of the products and save this to database
Add(zuzycie) table:
|ID|ID_Product|amount|date
|1 | 3 | 20 |3.12.2011
|2 | 4 | 5 |3.12.2011
|3 | 7 | 10 |3.12.2011
and sum amount of product in other (product) databse.
Product table
|ID|name |amount
|3 |Carrot |10 + 20
|4 |Potatos|15 + 5
|7 |Tomato |7 + 10
In database, amount are save as seperate record. I hope you are understand what I have meaning.
How to get ID of everyone products in controller and save it in database?
View:
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Zużycie produków</legend>
<br />
#{
var grid = new WebGrid(ViewBag.produkty,null, "Produkty", 5);
}
#grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column("nazwa_prod","Produkt"),
grid.Column("ilosc","Ilość"),
grid.Column("jednostka","Jed."),
grid.Column("cena","Cena"),
grid.Column("nazwa","Firma"),
grid.Column("ID_Produkt", "ID_Prod" ),
grid.Column(header: "Zuzycie", format: (item) =>
new HtmlString(
Html.TextBoxFor(model => model.ilosc).ToString())) /*amount text box */
)
)
Model:
public class zuzycieModel
{
public int ID_Produktu { get; set; } //Id_product
public decimal ilosc {get;set;} //amount
public string data { get; set; } //date
}
Controller:
public ActionResult zuzycie()
{
var prod = (from d in baza.Produkts
join s in baza.Firmas on d.ID_firma equals s.ID_firma
select new { d.ID_firma, d.nazwa_prod, d.ilosc, d.jednostka, d.cena, d.ID_Produkt, s.nazwa }).ToList();
ViewBag.produkty = prod;
return View();
}
[HttpPost]
public ActionResult zuzycie(zuzycieModel model)
{
Zuzycie zuz = new Zuzycie(); //table zuzycie
var dat = DateTime.Today;
zuz.ID_Produkt = model.ID_Produktu; //Id product
zuz.ilosc = model.ilosc; //amount
zuz.data = dat; //date
baza.Zuzycies.InsertOnSubmit(zuz);
baza.SubmitChanges();
return RedirectToAction("zarzadzaj_produktami", "Produkt");
}
I try get ID of product, I putted it in View as HiddenFor and get using model... but it doesn't work...
I'm not clear on what was your idea with HttpPost zuzycie() method. What is Zuzycie() ? You're asking about saving multiple records but your ZuzycieModel cleary refers to a single ProductID.
Why are you using a ViewBag to pass the collection to your View ? can't you just return it through
return View(prod);
Notice what are you passing - Collection (a List<>) and I don't see this to be reflected in your data persistance logic.