create dynamic checkbox on the basis of value in my model - c#

I am working in MVC 4, and in my View i am writing this code to generate the checkbox:
<tr class="formSectionField clearfix">
<td>
<label id="lblStoreList" class="formSectionLabel">Title:</label>
</td>
<td>
<div class="txtInput input323">
#Html.CheckBoxFor(m => m.StoreList, new SelectList(Enumerable.Empty<SelectListItem>()))
</div>
</td>
</tr>
Initially, i am just telling MVC framework, that it will have a checbox, but i want to have n number of checkbox based upon the value that is contained in my model.
How could i achieve that?
Below is the JS code with AJAX which will generate my dynamic checkbox:
function BindTitle() {
$.ajax({
"url": "/Admin/GetTitleList/",
"type": "get",
"dataType": "json",
"success": function (data) {
var items = $('#TitleId');
items.empty();
$.each(data, function (i, drdData) {
items.append($('<checkbox/>', { value: drdData.Value, html: drdData.Text }));
});
}
});
}
Hope i made you clear with this, in any case if you want further suggestion, please feel free to ask

Related

Can't access to action method from JQuery if [AntiForgeryToken] is enabled

I have a JQuery function that works ok but if I enable [AntiForgerToken] on the Action Method the JQuery function can't access the Action Method, on the view I have other snippet where I enabled AntiForgeryToken:
#using (Html.BeginForm("InsertStudent","Students",FormMethod.Post, new { #id="myform"}))
{
#Html.AntiForgeryToken()
It doesn't matter if the #Html.AntiForgeryToken() inside the view is enabled or not, the JQuery function works good, the one with the problem is at the Action Method...
Why is happening that? What I'm missing?? I've read is very important for security to have [AntiForgeryToken] enabled on the Post Action Methods so I think that the application should work with it enabled in both places the Action Method and the View.
JQuery function:
function InsertShowStudents() {
var counter = 0;
$.ajax({
type:"post",
url: "/Students/InsertStudent/",
data: { Name: $("#Name").val(), LastName: $("#LastName").val(), Age: $("#Age").val() }
}).done(function (result) {
if (counter==0) {
GetStudents();
CounterStudents();
counter = 1;
}
else {
$("#tableJQuery").append("<tr>"+"<td>"+result.Name+"</td>"+"<td>"+result.LastName+"</td>"+"<td>"+result.Age+"</td>"+"</tr>")
}
//clear the form
$("#myform")[0].reset();
}).error(function () {
$("#divGetStudents").html("An error occurred")
})
}
Action method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult InsertStudent(Student student)
{
if (ModelState.IsValid)
{
db.Students.Add(student);
db.SaveChanges();
//ModelState.Clear();
return RedirectToAction("InsertStudent");
}
return View(student);
}
columns of the table:
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
#* <td style="display:none" class="tdStudentID">#Html.DisplayFor(modelItem => item.StudentID)</td> *#
<td>
<img src="~/images/deleteIcon.png" width="20" height="20" class="imgJQuery" data-id="#item.StudentID" />
</td>
<td>
#Html.ActionLink("Details","Details", new { id=item.StudentID})
</td>
</tr>
}
You not passing the value of the token in your ajax call so an exception is thrown. You can get the value of the token using
var token = $('[name=__RequestVerificationToken]').val();
and modify your ajax call to include it using
data: { __RequestVerificationToken: token, Name: $("#Name").val(), LastName: $("#LastName").val(), Age: $("#Age").val() }
however, it is easier to just serialize your form which will include the token
$.ajax({
type:"post",
url: '#Url.Action("InsertStudent", "Students")', // don't hardcode your url's
data: $('#myform').serialize(),
}).done(function (result) {
Side note: Ajax calls never redirect (the whole point of ajax is to stay on the same page) so having return RedirectToAction("InsertStudent"); in your InsertStudent() will not work. In addition, your returning html, so the $("#tableJQuery").append() code in the .done() callback will fail.
It appears you have a form to add a new Student so your method simply need to return a JsonResult indicating success or otherwise, and if successful, then you can add a new row to your table based on the values in the form, for example
}).done(function (result) {
if (result) {
var row = $('<tr></tr>');
row.append($('<td></td>').text($("#Name").val()));
... // add other cells
$("#tableJQuery").append(row);
//clear the form
$("#myform")[0].reset();
} else {
// Oops something went wrong
}
})

ASP MVC - Editor Templates issue (Sends always data from only first template)

I have a form/view which represents a strongly typed model which contains simple properties and an IEnumerable property. I use an editor template for the IEnumerable property of my model.
for (int i = 0; i < #Model.Items.Count(); i++)
{
#Html.EditorFor(model => #Model.Items[i])
}
Now, the template looks like the following:
#using (Html.BeginCollectionItem("Items"))
{
<table style="width: 100%">
<tr>
<td>
#Html.TextBoxFor(model => #Model.ID, new {id = "ID" })
</td>
<td>
#Html.TextBoxFor(model => #Model.Description, readonly="readonly", new {id = "Description" })
</td>
<tr />
<a role="button" id=getDescBtn>
</a>
</table>
}
And my template's script:
<script type="text/javascript">
$(document).ready(function() {
$("#getDescBtn").on('click', function (event) {
$.ajax({
url: '#Url.Action("LoadDescription")',
async: false,
cache: false,
data: {id: $("#ID").val()}
}).success(function (partialView) {
});
});
});
Now, My controller action looks like:
public ActionResult LoadDescription(string id)
{}
Now, Suppose I have two templates:
In the first one, the ID textbox contains the value of "1".
In the second one, the ID textbox contains the value of "2".
When I press the button in the first template, I get to the controller action twice, both with the value of "1" (from the first template).
When I press the button in the second template, I get to the controller action once, with the value of "1" (from the first template, although I pressed the button of the second template).
Now, what I'm trying to achieve is quite simple logically: press button in first template, get to controller action once with value of "1".
press button in secondtemplate, get to controller action once with value of "2".
Also, the action in controller is responsible to calculate value for description and then fill in the description field. What should the action method return (I don't think I should perform a post for the whole form), and how do I receive it within the success function while using Ajax?
Thanks for any help.
I think you need to use classes for your buttons and editors instead of ids. In your code you have multiple text boxes all with Id=ID and multiple buttons with id=getDescBtn. So $("#ID").val() will just give you the value of the first element with id="ID" which is your first textbox.
As for updating the description, you can have your action return the description value and then set the description text box on the success of your ajax call.
#using (Html.BeginCollectionItem("Items"))
{
<table style="width: 100%">
<tr>
<td>
#Html.TextBoxFor(model => #Model.ID, new {#class = "ID" })
</td>
<td>
#Html.TextBoxFor(model => #Model.Description, readonly="readonly", new {#class = "Description" })
</td>
<tr />
<a role="button" class="getDescBtn">
</a>
</table>
}
<script type="text/javascript">
$(document).ready(function() {
$(".getDescBtn").on('click', function (event) {
$.ajax({
url: '#Url.Action("LoadDescription")',
async: false,
cache: false,
data: {id: $(this).parent().find(".ID").val()}
})
.success(function (data) {
$(this).parent().find(".Description").val(data.description )
});
});
});
public JsonResult LoadDescription(string id)
{
//your logic here
return Json(new {description )});
}

DropDownList with Textbox Input as filter criteria

I need to have a DropDownList or equivalent in ASP.NET MVC in a View, which is populated with a bunch of entries from a database.
When selected, the DropDownList should produce the List as usual, with the exception that the user can enter text into it, at which point the items in the DropDownList will be filtered based on the entered text.
The user should however still only be able to choose one of the options in the list.
It could be any other control, but preferably NOT a 3rd party thing.
It is possible by writing some jQuery code. But it is already available and it is open source, widely used
Use jQuery chosen and configure like below
$(".select").chosen();
I found a decent method that works.
The only problem with this is that it requires 2 separate controls (DropDownList and TextBox), but other than that, works beautifully.
HTML Code (declaration of controls) is:
<table>
<tr>
<td>
<div>
<%: Html.Label("Search Filter:")%>
</div>
</td>
<td>
<div>
<%: Html.TextBox("textBoxForFilterInput")%>
</div>
</td>
</tr>
<tr>
<td>
<div>
<%: Html.Label("The List")%>
</div>
</td>
<td>
<div>
<%: Html.DropDownList("listOfOptions")%>
</div>
</td>
</tr>
</table>
The JavaScript code is:
$(function () {
var opts = $('#listOfOptions option').map(function () {
return [[this.value, $(this).text()]];
});
$('#textBoxForFilterInput').keyup(function () {
var rxp = new RegExp($('#textBoxForFilterInput').val(), 'i');
var optlist = $('#listOfOptions').empty();
opts.each(function () {
if (rxp.test(this[1])) {
optlist.append($('<option/>').attr('value', this[0]).text(this[1]));
}
});
});
});
Then just populate #listOfOptions and then you should be good to go.
Alternatively, you could hook it up to a predefined list/array or fetch it from a database like I do.
This works like a charm, very simple and super fast.
Thanks to DMI for sending me on the right path.
His work on this can be found here.
For this .autoComplete of Jquery can be used.
HTML is like
<table><tr><td><input type="textbox" id="textBoxid" /> <div id="targetDiv" style="z-index:10"></div>
Jquery code will be like
$(function () {
$("#textBoxid").autocomplete({
appendTo: "#targetDiv",
position: { at: "bottom bottom" },
source: function (request, response) {
$.ajax({
url: '#Url.Action("ActionMethod", "Controller")',
type: "POST",
dataType: "json",
data: { searchString: request.term },
success: function (data) {
response($.map(data, function (item) {
return { label: item.ColumnValue, Id:item.ColumnId }
}))
}
})
},
select: function (event, ui) {
if (ui.item) {
// for saving the selected item id or any other function you wanna perform on selection
$('#hiddenfield').val($.trim(ui.item.Id));
}
}
});
Action Method will be like
[HttpPost]
public JsonResult MaterialDesc(string searchString)
{
// On searchString basis you can have your code to fetch data from database.
}
hope it can help you
:)

Jquery Post not reaching MVC Controller

Apologies if this i trivial, i have read many other comments and still cannot see what is wrong. I have done a few tutorials and they seem to work ok, so I am really missing something simple.
I have a basic 'remove' link that i want to do a JQuery Post back to the controller to remove an item from the database and then update the view.
My View / Javascript:
<script type="text/javascript">
$(function () {
$(".RemoveLink").click(function () {
var id = $(this).attr("data-id");
if (id != '') {
$.post("#Url.Content("~/Agent/Remove")", { "id": id }, function (data) { alert('Here i am'); });
}
});
});
#foreach (var item in Model.Object) {
<tr id="row-#item.ID">
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<a href="#" class="RemoveLink" data-id="#item.ID" >Remove</a>
</td>
</tr>
}
My Controller:
[HttpPost]
public ActionResult Remove(int id)
{
return Json(new { Data = "true" });
}
Any assistance will be great.
Use #Url.Action("Remove", "Agent") instead.
#Url.Content("...") is used to locate any static content of the site.
Cheers
Below code works well.
#foreach (var item in Model.Object) {
<tr id="row-#item.ID">
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<input type="button" class="RemoveLink" id="#item.ID" Value="Remove" />
</td>
</tr>
}
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$('.RemoveLink').live("click", function () {
Remove($(this));
});
});
function Remove(_this) {
var Id= $(_this).attr('id');
$.ajax({
type: 'POST',
url: '#Url.Action("Remove", "Agent")',
data: "{id: '" + Id + "'}",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
//do something here......
},
error: function () {
}
});
}
</script>

Using jQuery to post back to Controller

In my web page, I have a series of tables that basically just contain rows of information. Each of these is given an id in a for loop and I'm trying to reference them from outside that. I added classes to both the table and a 'Save Changes' button.
Essentially, my goal is for the user to be able to drag and drop rows around, thereby changing the order. Then they can click the 'Save Changes' button and this will post back to the server with the relevant information.
I am having trouble matching up the button to the relevant table and thereby submitting the id's of each row back to the server in an array. I have written the code to be able to be able to get the ids from each of the tables and their current order, but I don't know how to assign this to an array from within the button click jQuery.
Here is the View:
#foreach (var collection in Model.Collections)
{
<h2>#collection.Season</h2>
#Html.ActionLink("Delete Collection", "DeleteCollection", new { controller = "Edit", brand = collection.Brand.Name, season = collection.Season })
#Html.ActionLink("Edit Collection", "EditCollection", new { controller = "Edit", brand = collection.Brand.Name, season = collection.Season })
#Html.ActionLink("Add Image", "CreateImages", new { controller = "Edit", season = collection.Season })
<p>
To change the ordering of images, drag and drop to your desired position and then click the Save Changes button on the appropriate collection.
</p>
<table class="table-collection" id="table-#collection.Id">
<tr class="nodrop nodrag">
<th>
Id
</th>
<th>
Description
</th>
<th>
Image
</th>
<th>
Options
</th>
</tr>
#foreach (var image in collection.Images)
{
<tr id="#collection.Id-#image.Id">
<td class="dragHandle showDragHandle">
#image.Id
</td>
<td>
#image.Description
</td>
<td>
<img src="#Url.Content("~/" + image.Location)" alt="#image.Description" />
</td>
<td>
<ul>
<li>
#Html.ActionLink("Edit", "EditImage", new { controller = "Edit", brand = image.Collection.Brand.Name,
season = image.Collection.Season, imageId = #image.Id } )
</li>
<li>
#Html.ActionLink("Delete", "DeleteImage", new
{
controller = "Edit",
brand = image.Collection.Brand.Name,
season = image.Collection.Season,
imageId = #image.Id
})
</li>
</ul>
</td>
</tr>
}
</table>
<p>
<input type="submit" value="Save Changes" class="save-order" id="saveTable-#collection.Id"/>
</p>
}
Here is the jQuery so far:
$(document).ready(function () {
$(".table-collection").tableDnD();
$(".save-order").click(function (e) {
e.preventDefault();
$.ajax({ url: window.location.href,
type: 'POST',
data: { ids: $("--ASSIGN ARRAY HERE--"
});
The jQuery to iterate through each row is essentially this:
function(table, row) {
var rows = table.tBodies[0].rows;
var debugStr = "Row dropped was "+row.id+". New order: ";
for (var i=0; i<rows.length; i++) {
debugStr += rows[i].id+" ";
}
I see you are using input type submit which is exclusively used to postback forms. What you need to do is wrap every table up in a form with something like this:
#using(Html.BeginForm("Action", "Controller", new{ collectionId = collection.Id }))
{
<input type="submit" value="Save Changes" class="save-order" />
}
Note that this will cause a 'post-back' of the form to Action, Controller. Specify the collection id inside the route values to identify the specific collection.
Do note, you need to add input type hidden with the id's value otherwise the ids' won't get serialised - all you have to specify is the name attribute
<td class="dragHandle showDragHandle">
<input type="hidden" name="ids" value="#(image.Id)" />
#image.Id
</td>
Then you can intercept the call then do it via ajax with:
$(".save-order").click(function(e) {
e.preventDefault();
var form = $(this).closest('form');
if(form.validate()) {
$.post(form.attr('action'), form.serialize(), function() {
alert('The new image order has been saved.');
});
}
return false;
});
The accepting controller action method will probably have this signature
public ActionResult Action(int collectionId, int[] ids)
{
//Do stuff here
return Request.IsAjaxRequest() ? null : View();
}
Now it should support graceful degradation if javascript is disabled (does a normal form submit, otherwise does it via ajax)
Hope this helps :)
You can grab all of the IDs with something like this:
var IDs = [];
$("#mydiv").find("span").each(function(){ IDs.push(this.id); });
In your scenerio, do something like this:
$(document).ready(function ()
{
$(".table-collection").tableDnD();
$(".save-order").click(function (e)
{
var IDs = [];
$("#yourtable").find("draggable-tr-class").each(function(){ IDs.push(this.id); });
e.preventDefault();
$.ajax(
{
url: window.location.href,
type: 'POST',
data: { ids: IDs }
);
}
})
i have been create demo in jsfiddle using json
http://jsfiddle.net/viyancs/4ffb3/11/
if you use like that demo in your server must be get parameter `JSONFile' after that parse this json for what do you want.actually the demo not same with your case but i think you can use this by your logic.

Categories