I have a textbox on my form:
<input type="text" class="input-group-field" id="draftSearchProducts" name="draftSearchProducts" placeholder="SearchProducts" />
In my controller I have the following:
[HttpGet]
public ActionResult SearchResults(string keywords, int queryLimit = 20, int offset = 0)
{
try
{
ProductSearchResults searchResults = new ProductSearchResults();
ComApiData<GetProductsDataConnector> productData = new ComApiData<GetProductsDataConnector>();
var products = productData.Connector.GetProductBySearch(new ProductRequestParameters()
{
Search = keywords,
LTPMerchantId = merchantId,
QueryLimit = queryLimit,
QueryOffset = offset
});
searchResults.ProductDetails = products.ToList();
return PartialView("_SearchResults", searchResults);
}
catch (Exception ex)
{
throw ex;
}
}
And there is a button on the form:
<a id="draftAddProduct" class="hollow button secondary"><i class="fa fa-plus"></i> Add Product</a>
Since I am new to this side of development, I need a little help. I need to wire up the button to take the value typed in the text call the SearchResults controller (located in a file called ProductsController.cs) and populate a modal dialog box with the results. I have a partial razor page:
#model Sauron.Models.Products.ProductSearchResults
#foreach (var product in Model.ProductDetails)
{
<tr>
<td class="imageColumn">
#if (product.Image != null)
{
<div class="ajax-image-load">
<input type="hidden" id="BlockImageID" value="#product.Image.ImageId" />
<input type="hidden" id="BlockImageWidth" value="89" />
<input type="hidden" id="BlockImageHeight" value="89" />
<input type="hidden" id="BlockImageLoaderGif" value="/images/loader-circle-basic.gif" />
</div>
}
</td>
<td>
#product.SKU
<input type="hidden" id="editID" name="editID" value="#product.ProductId" />
</td>
<td>#(product.Description != null ? product.Description.Name : product.ReceiptName)</td>
#*<td>#(product.ColorId != null ? product.)</td> we might want to gather the color object as a property of this search class model*#
<td>
#{
var textColor = "";
if((product.InventorySummary ?? 0) <= 0){
textColor = "red-text";
}
}
<span class="#textColor">#((product.InventorySummary ?? 0).ToString())</span>
</td>
<td>
#if (product.ProductType != null ? product.ProductType.Equals(ProductType.PACK) : false)
{
<span>#(product.PackQty != null ? string.Format("{0} {1}", product.PackQty.Value, product.ProductType.ToString()) : product.ProductType.ToString())</span>
}
else if (product.ProductType != null ? product.ProductType.Equals(ProductType.CASE) : false)
{
<span>#(product.PackQty != null ? string.Format("{0} {1}", product.PackQty.Value, product.ProductType.ToString()) : product.ProductType.ToString())</span>
}
else
{
<span>#(product.ProductType != null ? product.ProductType.ToString() : "")</span>
}
</td>
</tr>
}
that will display the results. I need to display the results of the _SearchResults.cshtml page in a modal box.
I want to call the SearchResults method from the values entered in the text box to display the results.
Anyone's help is appreciated.
The problem was I was calling the controller by the wrong name. Once I got the right name, it started working.
Code:
$('#draftAddProduct').click(function () {
var keyWord = $('#draftProductModal').val();
$('#draftProductModal').load("#Url.Action("SearchResults","Products")?keywords=chair");
});
You can find an answer for this question here:
Bootstrap Modal Dialog - Loading Content from MVC Partial View
Related
I've been struggling with this for a while now. I'm constructing this view:
But when I hit the 'Update' button after do some changes the web refreshes to show the original values.
About the view: I get this view using an IEnumerable and looping thru each item in the model inside a form. Then, inside the form, there is a table that contains only 1 row. I do this in order to wrap all the items of the record in one form. This is part of code:
#foreach (var item in Model)
{
<form asp-action="Test" asp-route-id="#item.Id">
<table class="table">
<tbody>
<tr>
<td>
<input type="hidden" asp-for="#item.Id" />
<div class="form-group">
<div class="col-md-10">
<input asp-for="#item.MchName" readonly class="form-control" />
<span asp-validation-for="#item.MchName" class="text-danger"></span>
</div>
</div>
</td>
//more fields
<td>
<input type="submit" value="Update" class="btn btn-default" />
</td>
</tr>
</tbody>
</table>
</form>}
I declare an asp-action and a asp-route-id:
<form asp-action="Test" asp-route-id="#item.Id">
Question: Is this good enough? Is there something missing?
This is the Get Method:
public async Task<IActionResult> Test()
{
PopulateMachineTypeDropDownListStore();
return View(await _context.Machines.AsNoTracking().ToListAsync());
}
Question: I'm not passing any argument to the controller, yet the view will list the items following the given structure using an IEnumerable. Should I pass anything to the Get Method or is it fine as it is?
This is the Post Method:
#model IEnumerable<Application.Models.Machine>
[HttpPost, ActionName("Test")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> TestPost(int? id)
{
if (id == null)
{
return NotFound();
}
var machinetoUpdate = await _context.Machines
.SingleOrDefaultAsync(s => s.Id == id);
if (await TryUpdateModelAsync(
machinetoUpdate,
"",
s => s.MchName, s => s.StoreID, s => s.PUnit, s => s.Status))
{
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateException)
{
ModelState.AddModelError("", "Unable to save changes. " +
"Try again, and if the problem persists, " +
"see your system administrator.");
}
return RedirectToAction("Test");
}
PopulateMachineTypeDropDownListStore();
return View(await _context.Machines.AsNoTracking().ToListAsync());
}
Question: I don't know if because the entity I retrieve the id from (and that I use to update the model thru TryUpdateModelAsync()) is also being used to compare to the model that thru the view this might not been working properly.
Thanks in advance for any help.
In the view, the model is:
#model List<ParamsTaskLib.ParamRecord>
I want to create a form with an input field which will be the DeviceID to search for:
public class ParamRecord
{
[Required]
[RegularExpression(#"^[0-9a-fA-F]{8}$", ErrorMessage = "Invalid Device ID (hex)")]
public Int64 DeviceID { get; set; }
other fields in here...
I tried editing the view in the following way:
<form method="get" >
#Html.EditorFor(model => model.First().DeviceID)
#Html.ValidationMessageFor(model => model.First().DeviceID)
But it doesn't work obviously, it doesn't seem like it SHOULD work:)
I'm confused with how to work with a list as a model, combined with a search box...
The error I get is "Value can't be NULL" on this line:
#Html.EditorFor(model => model.First().DeviceID)
Extra clarification: the purpose of this page is to display a table which contains many lines (ParamRecord) of a specific DeviceID from the database.
The purpose of the form + input field is to supply the web server with the DeviceID of which I want to see data (a collection of ParamRecord)
This is the complete View page:
#model List<ParamsTaskLib.ParamRecord>
#{
ViewBag.Title = "SearchResults";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script type="text/javascript" >
function UpdateFunc() {
$.get("/home/GetProgress", function(data) {
$("#UpdatePercentage").text(data);
if (data == "100")
location.reload();
else
setTimeout(UpdateFunc, 2000);
});
}
function Update() {
var id = $("#id").val();
$.post("#Url.Content("~/Home/UpdateID/")" + id, function (data) {
UpdateFunc();
});
$("#UpdateAni").attr("src", "#Url.Content("~/Content/Images/ajax-loader.gif")");
$("#UpdatePercentage").show();
}
</script>
<div>
<form method="get" >
#Html.TextBox("id")
#*#Html.EditorFor(model => model.First().DeviceID)*#
#Html.ValidationMessageFor(model => model.First().DeviceID)
<input type="submit" value="Search" />
<img id="UpdateAni" src="#Url.Content("~/Content/Images/ajax-loader_static.gif")" onclick="Update()"/>
<span id="UpdatePercentage" style="display:none" >0</span>
</form>
#if (Model != null )
{
<h4>ID 0x<span>#ViewBag.ID</span> , last update was at #ViewBag.LastUpdateTS</h4>
<h3>Total #ViewBag.NumOfParams parameters</h3>
<hr />
<table border="1" >
<thead>
<tr>
<th>Parameter Number</th>
<th>Device Inner ID</th>
<th>Device Type</th>
<th>Value (Int)</th>
<th>Value (Float)</th>
<th>Value (String)</th>
</tr>
</thead>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Model[i].ParamIndex</td>
<td>#Model[i].DeviceInnerID</td>
<td>#Model[i].DeviceType</td>
<td>#Model[i].ParamValInt</td>
<td>#Model[i].ParamValFloat</td>
<td>#Model[i].ParamValSTR</td>
</tr>
}
</table>
}
else if (ViewBag.NoResults == 1)
{
<h3>No results for ID 0x<span>#ViewBag.ID</span></h3>
}
</div>
Hello I'm new to cshtml and I have web pages in ASP.NET Razor v2 I would like to insert some data into DB on button click. These data are provided from various textboxes and also uploading picture. May I please know how to how to provide action on button click?
I tried this in my cshtml file :
<button type="submit" name="action" value="insertRegistered">Uložit</button>
#if (action == "insertRegistered")
{
var db1 = Database.Open("StarterSite");
var sql = "UPDATE services SET FileName=#0, FileContent=#1, MimeType=#2 WHERE IDservice=6";
db1.Execute(sql, fileName, fileContent, fileMime);
}
In WebMatrix, you can accomplish this in this way:
Razor code:
#{
var fileName = "";
var fileContent = "";
var fileMime = "";
var IDservice = "";
#*TEST CODE *#
#*if (!IsPost)
{
IDservice = "1";
var db = Database.Open("StarterSite");
var dbCommand = "SELECT * FROM services WHERE IDservice = #0";
var row = db.QuerySingle(dbCommand, IDservice);
fileContent = row.fileContent;
fileMime = row.MimeType;
fileName = row.fileName;
} *#
if (IsPost)
{
fileName = Request.Form["fileName"];
fileContent = Request.Form["fileContent"];
fileMime = Request.Form["fileMime"];
IDservice = Request.Form["IDservice"];
var db1 = Database.Open("StarterSite");
var sql = "UPDATE services SET FileName=#0, FileContent=#1, MimeType=#2 WHERE IDservice=#3";
db1.Execute(sql, fileName, fileContent, fileMime, IDservice);
}
}
And the markup should look like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Service</title>
</head>
<body>
<form method="post">
<fieldset>
<legend>Service Information</legend>
<p><label for="fileName">FileName:</label>
<input type="text" name="fileName" value="#fileName" /></p>
<p><label for="fileContent">File Content:</label>
<input type="text" name="fileContent" value="#fileContent" /></p>
<p><label for="fileMime">Mime:</label>
<input type="text" name="fileMime" value="#fileMime" /></p>
<input type="hidden" name="IDservice" value="#IDservice" />
<p> <button type="submit" name="action" value="insert Registered">Uložit</button></p>
</fieldset>
</form>
</body>
</html>
And here's a working sample.
Here's a set of tutorials which, I believe, should be very helpful!
Put your database logic into a controller action, like this:
public class HomeController : Controller
{
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection)
{
try
{
// Do database update logic here
// Upon successfully updating the database redirect to a view
// that displays the information, read-only version not editable
return RedirectToAction("Index");
}
catch(Exception ex)
{
// If something went wrong, then re-display the view
// the user tried to update database from
return View();
}
}
}
Now in your view create a form by using the HTML helper Html.BeginForm(), like this:
#using (Html.BeginForm("ActionMethodName","ControllerName"))
{
... your input, labels, textboxes and other html controls go here
<input class="button" id="submit" type="submit" value="Uložit" />
}
Note: Html.BeginForm() will take everything inside of it and submit that as the form data to the controller action specified as parameters to it.
I've a MVC application, whose SharedLayout view(Master Page) gives user capability to search. They could search their order by Order No or By Bill no. So there are two option buttons the Shared View along with the textbox. Code is somewhat like this
#using (Html.BeginForm("Track", "Tracking", FormMethod.Post))
{
<div style="text-align: center">
<textarea cols="20" id="txtNo" name="txtOrderNo" rows="2" ></textarea>
</div>
<div style="text-align: center">
<input type="radio" name="optOrderNo" checked="checked" value="tracking" />Order No <input type="radio" name="optRefNo" value="tracking" />Ref No
</div>
<div style="text-align: center">
<input type="submit" value="Track" />
</div>
}
So it'll go to TrackingController and Track Method in it and return the view. It works fine for a single search as a View is associated with a controller's methods. It works fine but how could i conditionally return the other view based on the radio button selection.
What i come up with is this
[HttpPost]
public ActionResult Track(FormCollection form)
{
string refNo = null;
if (form["optRefNo"] == null)
{
string OrderNo = form["txtOrderNo"];
var manager = new TrackingManager();
var a = manager.ConsignmentTracking(OrderNo);
var model = new TrackingModel();
if (OrderNo != null)
model.SetModelForConsNo(a, consNo);
return View(model);
}
refNo = form["txtConsNo"];
return TrackByRef(refNo);
}
public ActionResult TrackByRef(string refNo)
{
//what ever i want to do with reference no
return View();
}
Kindly guide.
Thanks
View has an overload where the first parameter is a string. This is the name (or path) to the view you want to use, rather than the default (which is a view that matches the action's name).
public ActionResult TrackByRef(string refNo)
{
//what ever i want to do with reference no
return View("Track");
// or, if you want to supply a model to Track:
// return View("Track", myModel);
}
I am attempting to validate my object that encapsulates a list of other objects, as follows (shortened for brevity):
public class FormDTO {
private List<AttributeDTO> ruleAttributes;
// More attributes here
}
public class AttributeDTO {
private String value;
// More attributes here
}
A snippet of my validator is as follows:
for(AttributeDTO attributeDTO : attributes)
{
if(attributeDTO.getValue() == null || attributeDTO.getValue().length() == 0)
{
errors.reject("value", "value.isEmpty");
}
}
My jsp contains the following:
<c:forEach items="${form.ruleAttributes}" var="ruleAttribute" varStatus="counter">
<tr>
<td>
<c:choose>
<c:when test="${ruleAttribute.isEditable}">
<form:input path="ruleAttributes[${counter.index}].value" value="${ruleAttribute.value}"/>
</c:when>
<c:otherwise>
<span class="derived">NotEditable</span>
</c:otherwise>
</c:choose>
</td>
<td>
<form:errors path="ruleAttributes[${counter.index}].value"/>
</td>
</tr>
</c:forEach>
How do I get the corresponding error message to appear for the relevant list item? In summary, I want the "value.isEmpty" message to appear in the table cell for the relevant row that has an empty value.
Thanks
After reading the Spring reference guide again, I can answer this question myself.
To get the appropriate error to appear for this snippet...
<form:errors path="ruleAttributes[${counter.index}].value"/>
...I need to modify my validation code as follows:
for(int i = 0; i < ruleAttributes.size(); i++)
{
AttributeDTO attributeDTO = ruleAttributes.get(i);
if(attributeDTO.getValue() == null || attributeDTO.getValue().length() == 0)
{
errors.rejectValue("ruleAttributes[" + i + "].value", "value.isEmpty", "Value should not be empty");
}
}