How to increase value on button click with controller - c#

I want to be able to increase the criteria number on button click
HTML Code:
<div class="criteria-header">
<span class="criteria-value">Criteria #ViewData["criteriaNo"]</span>
<div id="criteria-image">
<img src="~/images/red-cross.png" style="width: 100%" />
</div>
</div>
<input type="submit" value="Add new criteria" class="btn background-gold btn-180 btn-login col-2 criteria-btn" formaction="AddCriteria"/>
<input type="submit" value="Create" class="btn background-gold btn-180 btn-login col-2 criteria-btn" formaction="Create"/>
When i click on add criteria i need it to increase the criteria number to 2,3,4 and so on.
But because in the controller i set the criteria number to 1 everytime i click the button it will run through the controller and keep resetting the data.
public class JudgeController : Controller
{
int criteriaNo = 1;
public ActionResult JudgeCriteria()
{
ViewData["ShowCriteria"] = showCriteria;
ViewData["criteriaNo"] = criteriaNo;
Console.WriteLine(criteriaNo);
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddCriteria()
{
criteriaNo += 1;
showCriteria = true;
return RedirectToAction("JudgeCriteria");
}
}

Pass your criteria number from client side so you will be able to add it subsequently. And
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddCriteria(int number = 1)
{
number += 1;
showCriteria = true;
return RedirectToAction("JudgeCriteria", new { criteriaNo = number});
}
public ActionResult JudgeCriteria(int criteriaNo)
{
ViewData["ShowCriteria"] = showCriteria;
ViewData["criteriaNo"] = criteriaNo;
Console.WriteLine(criteriaNo);
return View();
}
After this pass your criteria from frontend and you will be good to go!

Related

asp.net mvc getting data from textbox on view back to stored procedure to edit record

I am new to ASP.NET but have done 20 years of desktop dev. I have a Customer class with fields CustId, CustName, CustNotes.
I have a view called CustView that has some input boxes that are to be pre-populated with customer details from a previous view using the CustID.
I can show the customer details in the text boxes but I cannot get the user edited textboxes (ie the user changes the name of a customer) back to a stored procedure in an Action.
I use a DB class called Cust1DBHandle to call the stored procedure. I have set up 3 buttons and 3 actions in a bid to get any of them to work, either by passing variables or using RequestString but nothing works.
Question #1: how can I pass the new text values back as either global variables, variables in the action or using a datamodel?
Question #2: in the CustViewDBHandle, I populate a list of the results. Is that the correct thing to do if it’s only for one row of data?
Question #3: when pressing a SAVE button that executes a stored procedure, do you have to have a return in the action in the controller?
Thanks.
Cust.cs model
public partial class Cust
{
[DisplayName("Cust ID")]
public Int32 CustID { get; set; }
[DisplayName("Customer Name")]
// [Required(ErrorMessage = "This field is required")]
public string CustName { get; set; }
[DisplayName("Customer Notes")]
public string CustNotes { get; set; }
public string ErrorMessageCust { get; set; }
}
CustView.cshtml:
#model IEnumerable<App22.Models.Cust>
#{
ViewBag.Title = "CustView";
}
<h2>#ViewBag.Title.</h2>
<h3>#ViewBag.Message</h3>
<header>
</header>
<meta name="viewport" content="width=device-width" />
<title>CustViewy</title>
<html>
<head>
</head>
<style>
th, td {
padding: 5px;
}
</style>
<body>
<p>
</p>
<p>CUSTOMER DETAILS ARE HERE</p>
<form name="1" method="post">
<fieldset>
<legend>Headline Details</legend>
<table>
#foreach (var item in Model)
{
<tr>
<td>
<label for="CustID">CustID:</label>
</td>
<td>
<input type="text" name="1CustID" value="#Html.DisplayFor(modelItem =>
item.CustID)" />
</td>
</tr>
<tr>
<td>
<label for="CustName">CustName:</label>
</td>
<td>
<input type="text" name="2CustName" value="#Html.DisplayFor(modelItem
=> item.CustName)" />
</td>
</tr>
<td>
<label for="CustNotes">Cust Notes:</label>
</td>
<td>
<input type="text" name="3CustNotes" value="#Html.DisplayFor(modelItem =>
item.CustNotes)" />
</td>
<tr>
<td></td>
<td>
<input type="submit" name="action:Save1" value="Save" />
<button style="background-color:red" type="button" name="tree0"
class="btn btn-primary" onclick="location.href='#Url.Action("SaveCust0","Cust1")'">
SAVE0 »
</button>
<button style="background-color:blue" type="button" name="tree1"
class="btn btn-primary" onclick="location.href='#Url.Action("SaveCust1","Cust1",new { CustyIDSave = item.CustID , CustyNameSave = item.CustName })'">
SAVE1 »
</button>
<button style="background-color:green" type="button" name="tree2" class="btn btn-primary" onclick="location.href='#Url.Action("SaveCust2","Cust1")'">
SAVE2 »
</button>
</td>
<td>
</td>
</tr>
}
</table>
</fieldset>
</form>
</body>
</html>
Cust1Controller.cs:
public class Cust1Controller : Controller
{
public ActionResult SaveCust0()
{
string message = "";
message = Request.Form["CustName"].ToString();
return Content(message);
CustViewDBHandle dbhandle = new CustViewDBHandle();
ModelState.Clear();
dbhandle.SaveCust(Convert.ToInt32(Request.Form["CustID"]),
Request.Form["CustName"].ToString());
}
public ActionResult SaveCust1(int CustyIDSave, string CustyNameSave)
{
CustViewDBHandle dbhandle = new CustViewDBHandle();
ModelState.Clear();
dbhandle.SaveCust(CustyIDSave, CustyNameSave);
return null;
}
[HttpPost]
public ActionResult SaveCust2(int CustyIDSave, string CustyNameSave)
{
CustViewDBHandle dbhandle = new CustViewDBHandle();
ModelState.Clear();
dbhandle.SaveCust(CustyIDSave, CustyNameSave);
return null;
}
// GET: Cust1
public ActionResult Index()
{
Cust1DBHandle dbhandle = new Cust1DBHandle();
ModelState.Clear();
return View("~/Views/Cust/Cust1.cshtml",dbhandle.GetCust(""));
// return View("~/Views/Cust/Cust1.cshtml"); //This works
}
[HttpGet]
public ActionResult Reload(string tree)
{
//tree = "Breaker2";
Cust1DBHandle dbhandle = new Cust1DBHandle();
ModelState.Clear();
return View("~/Views/Cust/Cust1.cshtml", dbhandle.GetCust(tree));
//Cust1DBHandle dbhandle = new Cust1DBHandle();
//ModelState.Clear();
//return View("~/Views/Cust/Cust1.cshtml", dbhandle.GetCust(SearchBy));
// return View("~/Views/Cust/Cust1.cshtml"); //This works
}
public ActionResult ViewCust(int CustyIDView)
{
//tree = "Breaker2";
CustViewDBHandle dbhandle = new CustViewDBHandle();
ModelState.Clear();
return View("~/Views/Cust/CustView.cshtml", dbhandle.GetCust(CustyIDView));
//Cust1DBHandle dbhandle = new Cust1DBHandle();
//ModelState.Clear();
//return View("~/Views/Cust/Cust1.cshtml", dbhandle.GetCust(SearchBy));
// return View("~/Views/Cust/Cust1.cshtml"); //This works
}
}
CustViewDBHandle.cs:
public class CustViewDBHandle
{
// ********** VIEW CUSTOMER DETAILS ********************
public List<Cust> GetCust(int CustyID)
{
GlobalVar.connection();
List<Cust> CustyChosen = new List<Cust>();
SqlCommand cmd = new SqlCommand("psv_CustView1", GlobalVar.con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#CustyID", CustyID);
SqlDataAdapter sd = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
GlobalVar.con.Open();
sd.Fill(dt);
GlobalVar.con.Close();
foreach (DataRow dr in dt.Rows)
{
CustyChosen.Add(
new Cust
{
CustID = Convert.ToInt32(dr["CustID"]),
CustName = Convert.ToString(dr["CustName"]),
CustNotes = Convert.ToString(dr["CustNotes"]),
});
GlobalVar.GlobCustName1 = Convert.ToString(dr["CustName"]); //This method uses
Global Var to get data to pass to form. Can pass anything that way.
}
return CustyChosen;
}
public int SaveCust(int CustyID, string CustyName)
{
GlobalVar.connection();
SqlCommand cmd = new SqlCommand("psu_CustSave1", GlobalVar.con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#CustyID", CustyID);
cmd.Parameters.AddWithValue("#CustyName", CustyName);
GlobalVar.con.Open();
cmd.ExecuteNonQuery();
//SqlDataAdapter sd = new SqlDataAdapter(cmd);
//DataTable dt = new DataTable();
//sd.Fill(dt);
GlobalVar.con.Close();
return 1;
}
}
There is a lot to parse here, but what strikes me as the main part of the problem you have noted is:
a) You methods on the controller are not all decorated with HttpPost attributes.
b) The action on the form that you render will be looking for a POST endpoint with a name that matches the get
That said, you're going to find it hard to get answers for how to make this work, given that this is very non-idiomatic asp.net MVC code.
I would strongly suggest working through a few tutorials, as web dev is considerably different to windows dev, with a different set of challenges. Hopefully your experience will let you skim through that quickly.

Passing list of dynamically created dropdownlists to controller in MVC

I have a MVC5 project with a form where the user can click and add new dropdowns dynamically, it uses select2 and ajax to get the posible values and filter...
//ViewModel
public class MyViewModel
{
public List<string> Skus { get; set; }
//Tried public List<List<string>> Skus { get; set; } w/no success
}
//MVC Razor view
<div id="SkuContainer">
Product variations: #Html.DropDownListFor(m => m.Skus, Enumerable.Empty<SelectListItem>(), "Select", new { multiple = "true", #class = "Skus", #id = "Skus1" })
</div>
<input id="btnAddSku" type="button" value="Add variations" class="btn btn-primary" />
<input id="btnRemoveSku" type="button" value="Remove variations" class="btn btn-danger" />
....
$(document).ready(function () {....
$("#btnAddSku").on("click", function () {
var i = 2;
var dropdown = "<select data-val='true' class='Skus' id=Skus" + i + " name=Skus style='width:1000px' multiple> </select >";
var VariationContainer = "<div id='variationsdiv'><br/> Product variations: " + dropdown + " </div>";
$("#SkuContainer").append(VariationContainer);
i++;
});
...
//Controller:
public ActionResult Confirm(MyViewModel model)
{
Debug.WriteLine(model.Skus ) // I get all the selected values, it works but I can't diferenciate each dropdown because of how the model is structured.
}
How can I set the model and the view to get a list of lists of selected values so I can diferentiate each dropdown?
Thank you

Image Browser Asp.net MVC 5

I trying to create ImageBrowser in Asp.net MVC 5. Problem is when I try to switch to another picture.
Here's my code:
In View:
#model Katalog.Models.Model
#{
Model.enumerator = 0;
int count = Model.ImageList.Count;
int index = 1;
}
....
<table>
<tbody>
<tr>
<td> #index/#count </td>
....
</tr>
<tr>
#using (Html.BeginForm("previous", "Home",FormMethod.Post))
{
<td>
<input type="hidden" name="number" value="1" />
<input value="<" type="submit" onclick="ImageLeft()" class="buttonLeftRight"/>
</td>
}
<td>#{Html.RenderPartial("~/Views/Shared/ImageViews.cshtml", Model);}</td>
<td>
#using (Html.BeginForm("next", "Home", FormMethod.Post))
{
#Html.HiddenFor(a => a.ImageList)
#Html.HiddenFor(a => a.enumerator)
<input type="submit" class="buttonLeftRight" onclick="ImageRight()"/>
}
</td>
</tr>
</tbody>
</table>
....
<script>
function ImageRight()
{
#{ Model.enumerator++; }
}
</script>
My Controller
....
public ActionResult next(Katalog.Models.Model model)
{
model = MyModel;
return View("Searcher",model);
}
....
and my PartialView:
#model Katalog.Models.Model
<img id="foto" class="imgFinded" src="#Model.ImageList[#Model.enumerator]"/>
When I click Next button my model.ImageList is empty. Why?
The reason your models ImageList property is null is because your generating a hidden input #Html.HiddenFor(a => a.ImageList) which generates
<input name="ImageList" value="System.Collections.Generic.List[]String" .. />
which will not bind to your collection in the POST method (when something is not binding, always insect the name and value attribute of the form controls your generating.
In order to bind to that list you would need to generate an input for each item in the list using a loop.
The other issue is that your scripts does nothing at all. Your model is server side code, and you cannot increment the value of a model property using javascript - you need to send a request to the controller to do that.
Since you sending the collection of images to the view, there is no need to make a request back to the server - you can just update the src attribute of the <img> tag.
Change the model to
public class Model
{
public int InitialIndex { get; set; }
public int ImageCount { get { return ImageList.Count; } }
public List<string> ImageList { get; set; }
}
and then the view can be just (the partial is unnecessary)
<img id="foto" class="imgFinded" src="#Model.ImageList[#Model.InitialIndex ]"/>
<button type="button" id="previous">Previous</button>
<button type="button" id="next">Next</button>
and the scripts
var imagelist = #Html.Raw(Json.Encode(Model.ImageList));
var index = #Html.Raw(Json.Encode(Model.InitialIndex));
var max = #Html.Raw(Json.Encode(Model.ImageCount));
var image = $('#foto');
// Set the initial state of the buttons
if (index === 0) {
$('#previous').prop('disabled', true);
} else if (index === max) {
$('#previous').prop('disabled', true);
}
$('#next').click(function() {
$('#previous').prop('disabled', false);
index++;
image.attr('src', imagelist[index]);
if (index === max) {
$(this).prop('disabled', true);
}
})
$('#previous').click(function() {
$('#next').prop('disabled', false);
index--;
image.attr('src', imagelist[index]);
if (index === 0) {
$(this).prop('disabled', true);
}
})
The code #{Model.enumerator++;} and #{Model.enumerator--;} within the two Javascript functions is server side code so it will only be executed once when the view is rendering on the server and before it is passed to the client browser. So triggering the onclick="ImageRight()" by pressing the submit button will not change the server side value.
You could instead try to post the current index to the action in your controller and increment or decrement it depending on which action has been invoked.
#using (Html.BeginForm("Next", "Home", FormMethod.Post))
{
#Html.HiddenFor(a=>a.CurrentIndex)
<input type="submit" class="buttonRightLeft"/>
}
#using (Html.BeginForm("Previous", "Home", FormMethod.Post))
{
#Html.HiddenFor(a=>a.CurrentIndex)
<input type="submit" class="buttonLeftRight"/>
}
public ActionResult Next(int CurrentIndex)
{
// Get the NEXT image and return as model
model = MyModel;
return View("Searcher",model);
}
public ActionResult Previous(int CurrentIndex)
{
// Get the PREVIOUS image and return as model
model = MyModel;
return View("Searcher",model);
}

change the button text without page refreshing in mVC4

I am doing my application in MVC. In my view i have one textbox named as EmailId, and one Submit button. If i enter the Email id and submit the button,the Label of the button want to change as Verify and the text box should be cleared without refreshing the page.
My view page is
<div class="sign" id="email">
#using (Html.BeginForm("Randa", "BU", FormMethod.Post))
{
<div class="sign1">
<div class="sign2" style="height:267px;width:562px;margin-left:214px" id="cdiv">
#Html.TextBox("EmailId","", new {#placeholder ="Enter the Email id",id="txtemail "})<br /><br />
<input type="submit" name="submit" value="Sign Up" id="btn" onclick="addbutton()" class="addbutton"/>
</div>
</div>
}
</div>
<div class="drnd" id="rnd" style="display:none">
#using (Html.BeginForm("Ra_verify", "BU", FormMethod.Post))
{
<div class="sign1">
<div class="sign2" style="height:267px;width:562px;margin-left:214px" id="cdiv">
#Html.TextBox("Getran", "", new { #placeholder = "Enter the Randam", id = "txtrnd" })<br /><br />
<input type="submit" name="submit" value="Verify" id="btnrnd" class="addbutton" />
</div>
</div>
}
</div>
}
<script type="text/javascript">
var btxt = "Verified";
document.getElementById("#btn").innerHTML = btxt;
</script>
<script type="text/javascript">
function addbutton()
{
($("#email").hide())
$("#rnd").show();
}
</script>
My controller code is
public ActionResult Randa()
{
return View();
}
[HttpPost]
// send the randam No to the Entered mail id . Store the mail id and randam no into tbl_bussiness table;
public ActionResult Randa(string EmailId, string submit)
{
string userId = System.Configuration.ConfigurationManager.AppSettings["UserTypeId"];
int typeid = Convert.ToInt32(userId);
if (ModelState.IsValid)
{
if (submit != null && EmailId != null)
{
EmailManager.SendConfirmationEmail(EmailId);
tbl_BusinessUser b = new tbl_BusinessUser();
b.EmailId = EmailId;
b.RandomNumber = (int)Session["rnd"];
b.UserTypeId = typeid;
b.CreateDTTM = System.DateTime.Now;
db.tbl_BusinessUser.Add(b);
db.SaveChanges();
ViewBag.message = "Please check ur Mail for randam no.Enter random in textbox ";
}
else
{
ModelState.AddModelError("", "Error");
}
}
return View();
}
public ActionResult Ra_verify()
{
return View();
}
[HttpPost]
// check the random no with table random no ,if match redirect to registration create page
public ActionResult Ra_verify(int EmailId, string submit)
{
if (submit != null)
{
// int c = Convert.ToInt32(EmailId);
tbl_BusinessUser b = new tbl_BusinessUser();
var tbra = db.tbl_BusinessUser.Where(x => x.RandomNumber == EmailId).FirstOrDefault();
//var tbram = Convert.ToInt32(tbra);
return RedirectToAction("Create", "BU");
}
return View();
}
Can anyone please help me?
Thanks in Advance.
We have to use Ajax whenever we want to update the value in the webpage without refreshing.
We have to do following things to make your page work.
Remove BeginForm block from your view because when we use BeginForm, it will send request to controller and refreshes the page.
Use Ajax to pass information to controller and update the page without refreshing it.
As you have two POST actions in controller, so keep both divs "rnd" and "email"
Here is sample script block with Ajax option to update the page as you requested,
$('#btn').click(function () {
var urlinfo = '/Home/Randa';
var textboxValue = $('#txtemail').val();
$.ajax({
type: "POST",
data: { value: textboxValue },
url: urlinfo,
success: function (result) {
$('#email').hide();
$('#rnd').show();
},
error: function () {
alert("failed");
}
});
});
First of all you need to use Ajax.BeginForm
Using Ajax.BeginForm with ASP.NET MVC 3 Razor
And on success function you can write the below code for clear text EmailId, and one Submit button.
$("#EmailId").val("");
$("#btn").val("Verify");
and you don't need two forms, if you are going to do the above.

Issue sending data to PartialView C# MVC

I'm trying to build an inbox that is very similar to facebooks message inbox, where you have a list of conversations(I only want a list of a message title) and when you click the conversation or message title in my situation, I want the whole message to be rendered next to it in a partial view.
Here's my Inbox view:
#model BlocketProject.Models.ViewModels.ProfilePageViewModel
#{
ViewBag.Title = "Inbox";
}
<h2>Dina meddelanden:</h2><br />
<div class="left">
<table id="messageTable">
#foreach (var message in Model.UserMessages)
{
<tr>
<td>
<button type="submit" class="messageButton">
#if (message.Unread == true)
{
<h4 style="font-weight:bold;">#message.MessageTitle</h4>
}
else if (message.Unread == false)
{
<h4>#message.MessageTitle</h4>
}
</button>
</td>
</tr>
}
</table>
</div>
<div class="right">
#Html.Partial("ReadMessage")
</div>
When I click this message-element that is a button, I want to pass that messageId to the PartialView ReadMessage:
#model BlocketProject.Models.DbClasses.DbMessages
<h2>#Model.MessageTitle</h2><br />
<p>#Model.MessageText</p>
and the controller looks like this:
[HttpPost]
public ActionResult Inbox()
{
var allMessages = ConnectionHelper.GetAllMessages(ConnectionHelper.GetUserByEmail(User.Identity.Name).UserId);
var model = new ProfilePageViewModel();
model.UserMessages = allMessages;
return View("Inbox", model);
}
[HttpPost]
public ActionResult ReadMessage(int messageId)
{
var model = ConnectionHelper.GetMessageByMessageId(messageId);
return PartialView("ReadMessage", model);
}
I've tried passing the messageId through a post as you can see in my controller, but then the partialView is returned as a new page and I simply want to render it in the Inbox view.
Any ideas?
EDIT:
Jonesy's answer fixed my problem when I edited it like this:
Controller:
public ActionResult ReadMessage(int messageId)
{
var model = ConnectionHelper.GetMessageByMessageId(messageId);
return PartialView("ReadMessage", model);
}
View:
<div class="left">
<table id="messageTable">
#foreach (var message in Model.UserMessages)
{
<tr>
<td>
#using (Ajax.BeginForm("ReadMessage", new { #messageId = message.MessageId }, new AjaxOptions { UpdateTargetId = "showMessage" }, FormMethod.Post))
{
<button type="submit" class="messageButton">
#if (message.Unread == true)
{
<h4 style="font-weight:bold;">#message.MessageTitle</h4>
}
else if (message.Unread == false)
{
<h4>#message.MessageTitle</h4>
}
</button>
}
</td>
</tr>
}
</table>
</div>
<div class="right" id="showMessage">
#Html.Partial("ReadMessage", new BlocketProject.Models.DbClasses.DbMessages())
</div>
Razor is run on the server, before the page is rendered. Once the page is on the client, and they can click a message, the concept of the PartialView is gone - it's all just one HTML page.
The easiest way for you to do this is to use an Ajax.BeginForm where your button is, and on click, update an element with a partial view retrieved from the server. Something like:
#using(Ajax.BeginForm("ReadMessage", "Messages", new AjaxOptions() { UpdateTargetId = "showMessage" })) {
//...
}
//...
<div class="right" id="showMessage">
//ReadMessage partial rendered on button click
</div>
A little method that could help you :
protected ActionResult View(string viewName, object model)
{
if (ControllerContext.IsChildAction)
return PartialView(viewName, model);
else if (Request.IsAjaxRequest())
return PartialView(viewName, model);
else
return View(viewName, model);
}
This will return a PartialView when you call you action via #Html.RenderAction() or call the action via Ajax (jQuery).
You can then use jQuery to prevent the form to be posted and post it with Ajax or when you click on a message, you can also use jQuery to get the result from the action and insert it in your DOM.

Categories