I have added a code to fetch values from a database to show multiple checkboxes as shown below on my view page
#{
var dept_list = ViewBag.department_list;
}
#foreach (var dept_item in dept_list)
{
<input type="checkbox" id="dept_checkbox" name="#dept_item.name" value="#dept_item.department_ID" />
<span class="rmargin20">#dept_item.name</span>
}
Now I want to get the values of the checked checkboxes, and want to save these values to the database. The above mentioned code will generate the checkboxes for each record in database.
This can be done in asp.net. But i want to implement this feature in MVC.
Hi You can use FormCollection for getting the form values..
see my below sample code :
public ActionResult MethodName(FormCollection form)
{
string CheckboxValue = form.Get("CheckBoxName_1"); //Dynamic checkbox name
return View();
}
Hope it helps you :)
if your view is strongly binds then just submit the form and get the checked value using above solution.
And if it is not then using jquery to save checked values.
use a class for each check box
<input type="checkbox" id="dept_checkbox" class="checkbox_dept" name="#dept_item.name" value="#dept_item.department_ID" />
<span class="rmargin20">#dept_item.name</span>
Now get checked values
var selectedDepts == null;
$('.checkbox_dept::checked').each(function (e) {
selectedDepts += this.value + "^";
});
//ajax call
$.post("../ControlerName/Save", { "strSelectedDepts": selectedDepts },
function (data) {
//saved successfully
}.fail(function (xhr, textStatus, errorThrown) {
//Error occured
});
in your controller file.
[HttpPost]
public string Save(string strSelectedDepts)
{
//remove last ^ char
string strData = strSelectedDepts.Substring(0, strSelectedDepts.Length - 1);
string[] arrData = strData.Split('^');
foreach(var itm in arrData)
{
//do save operation
}
}
Related
I'm trying to add an unspecified number of rows to my database. These rows are created dynamically by the user's request:
$(document).ready(function () {
$(document).on('click', '#dataTable .add', function () {
var row = $(this).closest('tr');
if ($('#dataTable .add').length <= 100) {
var clone = row.clone();
// Clear the values.
var tr = clone.closest('tr');
tr.find('input[type=text]').val('');
$(this).closest('tr').after(clone);
}
});
// Only delete row if there exists more than one.
$(document).on('click', '#dataTable .removeRow', function () {
if ($('#dataTable .add').length > 1) {
$(this).closest('tr').remove();
}
});
});
So far what I am using to try and achieve this is a list with a maximum value of 100 elements (which I'd prefer a different method than this, perhaps one with no upper limit but this will do in the meantime), and I pass this list that I've created to my View():
// GET: Questions/Create
public ActionResult Create(int questionnaireUID)
{
List<QUESTION> questions = new List<QUESTION>();
for (var i = 0; i < 100; i++)
{
questions.Add(new QUESTION { QuestionnaireUID = questionnaireUID, Question1 = "" });
}
return View(questions);
}
In my View() here is the pertinent code sample that I am using to populate the values of my list (I believe my problems lie here...):
<table id="dataTable" name="dataTable">
#if (Model != null && Model.Count() > 0)
{
<tr>
#Html.HiddenFor(model => model[i].QuestionnaireUID)
<td>
#Html.EditorFor(model => model[i].Question1, new { htmlAttributes = new { #type = "text", #name = "question", #class = "question_input" } })
#Html.ValidationMessageFor(model => model[i].Question1, "", new { #class = "text-danger" })
<input type="button" name="addRow[]" class="add" value="Add">
<input type="button" name="addRow[]" class="removeRow" value="Remove">
</td>
</tr>
i++;
}
</table>
When I try to save this created list to my database, using the code below:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "QuestionnaireUID, Question1")] List<QUESTION> questions)
{
if (ModelState.IsValid)
{
foreach (var question in questions)
{
db.QUESTIONS.Add(question);
}
db.SaveChanges();
return RedirectToAction("Index");
}
return View(questions);
}
I am only able to save the first element of the list. The size of my list is always one, regardless of if the user dynamically generated 10 list elements.
Furthermore, if the first element has an error (e.g. it is empty) this error message is printed to all elements in the table. So, this being said although my list is able to generate in the view multiple elements/rows, for my database only one row is actually meaningful/used--which is the first row. How can I fix this?
As far as I know, MVC doesn't provide a built-in solution for handling dynamic/variable length lists. There are a few custom solutions that involve creating helpers to handle posting dynamic list objects. Here is one that I have used many times in the past, and is completely compatible with both old and current versions of ASP MVC (the blog uses old MVC markup, so you will need to update it to the RAZOR code for MVC3+).
http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/
The key component of this is the helper class "BeginCollectionItem", which handles the indexing of your list in a way that MVC will accept as a post-action parameter. Hope this helps.
I am new to mvc and this is my requirement. I am developing a page which should render a text and a checkbox. The checkbox will be checked depending on the T/F value from the database. So I am passing all the necessary data from db to the view as Json object in GetData() method.
namespace ClinicalAdvantage.Web.Controllers.UserAppSettingC
{
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using NHibernate.Mapping;
public class UserAppSettingsController : Controller
{
private readonly IAgg1 agg;
public UserAppSettingsController(IAgg1 agg)
{
this.agg = agg;
}
#region Public Methods and Operators
public ActionResult Index()
{
return this.View();
}
public ActionResult GetData()
{
return new JsonNetResult() { Data = this.agg.GetAllUserAppSettings() };
}
public ActionResult Save(JObject userAppSettings)
{
if (userAppSettings != null)
{
this.agg.SaveAllUserAppSettings(userAppSettings);
}
return this.Json(new { Status = "Success" });
}
#endregion
}
}
I have once tried returning the same data written as a viewmodel as a result of the index(). I had done something like
public ActionResult Index()
{
return this.View(model);
}
And for this I wrote out the in the corresponding view as
#model ClinicalAdvantage.Web.ViewModels.UserAppSettings1.UserAppSettingsViewModel
<form action="#Url.Action("Save")" method="post">
#Html.CheckBoxFor(x => x.IsM, new { maxlength = "50", size = "50" })
<!-- Form content goes here -->
<input type="submit" value="Save" />
</form>
But for some reason I am not using viewmodel to return data. So the above way of coding the veiw might not be right. I am not using GetData() to pass data to the front end and I can't really change this.
public ActionResult GetData() { return new JsonNetResult() { Data = this.agg.GetAllUserAppSettings() }; }
But I want to know how to code the front end to parse this json data when I am returning it as result of GetData method as tyype JsonNetResult.. Where will my view be. What should be the code if I want to display a checkbox and save button. The checkbox will be populated based on value returned by json.
This is the json I am returning
{"MaskPatientName":{"enabled":true,"value":false}}
There should be a label called MaskPatienTName
The check box should be checked if value property is true
On click of save butoon the save method in the controller shld be called.
Please help me
Simplest solution is to pass the populated view model to the view in your Index action
public ViewResult Index()
{
return View(agg.GetAllUserAppSettings());
}
And then your view should look something like this (use the Html helper to create form markup). This assumes that IsM is a property of UserAppSettingsViewModel.
#model ClinicalAdvantage.Web.ViewModels.UserAppSettings1.UserAppSettingsViewModel
#using (Html.BeginForm("Save", "UserAppSettings")) {
#Html.CheckBoxFor(x => x.IsM, new { maxlength = "50", size = "50" })
<!-- Form content goes here -->
<input type="submit" value="Save" />
}
I get typeahead working in my project but only for names. I am not able to process id of that particular label coming in autocomplete.
Bootstrap typeahead-
<input type="text" name="names" value="" id="typeahead" data-provide="typeahead" />
Script-
<script type="text/javascript">
$(function () {
$('#typeahead').typeahead({
source: function (term, process) {
var url = '#Url.Content("~/Invoice/GetNames")';
return $.getJSON(url, { term: term }, function (data) {
return process(data);
});
}
});
})
</script>
Json method-
[HttpGet]
public JsonResult GetNames(string term)
{
var names = (from u in db.Contacts
where u.name.Contains(term)
select u).ToArray();
var results = names.Select(u => u.name);
return new JsonResult()
{
Data = results,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
I am selecting whole table row on match. But How do I get Id with label name.
Or-
I can select whole row at server's side, But the problem persist for filtering result for label and name.
I used this info to also get the ID: http://fusiongrokker.com/post/heavily-customizing-a-bootstrap-typeahead (More complex... part)
I've started playing with Ajax and found a (hopefully) little problem I can't seem to find an answer to.
I generate a list of Ajax forms on my page, the code looks like this
using (Ajax.BeginForm("FixTranslation", new { translationId = errorGroup.Key.Id }, new AjaxOptions { UpdateTargetId = "targetCell_" + errorList.Key.Id }))
{
<table>
<tbody>
<tr><td>#errorGroup.SourceText</td></tr>
<tr><td id="#("targetCell_" + errorGroup.Id)"><input type="text" name="text" id="#("target_" + errorGroup.Id)" value="#(errorGroup.TargetText.Replace(' ', (char)0x00A0))" /><input type="submit" value="Fix" /></td></tr>
#foreach (var error in errorGroup.Value)
{
<tr><td>#error.Description</td></tr>
}
</tbody>
</table>
}
In the controller I have this action:
public ActionResult FixTranslation(string projectId, int translationId, string text)
{
if (Request.IsAjaxRequest())
{
return Content("You entered: " + new HtmlString(text));
}
return RedirectToAction("GetProjectOverview", new { projectId = projectId });
}
This works fine when there are no angle brackets present in the input field, the form gets sent properly. But when there are some angle brackets (e.g. "This is text with <1>tags") in the input field, my action method does not get called at all.
Does anybody know why this is happening?
Thank you very much.
Solved. It was not specific to Ajax forms and the cause has been a request validation, which can be turned off in this way for a particular action method:
[ValidateInput(false)]
public ActionResult FixTranslation(string projectId, int translationId, string text)
{
...
}
Here's an overview; I have a view with a table of data and upon changing the filter options (checkboxes) I call
a filter action, do some work, then redirecttoAction to the main action which accepts my filter info.
Stepping through in debug I can see the expected data passed through the actions and even on the View with the
building of the html, however the html expected with more or fewer rows does not render - it stays the same as the
defaulted filtered list.
Here is some of the code.
HTML with checkboxes:
<fieldset>
<legend style="color: #27568e;">Filter</legend>
<table id="Filter">
<thead>
</thead>
<tbody>
<tr>
<td>
<input type="checkbox" value="14" name="filterList" checked="checked"/>Type1
<input type="checkbox" value="15"name="filterList" checked="checked"/>Type2
<input type="checkbox" value="16" name="filterList" />Type3
<input type="checkbox" value="17" name="filterList" />Type4
<input type="button" value="Filter" id="Filterbutton" onclick="getFilterList('<%= Model.myId %>','filterList');" />
</td>
</tr>
</tbody>
</table>
</fieldset>
Javascript/JQuery
<script type="text/javascript">
function getFilterList(id, checklist)
{
var data = {};
var resultString = new String;
var selected = new Array();
var loopCounter = 0;
jQuery("input[name=" + checklist + "]:checked").each(function () {
//selected[loopCounter] = jQuery(this).val();
resultString += jQuery(this).val() + ",";
loopCounter += 1;
});
resultString = resultString + id.toString();
selected.push(id);
jQuery.post("/MyContr/Filter/", { resultStr: resultString });
};
</script>
Filter Action in Controller - MyContr:
[AcceptVerbs(HttpVerbs.Post)]
public RedirectToRouteResult Filter(String resultStr)
{
string strList = string.Empty;
Stack<string> myStack = new Stack<string>( resultStr.Split(new string[] { "," }, StringSplitOptions.None));
// Remove the id
var id = Convert.ToInt64(myStack.Pop());
//convert rest of values (selected checkbox values) to string and pass to Review *was not able to pass array
//build strList
while (myStack.Count > 0)
{
strList += myStack.Pop() +",";
}
if (strList != string.Empty)
strList = strList.Remove(strList.Length - 1, 1); //remove last comma
return RedirectToAction("Review", "myContr", new{id=id,filterList=strList});
}
Review Action in Controller - MyContr:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Review(long id, string filterList)
{
string[] strArray = new string[]{};
int[] filterArray;
if (filterList == null)
{
filterArray = new int[] { 14, 15 };//default to specific types
}
else
{ //if filterList is not null
strArray = filterList.Split(new string[] { "," }, StringSplitOptions.None); //split string into array
//convert str[] to int[]
filterArray = new int[strArray.Length];
for (int x = 0; x < strArray.Length; x++)
{
filterArray[x] = Convert.ToInt32(strArray[x].ToString());
}
}
var myData = something.GetMyData(id);
ViewData["checkboxes"] = filterArray;
return View(myData);
}
my View that outputs the filtered list
table within fieldset whose data rows are built by
foreach( item in MyFilteredData)
*the html in my View is contained in an asp:Content block with no opening and closing html tags
The page loads correctly the first time with the defaulted filter showing the correct number of rows in my table;
Changing the checkboxes to add to the filtered list does not update the html as expected; HOWEVER when I debug and step through
the code, the correct data is passed through the actions and back to the view; it seems as though its just not rendering the new/updated
html
Does anyone know why its not refreshing or rendering the updated filtered data even though I can step through and see
what I expect to?
I am not a jQuery expert, but doesnt your post method need to specify a callback function that adds the returned html to an element in the DOM?
from jquery's page:
$.post('ajax/test.html', function(data) {
$('.result').html(data);
});
http://api.jquery.com/jQuery.post/
where the returned html is appended to the element to the the .result class via the html method.
more from jquery's page:
Example: Request the test.php page,
but ignore the return results.
$.post("test.php");
Example: Request the test.php page and
send some additional data along (while
still ignoring the return results).
$.post("test.php", { name: "John", time: "2pm" } );
There are 2 problems with your code. As #Francis Noriega points out, there needs to be a callback function in your jquery to populate the returned view back into the page.
However, the bigger issue is:
return RedirectToAction("Review", "myContr", new{id=id,filterList=strList});
This returns a HTTP 302 (redirect) to your jquery calling code, and not the html contents of the called action. You will need to change the action method to return a partial view.