Counting how many times a button was clicked - c#

I am wondering how can I count the number of times a button in my view was clicked using sessions and not using jQuery, just asp.net.
Here is my action method (empty) :
public ActionResult ClickCounter()
{
return View();
}
and my view :
#{
ViewBag.Title = "ClickCounter";
}
<h2>ClickCounter</h2>
#using (#Html.BeginForm())
{
<!-- form content here -->
#Session["num"] = 0;
<form method="post">
<fieldset>
<legend>Button clicks counter</legend>
<div>
<label for="Clciks">Clicks:</label>
<h2>#Session["num"]</h2>
</div>
<div>
<label> </label>
<input type="submit" value="Click!" class="submit" />
</div>
</fieldset>
</form>
}
Excuse me for the lame questions, but I am a complete novice and trying to understand how this stuff work. I tried googleing.
I just want to display the click count in the h2 in my view using sessions for the purpose.
Any tips will be appreciated.

If it is for simply increasing the clicked count on form submit, You can update your http post action method to read the session value if exist and increase and set it back. If not exist, initialize it.
const string sessionVariableName = "num";
public ActionResult ClickCounter()
{
if (Session[sessionVariableName] == null)
{
Session[sessionVariableName] = 0;
}
return View();
}
[HttpPost]
public ActionResult ClickCounter(string dummyParam)
{
if (Session[sessionVariableName] == null) // should not happen!
{
Session[sessionVariableName] = 0;
}
else
{
var n = (int)Session[sessionVariableName];
n++;
Session[sessionVariableName] = n;
}
return View();
}
Make sure that you are doing a GET form method on submit.
You also need to remove the (re) initialization in the view this line #Session["num"] = 0; as we are doing that in the action method. Also you should not have nested forms as it is invalid. Html.BeginForm helper will render the markup for the form tag. So remove the inner form tag you have.

You have tagged this question as asp.net-mvc, why not take advantage of the framework?
Model
class MyModel
{
public int ClickCount { get; set; }
}
View
#model MyModel
#{
ViewBag.Title = "ClickCounter";
}
<h2>#ViewBag.Title</h2>
<form method="post">
<!-- hidden input of the current click count -->
#Html.HiddenFor(m => m.ClickCount)
<fieldset>
<legend>Button clicks counter</legend>
<div>
#Html.LabelFor(m => m.ClickCount)
<h2>#Model.ClickCount</h2>
</div>
<div>
<button type="submit">Submit!</button>
</div>
</fieldset>
</form>
Controller
const string clickCountSessionKey = "clickCount";
[HttpGet]
public ActionResult ClickCounter()
{
// initialize the model
var model = new MyModel() { ClickCount = 0 };
var previousClickCount = Session[clickCountSessionKey];
if (previousClickCount != null)
{
model.ClickCount = (int)previousClickCount;
}
return View(model);
}
[HttpPost]
public ActionResult ClickCounter(MyModel model)
{
// increment the click count of the model
model.ClickCount++;
// track the click count in the session
Session[clickCountSessionKey] = model.ClickCount;
return View(model);
}

Related

ASP Core Razor Syntax #for -> multiple submitbuttons with diffrent inputs?

i am trying to create a ASP Core Application with Razorpages.
Everything is working fine so far, but now i'm stuck with this problem:
I want to create a form with multiple Buttons based on a Objectarray. Each Button has its own Name and should call the same OnPost method. So far so good. I struggle with posting the correct Object with the form.
Here is some Code...
Test.cshtml :
#page
#using APP.Models
#model TestModel
#{
ViewData["Title"] = "Test";
Layout = "~/Pages/Shared/_Layout.cshtml";
var bereiche = Bereich.getBereiche();
}
<div class="grid">
<h1 class="center-text">#ViewData["Title"]</h1>
<form method="post" class="center">
<div class="form-group">
<label asp-for="Model" class="col-form-label"></label>
<div class="button-group-vertical">
#for (var i = 0; i < bereiche.Count; i++)
{
<input type="hidden" asp-for="Model" value="#bereiche[i]" />
<button class="btn btn-info btn-md button-group-vertical-item">#bereiche[i].name</button>
}
</div>
</div>
</form>
</div>
Bereich.cs in namespace Model
public enum Art
{
Mitte, Beladen, Inspection, Kette
}
public class Bereich
{
public string name { get; set; }
public Art art { get; set; }
public static List<Bereich> getBereiche()
{
var bereiche = new List<Bereich>
{
new Bereich() { name="Mitte", art = Art.Mitte},
new Bereich(){name= "Beladen",art = Art.Beladen },
new Bereich(){name = "Qualitätskontrolle",art = Art.Inspection},
new Bereich(){name ="Kette",art= Art.Kette}
};
return bereiche;
}
}
Test.cshtml.cs :
public class TestModel : PageModel
{
[DisplayName("Bereich")]
[BindProperty]
public Bereich Model { get; set; }
public void OnGet()
{
}
public IActionResult OnPost()
{
return Page(); // BREAKPOINT HERE -> MODEL always "art=Mitte", "name=null" :/
}
}
Does anyone have a clue what i am doin wrong ?
In order to post an object back, you could use one form per object, with named fields corrosponding to your object property names.
Try this instead:
#for (var i = 0; i < bereiche.Count; i++)
{
<form method="post" class="center">
<input name="art" type="hidden" value="#bereiche[i].art" />
<button name="name" value="#bereiche[i].name" class="btn btn-info">#bereiche[i].name</button>
</form>
}
And also if you want your button to hold a value, you need to put the value in a value tag like i did in the example.

Render whole page with PartialView (and data) on page load

Currently we have a page where you select some parameters and click on a button to load data and display it in a grid, but there is no functionality to display the data on page load (via url parameters) yet. I've added the necessary routing configurations and Action, but I'm having troubles to render the page, it only displays the PartialView without styles.
How can I get the whole page to render and not just the PartialView?
Below is my simplyfied code for the View and Controller.
Views/Planing/Index.cshtml
#model PlaningTool.Web.Models.PlaningViewModel
<div class="row">
<div>
#using (Ajax.BeginForm("GetDataRows",
"Planing",
new AjaxOptions
{
HttpMethod = "Get",
UpdateTargetId = "gridPlaceholder",
LoadingElementId = "loadingIndicator"
}))
{
<!-- some comboboxes to select project and year -->
<input type="submit" value="Load data" />
}
</div>
</div>
<div id="gridPlaceholder">
<div id="loadingIndicator" style="display: none;">
<img src="~/Content/images/loading-image.gif" />
</div>
</div>
Controllers/PlaningController.cs
public partial class PlaningController : Controller
{
public virtual ActionResult Index()
{
return View();
}
public virtual ActionResult Plan(long projectID, int year)
{
var viewModel = new PlaningViewModel
{
ProjectID = projectID,
Year = year
};
// return GetDataRows(viewModel);
return RedirectToAction("GetDataRows", viewModel);
}
[RestoreModelStateFromTempData(typeof(PartialViewResult))]
public virtual PartialViewResult GetDataRows(PlaningViewModel viewModel)
{
// Load data from database with viewModel.ProjectID
// and viewModel.Year as parameters
[...]
var vm = new PlaningViewModel
{
// Set ViewModel for loaded data
[...]
};
return PartialView("Shared/_PlaningViewModelRows", vm);
}
[...]
}
I finally found a solution. I'm pretty sure it's not the best way to do this but it works.
If the Model is already set I render the PartialView.
<div id="gridPlaceholder">
#{
if (Model != null)
{
Html.RenderPartial("Shared/_PDataViewModelRows", Model);
}
}
<div id="loadingIndicator" style="display: none;">
<img src="~/Content/kendo/Bootstrap/loading-image.gif"/>
</div>
</div>
And in my Controller I've changed to this, so my ViewModel gets loaded independently and I simply return the same view as I would for Index with the new ViewModel.
public virtual ActionResult Plan(long projectID, int year)
{
var viewModel = new PlaningViewModel
{
ProjectID = projectID,
Year = year
};
return View("Index", LoadViewModel(viewModel));
}
public PlaningViewModel LoadViewModel(PlaningViewModel viewModel)
{
// Load data from database with viewModel.ProjectID
// and viewModel.Year as parameters
[...]
var vm = new PlaningViewModel
{
// Set ViewModel for loaded data
[...]
};
return vm;
}

In MVC, posting of form return empty model

I have the following viewModel
public class ExerciceViewModel
{
public string Code { get; set; }
public string Titre { get; set; }
public int QuestionCourante { get; set; }
}
the following view
#model MonEcoleVirtuelle.ViewModel.ExerciceViewModel
#{
ViewBag.Title = "Test";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Test</h2>
#using (Html.BeginForm("test", "exercice", FormMethod.Post))
{
#Model.Code <br />
#Model.Titre<br />
#Model.QuestionCourante<br />
<br />
<br />
Model.Code = "Code Modifie";
<input type="submit" value="Post Moi Ca!" name="fini" />
}
and the following controller methods
[HttpPost]
public ActionResult Test(ViewModel.ExerciceViewModel model)
{
if (ModelState.IsValid)
{
return Content(model.Code);
}
return View(model);
}
[HttpGet]
public ActionResult Test()
{
var vm = new ViewModel.ExerciceViewModel { Code = "code1", Titre = "Mon titre", QuestionCourante = 1 };
return View(vm);
}
When I submit the form, the model passed is empty, all properties are reset, not keeping the original values. What am I missing.
thanks
well, instead of #Model.Code which just display the values, you need some inputs.
So #Html.TextBoxFor(m => m.Code) for example
To manage a collection, you can do something like that :
#for (var i = 0; i < Model.Collection.Count; i++) {
Html.TextBoxFor(m => Model.Collection[i].Property)
}
You have not included any input fields in your view.
The #Model.Code etc only output the value of the field. To be able to post back elements they need to be form elements, like inputs. Use something like
#Html.TextBoxFor(p=>p.Code)
to create input fields that can then be posted back.
For a more complete guide see MSDN at http://msdn.microsoft.com/en-us/library/dd410596(v=vs.100).aspx

Not able to run another function for another button inside same view

I have got the two buttons in the same view one is working with the data to show in a label in another view and I have written the function for the button2 (adding another value), when I click on the button2 its not showing the data in view ..... rather it's giving error like this ... http:404 Resource not found error
and this is the view
#model MvcSampleApplication.Models.products
#{
ViewBag.Title = "Valuesadd";
}
<h2>Valuesadd</h2>
#using (Html.BeginForm("SubmitValue","EnterValue",FormMethod.Post))
{
<div>
<fieldset>
<legend>Enter Textbox Value</legend>
<div class ="editor-label">
#Html.LabelFor(m => m.EnteredValue)
</div>
<div class="editor-field">
#Html.TextBoxFor(m=>m.EnteredValue)
</div>
<p>
<input type="submit" value="Submit1" />
</p>
</fieldset>
</div>
}
#using (Html.BeginForm("SubmitValue2","EnterValue",FormMethod.Post))
{
<p>
<input type="submit" value="Submit2" />
</p>
}
and this is the controller for
namespace MvcSampleApplication.Controllers
{
public class EnterValueController : Controller
{
[HttpPost]
public ActionResult SubmitValue(MvcSampleApplication.Models.products model)
{
TempData["logindata"] = model.EnteredValue;
return RedirectToAction("submittedvalues" , "SubmitValue2");
// how can we redirect to another view when the button is clicked in one view
}
public ActionResult submittedvalues()
{
var model = new MvcSampleApplication.Models.category();
string data = TempData["logindata"] != null ? TempData["logindata"].ToString() : "";
model.lablvalue = data;
return View(model);
}
// action for second button click
public ActionResult submittedvalues2()
{
var model = new MvcSampleApplication.Models.category();
string data = TempData["logindata"] != null ? TempData["logindata"].ToString() : "";
model.lablvalue = "HIIII"+data;
return View(model);
}
}
}
would you pls suggest any idea ..
Many thanks...
Your form action and action in the controller are not named the same. Also you don't have a HttpPostfor it
#using (Html.BeginForm("SubmitValue2","EnterValue",FormMethod.Post))
{
}
//add this
[HttpPost]
public ActionResult submittedvalues2()
{
var model = SOMETHING;
return View("submittedvalues", model);
}
or
[HttpPost]
public ActionResult submittedvalues2()
{
//Do your post actions and redirect to action
return RedirectToAction("submittedvalues");
}
SubmitValue2 in the form should be submittedvalues2, and add a HttpPost attribute on it

How to convert my simple ASP.NET MVC 4 application to AJAX?

How to I convert my simple MVC4 todo list application to AJAX?
The ideal answer would give me the steps that would lead to a successful conversion of this example to AJAX.
Note: I don't need an AJAX tutorial so much as an understanding of how the ASP.NET MVC architecture supports it.
Side Question: Why does #Html.EditorFor(model => model.TodoItemToCreate) bring back the value that was typed in even though the view model sets with this.TodoItemToCreate = null?
Model
public class TodosViewModel
{
List<string> todoItems;
public List<string> TodoItems
{
get { return this.todoItems ?? (todoItems = new List<string>()); }
}
[Display(Name="What do you need to do?")]
public string TodoItemToCreate { get; set; }
public bool AcceptTodoItem()
{
bool isThereAnItemToAccept = !string.IsNullOrWhiteSpace(this.TodoItemToCreate);
if (isThereAnItemToAccept)
{
this.TodoItems.Add(this.TodoItemToCreate);
this.TodoItemToCreate = null;
}
return isThereAnItemToAccept;
}
}
Controller
public class TodosController : Controller
{
public ActionResult Index()
{
return View(new TodosViewModel());
}
public ActionResult Create(TodosViewModel todosViewModel)
{
todosViewModel.AcceptTodoItem();
return View("Index", todosViewModel);
}
}
Index View
#model Programming.LearnWeb.Models.TodosViewModel
#{
ViewBag.Title = "Todos";
}
#using (Html.BeginForm("Create", "Todos"))
{
#Html.Partial("List")
#Html.LabelFor(model => model.TodoItemToCreate)
#Html.EditorFor(model => model.TodoItemToCreate)
<input type="submit" value="Create" />
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
List View
#model Programming.LearnWeb.Models.TodosViewModel
#{ int i = 0; }
<table>
#foreach (var todoItem in Model.TodoItems)
{
<tr>
<td>
#Html.Hidden("TodoItems[" + i++ + "]", todoItem)
#todoItem
</td>
</tr>
}
</table>
I got this done on my own - the result is at https://github.com/gabrielgreen/Todos.Mvc if anyone is interested or has any comments.
I put a fair amount of effort in and would appreciate any feedback that indicates if I did it right.

Categories

Resources