Put thousands separator in MVC - c#

I am sending via ViewData values to my view like this.
Controller
public List<string> ListarTarjetas()
{
OpexDB db = new OpexDB();
List<string> Tarjetas = new List<string>();
using (db)
{
var listTarjetasInformativas = db.SP_TARJETASINFORMATIVAS();
foreach(var item in listTarjetasInformativas)
{
Tarjetas.Add(item.NOMBRE);
Tarjetas.Add(item.MONTO.ToString());
}
}
return Tarjetas;
}
public ActionResult Index()
{
var DatosTarjetas = ListarTarjetas();
ViewData["PrimerNombre"] = DatosTarjetas[0];
ViewData["PrimerMonto"] = String.Format(DatosTarjetas[1], new CultureInfo("es-HN"));
return View();
}
Part of my razor view:
<div class="inner">
<p>#ViewData["PrimerNombre"]</p>
<p>#ViewData["PrimerMonto"]</p>
<div class="icon">
<i class="ion ion-pull-request"></i>
</div>
</div>
Within my view, in the part of <p>#ViewData["PrimerMonto"]</p> this value 7218.19 is reflected, but I would like it to be reflected in this way, 7,218.19.
I have tried like this:
ViewData["PrimerMonto"] = String.Format(DatosTarjetas[1], new CultureInfo("es-HN"));
and other ways too. But I don't get any change.
Thank you for any help you can provide.

You can format it just as a number or as currency, but if it's a string in your view data, you need to convert it to a number.
See also https://learn.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings
[TestMethod]
public void TestNumberFormat()
{
string numberStringValue = "7891.12";
double numberNumericValue = double.Parse(numberStringValue);
string formattedValueWithSymbol = string.Format(new CultureInfo("es-HN"), "{0:c}", numberNumericValue);
string formattedValue = string.Format("{0:N}", numberNumericValue);
Console.WriteLine(formattedValueWithSymbol);
Console.WriteLine(formattedValue);
}
The output of this will be
Standard Output: 
L7,891.12
7,891.12

Related

How to Store multiple check box selection in SQL Db using ViewBag from View to Controller?

How can I pass multi-select values from ViewBag to Controller and save in respective data type for Db. With my current Code I am able to take along the values selected in View until the Action method, but post updating Contoller saves only the last values from the selected list for the Property.
It should store info in this format
LeaseID = 1,2,3
LeaseStatus will store as Rented, Vaccant, OwnerOccupied
Currently it saves like = 3 (If selected all 3)
Below is my Action Method
public ActionResult ReviewProperty(Property model, List<Leasing> LeasingStatus)
{
int id = model.PropId;
var uName = User.Identity.Name;
if (!ModelState.IsValid)
{
return View(model);
}
using (Db db = new Db())
{
Property dto = db.Properties.Find(id);
dto.OwnerName = model.OwnerName;
dto.OwnerMobNumber = model.OwnerMobNumber;
dto.AlterContactNum = model.AlterContactNum;
dto.OwnerEmail = model.OwnerEmail;
dto.PropertyStatus = model.PropertyStatus;
db.SaveChanges();
foreach(var lease in LeasingStatus)
{
dto.LeaseID = lease.LeaseID;
}
Leasing leaseDTO = db.Leasings.Where(x => x.LeaseID == dto.LeaseID).ToArray().ToList().FirstOrDefault();
dto.LeaseStatus = leaseDTO.LeaseStatus;
db.Properties.Add(dto);
db.SaveChanges();
}
TempData["SM"] = "Changes successfully updated!";
return RedirectToAction("MyPendingTask");
}
View
#for (int i = 0; i < ViewBag.ListLease.Count; i++)
{
<div class="form-row">
<div class="form-check">
<input type="checkbox" id="#ViewBag.ListLease[i].LeaseStatus" name="[#i].LeaseID" value="#ViewBag.ListLease[i].LeaseID" checked="#ViewBag.ListLease[i].isChecked" />
<label class="form-check-label">
#ViewBag.ListLease[i].LeaseStatus
</label>
</div>
</div>
}
You are saving the data outside the loop so that you save the data inside the loop, this will save all your data, all ids
foreach (var lease in LeasingStatus)
{
dto.LeaseID = lease.LeaseID;
Leasing leaseDTO = db.Leasings.Where(x => x.LeaseID == dto.LeaseID).ToArray().ToList().FirstOrDefault();
dto.LeaseStatus = leaseDTO.LeaseStatus;
db.Properties.Add(dto);
db.SaveChanges();
}

export partial view to text file

I'm writing an ASP.NET web app (university task for exam). I have a database which has columns like Id, Name, Age, SumNote. First of all I had to make a partial view with top 5 students in database:
This method to get top 5 students
public class HomeController : Controller
{
StudentContext db = new StudentContext();
public ActionResult ShowTopFive ()
{
var allStudents = db.Students.OrderByDescending(s => s.SumNote).Take(5);
return PartialView(allStudents);
}
}
This is the patrial View:
#model IEnumerable<Univercity.Models.Student>
<div id="results">
<h4>Best 5 students</h4>
<ul>
#foreach (var item in Model)
{
<li>#item.Name, Summ of notes: #item.SumNote</li>
}
</ul>
</div>
and with this one I got the list of students in my webpage
<div>
<h5>Show top 5 students</h5>
</div>
<div>
#using (Ajax.BeginForm("ShowTopFive", new AjaxOptions { UpdateTargetId = "results" }))
{
<input type="submit" value="Show"/>
}
<div id="results"></div>
</div>
the output result looks like this:
Ivanov Mikhail, Summ of notes: 16
Kozlov Pete, Summ of notes: 12
Mary Ann, Summ of notes: 11
I also need to save it as text file. Can't figure out how? May be there is a way to change something in Ajax code?
Thanks in advance. Hope someone know how to do it. Google didn't help
You could create a controller action method which uses FileStreamResult by iterating the list created from ToList() and write necessary property values into a stream, then use Controller.File() overload which accepts stream to let user download text file:
public ActionResult GetTextFile()
{
var topFiveStudents = db.Students.OrderByDescending(s => s.SumNote).Take(5).ToList();
if (topFiveStudents != null && topFiveStudents.Count > 0)
{
string fileName = "something.txt";
// create a stream
var ms = new MemoryStream();
var sw = new StreamWriter(ms);
foreach (var students in topFiveStudents)
{
// iterate the list and write to stream
sw.WriteLine(string.Format("{0}, Sum of notes: {1}", students.Name, students.SumNote));
}
sw.Flush();
ms.Position = 0;
// return text file from stream
return File(ms, "text/plain", fileName);
}
else
{
// do something else
}
}
Afterwards, create an anchor link pointed to that action method mentioned above inside partial view:
#Html.ActionLink("Export to TXT", "GetTextFile", "ControllerName")

How to pass the results from a HTMLDropDownList to a MVC Controller?

I have a view with a HTML.DropDownList. I am trying to figure out how to capture the selection. The selection contains two values and only one value can be selected. The value is a room number that will be a string input to my Switch in the controller.
I've got the dropdownlist working, I've got the model working and sending data to the view. I can't figure out how to pass through the value of the DropDownList.
I know I need some Jquery to trigger the POST to the controller, not sure what to write though. Any help is appreciated. Code is below.
#using (Html.BeginForm("SelectRoomNumber", "PEO"))
{
<fieldset>
Room Numbers
#Html.DropDownList("RoomList", (SelectList) ViewBag.RoomList)
<p>
<input type="submit" value="Submit" />
</p>
</fieldset>
I am calling the method SelectRoomNumber in the PEO controller.
[HttpPost]
public ActionResult SelectRoomNumber()
{
string roomNumber ="";
string readValueBv = "T";
string readValueAv = "80";
string readValueMv = "Occ";
switch (roomNumber)
{
case ("1B^1001^01"):
model.RmNum = "1B^1001^01";
model.BvInstance = 3000018;
model.AvInstance = 3000022;
model.MvInstance = 3000040;
break;
case ("1B^1002^01"):
model.RmNum = "1B^1002^01";
model.BvInstance = 3000020;
model.AvInstance = 3000023;
model.MvInstance = 3000042;
break;
default:
model.RmNum = "Room";
model.BvInstance = 0;
model.AvInstance= 0;
model.MvInstance= 0;
break;
}
//Start BACnet Message Que
_bacnetAgent.StartActivity(IpAddress);
Thread.Sleep(2000);
//Trigger Read Method BV
_bacnetAgent.Read(deviceId, BvReadBacObj, model.BvInstance, BacProp, out readValueBv);
model.BvRes = readValueBv;
//Trigger Read Method AV
_bacnetAgent.Read(deviceId, AvReadBacObj, model.AvInstance, BacProp, out readValueAv);
model.AvRes = readValueAv;
//Trigger Read Method MV
_bacnetAgent.Read(deviceId, MvReadBacObj, model.MvInstance, BacProp, out readValueMv);
model.MvRes = readValueMv;
return View("PEO", model);
}
Just Add this if you want it as integer:
[HttpPost]
public ActionResult SelectRoomNumber(int RoomList)
{
}
Otherwise as a string :
[HttpPost]
public ActionResult SelectRoomNumber(string RoomList)
{
}
RoomList is the keyname which you have entered in your view:
#Html.DropdownList("KEYNAME")
just create a variable with the same name of the attribute name of your select element.
[HttpPost]
public ActionResult SelectRoomNumber(string RoomList)
{
//rest of your code
}
MVC view works hand in hand with the associated controller, so u can pass a value or values from the view to the controller as long as the id in the view and in the controller are the same names. e.g
in your controller u have this
[HttpPost]
public ActionResult SelectRoomNumber(string RoomList)
{
}
and in your view u should have this
Html.Textbox("RoomList")

How i can generate dynamic id for text field and get data from array of model in asp.net 4 mvc3

This is my first post here! :)
I have to return an array of my model from my controller class to the view page. I want to put the data into a text box and generate dynamic id's for each text box to use the data further via JavaScript (that's why I am looking for dynamic id's).
Model
public partial class BhBuyerChart
{
public string Date { get; set; }
public string Quantity { get; set; }
public BhBuyerChart(string n, string d)
{
Date = n;
Quantity = d;
}
}
Controller
public ActionResult test()
{
BhBuyerChart[] model = new BhBuyerChart[7];
DataTable dt = (DataTable)ExecuteDB(ERPTask.AG_GetAllShipmentRecord, CurrentUserId);
List<BhBuyerChart> ItemList = null;
ItemList = new List<BhBuyerChart>();
int i = 0;
foreach (DataRow dr in dt.Rows)
{
model[i] = new BhBuyerChart(dr["Shipmentdate"].ToString(), dr["ShipmentQuantity"].ToString());
i++;
};
return View(model);
}
View
1st Attempt
<div>
<% for (int i=0; i<2; i++) {%>
<%: Html.TextBoxFor(m => m[i].Quantity, new { id = "Quantity"})%> <%--value can assign from model but dnt know how to assing dynamic id --%>
<input type="text" value="<%= i %>" id="text<%=i %>"/> <%--dynamic id can be assinged dnt knw how to assing model value here in textbox --%>
<% } %>
</div>
2nd Attempt
<div>
<% int i = 0; %>
<% foreach (ERP.Domain.Model.BhBuyerChart user in Model) { %>
<% i++; %>
<input type="text"; id="textbox<% i %>" ; value="<% user.Quantity %>" />
<% } %>
</div>
I really appreciate everybody's attention and help and I look forward to your responses!
I think this should do it for you. Effectively what you're going to do is build a new method inside the controller so that you can POST back to the controller with the updated values. Further, you don't want the Quantity fields to have different names because they won't bind - and so each one you build will say Quantity in the name and id attribute when the HTML is generated.
If I've misunderstood your need please comment.
Controller
public ActionResult test()
{
BhBuyerChart[] model = new BhBuyerChart[7];
DataTable dt = (DataTable)ExecuteDB(ERPTask.AG_GetAllShipmentRecord, CurrentUserId);
List<BhBuyerChart> ItemList = null;
ItemList = new List<BhBuyerChart>();
int i = 0;
foreach (DataRow dr in dt.Rows)
{
model[i] = new BhBuyerChart(dr["Shipmentdate"].ToString(), dr["ShipmentQuantity"].ToString());
i++;
};
return View(model);
}
[HttpPost]
public ActionResult test(ICollection<BhBuyerChart> charts)
{
// This allows you to POST to the controller with the modified values
// Note that based on what you're collecting client side the charts
// will ONLY contain the Quantity value, but they will all have one.
// If you need the date you can either show a text box for that or
// even place the date inside a hidden field.
}
View
<form method="post" action="/{controllername}/test">
...
<div>
<% for (int i=0; i<2; i++) {%>
<!-- This line will both bind the value and allow you to POST -->
<!-- this form back to the controller with the new values -->
<!-- NOTE: each control is actually going to be named the same -->
<!-- but when it's posted will post in order to the collection -->
<%: Html.TextBoxFor(m => m[i].Quantity) %>
<!-- You may or may not want this here so that you can get the -->
<!-- value of the date back to the server during a POST -->
<%: Html.HiddenFor(m => m[i].Date) %>
<% } %>
</div>
...
</form>
JavaScript
Now in JavaScript what you can do is use jQuery to simply get a listing of all the elements named Quantity like this and use them from that array.
// with this ([0].Quantity) being the template
// we'll use a simple wildcard selector to find
// all of them that end with Quantity.
var elems = $("[name$=Quantity]")
// now you have a list of the elements that you
// can use to populate the other array with -
// getting the value with a statement like...
var val = elems[0].val();
You need the excellent extension made by Steven Sanderson called BeginCollectionItem. For each row in your Model, each inputs will inherit an unique guid that you can reuse for validation or other stuff.
For more information on how to use the extension step by step, please go see the article on Steven Sanderson's blog : Editing a variable length list, ASP.NET MVC 2-style
The article was made for MVC2 but it work in MVC3 too. It should work in MVC4 but i haven't tested yet.
View
<% foreach (var item in Model) {
<% using(Html.BeginCollectionItem("bhBuyerItem")) { %>
<%= Html.TextBoxFor(m => m.Quantity) %>
<%= Html.TextBoxFor(m => m.Date) %>
<% } %>
<% } %>
The extension method
public static class HtmlPrefixScopeExtensions
{
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
{
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
// autocomplete="off" is needed to work around a very annoying Chrome behaviour whereby it reuses old values after the user clicks "Back", which causes the xyz.index and xyz[...] values to get out of sync.
html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex)));
return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex));
}
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
{
// We need to use the same sequence of IDs following a server-side validation failure,
// otherwise the framework won't render the validation error messages next to each item.
string key = idsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null) {
httpContext.Items[key] = queue = new Queue<string>();
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (string previouslyUsedId in previouslyUsedIds.Split(','))
queue.Enqueue(previouslyUsedId);
}
return queue;
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
}
well after several tries i guess i have able to make this
<%for (int i = 0; i <= 1; i++)%>
<% { %>
<div style="width:100%; float:left">
<%: Html.TextBoxFor(m => m[i].Date, new { id= i+500 })%>
<%: Html.TextBoxFor(m => m[i].Quantity, new { id = i })%>
<%: Html.TextBoxFor(m => m[i].Quantity) %>
</div>
<script type="text/javascript">
var val = [[], []];
for (k = 0; k <= 1; k++) {
val[k][0] = document.getElementById(k+300).value;
val[k][1] = parseInt(document.getElementById(k).value);
}
</script>
this gonna take dynamic data from model array and create dynamic id for each textbox and assign them into variable using dynamic id

have problem with MVC, String not Showing in the Return View

in the Controller:
public ActionResult Create()
{
int i = 0;
string s = "";
bool unique = false;
while (!unique)
{
s = GenerateCode(i);
var CheckURLs = from x in db.QRCodeGs
where x.QRCodeShortString == s
select new { ShortCode = x.QRCodeShortString};
if (CheckURLs.Count() == 0)
{
unique = true;
}
else
{
i++;
}
}
return View(new QRCodeG { QRCodeShortString = s, QRCodeGenDate = DateTime.Today, LastEditDate = DateTime.Today, LastEditor = User.Identity.Name });
//return View();
}
Create.cshtml page:
<div class="editor-field">
#Html.EditorFor(model => model.QRCodeShortString)
#Html.ValidationMessageFor(model => model.QRCodeShortString) <br />(You make choose your own string or use this dynamically generated one)
</div>
Not sure exactly what the problem is, but here's a few things to check
Make sure the model is the proper type in the cshtml page. ie: #model QRCodeG
Make sure the variable 's' actually has something in it
Check your css (editor-field class) to make sure you aren't hiding it by mistake.
the first thing I would suggest is to move where you declare the model you are passing to the view, do something like
var qrCodeG = new QRCodeG { QRCodeShortString = s, QRCodeGenDate = DateTime.Today, LastEditDate = DateTime.Today, LastEditor = User.Identity.Name };
return qrCodeG;
then use the debugger to see if qrCodeG is being populated correctly.
if that works then try adding
<div> #model.QRCodeShortString </div>
to your view and see if that is outputting your data correctly
if that works look at what is going on in #Html.EditorFor(model => model.QRCodeShortString)

Categories