MVC3 Dynamic list update issue - asp.net

I have a dynamic list and I need to return the selected items from view back to the controller. I have checked the link CheckboxList in MVC3 View and get the checked items passed to the controller the problem is i have a dynamic list and i need to display it horizontally so i am using
<table>
<tr>
#foreach (var item in mylist)
{
<td><img src='#item.PictureUrl'/><br />#Html.CheckBox(#item.Id,#item.checkedin)#item.Name</td>
}
</tr>
</table>
I also have a textarea in the same form.
In the controller post method, I am able to access the textarea value but not the list or checked items. please help.
Or is there any other better way to display my list and get back the checklist items?
I am new to MVC, any help would be appreciated.
Thanks

Using the JQuery is the best way:
1- Download Jquery.json.js and add it to your view:
<script src="../../Scripts/jquery.json.js" type="text/javascript"></script>
2- add a ".cssMyClass" to all checkboxes so you can grab the values by their css class:
<script type="text/javascript" >
$(document).ready(function () {
$("#btnSubmit").click(sendValues);
});
function populateValues()
{
var data = new Array();
$('.myCssClas').each(function () {
if ($(this).attr('checked')) {
var x = $(this).attr("value");
data.push(x);
}
});
return data;
}
function sendValues() {
var data = populateValues();
$.ajax({
type: 'POST',
url: '#Url.Content("~/Home/Save")',
data: $.json.encode(data),
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function () { alert("1"); }
});
}
</script>
As you can see I've added all selected values to an Array and I've passed it to "Save" action of "Home" controller by ajax
*- in Controller you can receive the values by adding an array as argument:
[HttpPost]
public ActionResult Save(int[] val)
{
I've searched too much but apparently this is the only solution. Please let me know if you find a better solution for it.

Related

Accessing div in view from controller

In my layout page I've got this html:
<div id="ajax-loading" class="global-loading-image" runat="server">
<img src="/content/travelbill/img/small-loading-image.gif"/>
</div>
Which is a loading-symbol. I want it to show when my code is doing its business.
I've read on other threads here on Stackoverflow that if you use runat="server", you are supposed to be able to access the div in the controller. Like so:
ajax-loading.Visible = true;
EditTravelBillViewModel model = this.travelBillService.GetTravelBill(travelBillId);
model.StageOfProcess = (int)TravelBillStageOfProcessEnum.APPROVED;
this.travelBillService.Update(model, true);
ajax-loading.Visible = false;
return RedirectToAction("GetTravelBillsPerCompany");
But I get the error that the loading and the ajax do not exist in the current context. What am I doing wrong?
That was in the old ASP.NET pages. In ASP MVC you don't have a ViewState, isPostBack or runat="server" you can pass variables from the controller to the view using ViewBag and ViewData like:
Controller:
ViewBag.Name = "My Name";
ViewData["Name"] = "My Name";
View:
#ViewBag.Name
#ViewData["Name"]
I don't think you need to do that. You can have a action that do the task that you need to get done and with JavaScript request that action via AJAX. You can then with JavaScript show and hide the loading as you wish:
function LoadAjax(containerId, url, params){
//Set loading in container
$(containerId).html('<img src="loading.gif" alt="loading"/>');
//Do the request
$.ajax({
type: 'POST',
dataType: "html",
url: url,
data: params,
success: function(data){
// show response inside container (removes loading)
$(containerId).html(data);
},
error: function( jqXHR, textStatus, errorThrown){
// show error inside container (removes loading)
$(containerId).html(textStatus);
}
});
}
While the page is loading it will display the loading image. You will need Jquery to use my code. Hope it helps.

KendoUI Grid Custom Toolbar Action to delete selected items

I'm trying to add a new Custom Toolbar Action to my Kendo UI Grid but am lost on how to get the desired behaviour.
I need a button that I can click that will invoke an action method and pass in the collection of selected items in the grid so I can do a bulk delete (or some other action against all of the records)
Can anyone help ?
Currently I have: -
.ToolBar(toolbar =>
{
toolbar.Custom().Action("Users_DeleteSelected", "Users").Text("Delete Selected");
})
This invokes my method thus: -
public ActionResult Users_DeleteSelected([DataSourceRequest] DataSourceRequest request)
{
// We need the list of selected UI items *here* so we can delete them - but how
...???
// Just redirect for now, we need to test getting the list of selected items here...
RedirectToAction("Index");
}
So if I have several items "selected" in the grid, I somehow want to invoke a method like the one above (Users_DeleteSelected) and have it get passed in the list of items to delete, then redirect to the Index once the delete is complete.
** This may not just be linked to deleting - there may in future be several other functions that will be required that fit the same method - i.e. "Mark As Complete" on a list of jobs for example.
I'm guessing maybe the DataSourceRequest isn't the way to go and that maybe I need to add some client side code to somehow assemble the list of selected items.
KendoUI is great but I need more examples.
Thanks for your kind replies. We've figured it out with a bit of searching and the like.
Firstly "kudos" to "this post" on the kendoui site as it pointed me in the right direction.
It turns out that this is what we need: -
In the. cshtml file for the grid...
// .... Other grid stuff
.ToolBar(toolbar =>
{
toolbar.Custom().Text("Test Button").Url("#").HtmlAttributes(new { #class = "test-button" });
})
// And then also...
$(document).ready(function () {
$(".test-button").click(testFunction)
})
// And finally
function testFunction(e) {
kendoConsole.log("Items Selected");
e.preventDefault();
var grid = $("#Grid").data("kendoGrid");
var selection = [];
grid.select().each(
function () {
var dataItem = grid.dataItem($(this));
selection.push(dataItem);
}
);
$.ajax({
type: "POST",
url: "Users/Users_DeleteSelected",
data: JSON.stringify({ items: selection }),
dataType: "html",
contentType: "application/json; charset=utf-8",
success: function (form) {
document.open();
document.write(form);
document.close();
}
});
};
Then in the controller we simply have: -
[HttpPost]
public ActionResult Users_DeleteSelected(List<UserViewModel> items)
{
// Stub to redirect for now
return RedirectToAction("Index");
}
And that's it. All of the items currently selected in the grid will be posted back to the correct action method and the jobs done.
Thanks.
Sounds like you are looking for batch editing capability. Take a look at this Kendo batch editing example. You can control whether to batch or not on the DataSource.

In ASP.NET, a POST/Redirect/GET sequence with AJAX hits the redirected-to action twice

Inside a view, I have the following:
#using (Html.BeginForm())
{
<input type="submit" id="savebtn" value="Save" onclick="saveLayout()"/>
}
<script type="text/javascript">
function saveLayout() {
$.ajax({
url: '/Page/SaveFaces/',
data: {
/* layout data of the page, irrelevant */
},
type: 'post',
success: function () {
}
});
return false;
}
</script>
The above hits the following action, which simply redirects the user back to the URL they came from (it's also supposed to save the data, but I've removed that part for simplicity, as it doesn't affect the problem):
[HttpPost]
public ActionResult SaveFaces(string items)
{
return Redirect(Request.UrlReferrer.AbsoluteUri);
}
Then, due to the redirect, we go back to this pretty standard model-fetching action:
public ActionResult Index(int id = 0)
{
var page = db.Pages.Find(id);
if (page == null) return HttpNotFound();
return View(page);
}
The problem is that this last action is called twice.
I have tried removing the AJAX call and doing a normal POST operation and the problem goes away. However, the data I'm trying to send is obtainable only through the a jQuery script and I can't put them in a form. I'm constrained to work with the AJAX method.
Is there anything I can do to prevent the action from being hit twice?
I see you are using jQuery. Can you try this instead? (Note you may have to bind the the form submit event rather than the input button, or both)
#using (Html.BeginForm())
{
<input type="submit" id="savebtn" value="Save" >
}
<script type="text/javascript">
$("#savebtn").submit(function saveLayout(event) {
// The magic that prevents post.
event.preventDefault();
$.ajax({
url: '/Page/SaveFaces/',
data: {
/* layout data of the page, irrelevant */
},
type: 'post',
success: function () {
}
});
return false;
}
</script>
Also if you have access to form element, another way:
<form onsubmit="javascript: return false;">
Though it might be a bit specific to my scenario, I just found an acceptable solution. Since all the data is provided through jQuery, I removed the form completely and replaced the submit button with a simple link.
So, this goes away:
#using (Html.BeginForm())
{
<input type="submit" id="savebtn" value="Save" />
}
And this is put in place instead:
<a onclick="saveLayout()" id="saveLink">Click to save.</a>
Now the [HttpPost] action is hit, the data is saved and the redirected-to action is also hit, once.

How to post parameter value to some actionlink

In my view i have 10 link every link associated with some unique value. Now i want that associated value at my controller action and from that action i want to redirect the flow to some other action based on that value.
But the condition is i dont want to display it on url.
How can i acheive this?
I tried ajax.post/#Ajax.ActionLink but doing this will not facilitate redirect to another action.
Is there anything with route i need to do?
View
<ul>#foreach (var item in Model)
{<li>
#Ajax.ActionLink(item.pk_name, "Index","Candidate", new { para1= item.para1 }
, new AjaxOptions { HttpMethod = "POST" })</li>
}</ul>
Action
[HttPost]
public ActionResult(int para1)
{
return RedirectToAction(para1,"anotherController");
}
I am getting value at para1 with ajax post(that is what i primarily needed) but here also want to redirect my application flow base on para1 value which is action name.
Confision : here i am not sure is this is the right way to do this thing. So i am asking you guys should i go for route map of working with ajax post will solve my objective.
If you only need to redirect the user based on what he clicks on without showing him the link, I believe the best way to achieve this is by client-side coding.
In my opinion there is no need to take any request through the server in order to change the page for such a low-complexity redirect.
View
// HTML
// Might be broken, been awhile since I worked with MVC
// Can't really remember if that's how you put variables in HTML
<ul id="button-list">
#foreach(var item in Model)
{
<li class="buttonish" data-para1="#item.para1">#item.pk_name</li>
}
</ul>
// JS
// I wouldn't do any server related work
$('#button-list li.buttonish').click(function(){
// Your controller and action just seem to redirect to another controller and send in the parameter
window.location.href = "/controller/method/" + $(this).data('para1');
});
I think you should make one jQuery function that is call when clicked and pass unique parameter.In that function you can use AJAX and post it on appropriate controller method.
Example:
<input type="button" id="#item.pk_name" onclick="getbuttonvalue(#item.para1);" />
In script
<script type="text/javascript">
$(document).ready(function () {
function getbuttonvalue(para1) {
$.ajax({
cache: false,
type: "POST",
dataType: 'json',
url: "/controller/method/" + para1,
success: function (data) {
}
});
}
});
</script>

Displaying PartialView when user enters text? Like an Autocomplete feature?

I've watch the videos on asp.net and I've looked online and have found nothing.
I have a search box on a site, that searches for recipes. Each recipe has a what you're making image, a title, and type(dessert, lunch, dinner).
All of these items are in a DataService, which I can query against and get a list of the items they are searching for.
Now I'm using VB's ASP.NET MVC3 w/ Razors for the site and I'm trying to get some auto completeness going on when the user enters text.
What should happen is when the user enter text, it will call an ActionResult in the Search Controller. Which queries the DataService and puts all the search results in a model. With that model I return a PartialView, results, with the Model included.
And it should display that partial view, but when the users deletes all the text I will remove the partial view.
Here's what I implemented. In the Layout View
#Code
Using Ajax.BeginForm("FastSearchResults", "Search", "", New AjaxOptions With {.UpdateTargetId = "searchitems", .HttpMethod = "GET", .InsertionMode = InsertionMode.Replace})
Html.BeginForm("Results", "Search", FormMethod.Get)
#<input type="text" name="id" id="searchbox" data-autocomplete="#Url.Action("FastSearchResults", "Search")" class="recipevox" value="Search Movie Title or Actor Here" />
Html.EndForm()
End Using
End Code
<span id="searchitems"></span>
The FastResult Method
Function FastSearchResults(ByVal id As String) As ActionResult
Dim model = search.FastSearch(id)
Return PartialView("_FastSearchResults", model)
End Function
Javascript Code
$(document).ready(function () {
$(":input[data-autocomplete]").autocomplete({ source: $(this).attr("data-autocomplete") }); });
I curious as to why this doesn't work, what else am I missing?
Your FastSearchResults controller action returns a partial view which presumably contains HTML. The autocomplete plugin doesn't expect HTML. It expects text or JSON. So to make this work you could have a different controller action specifically for the autocomplete:
<HttpPost()>
Function SearchResults(ByVal id As String) As ActionResult
' TODO: Query your service and return a list of model containing Id and Value properties
Dim model = Enumerable.Range(1, 10).Select(Function(x) New With {.Id = x, .Value = "item" & x})
Return Json(model)
End Function
and then setup your autocomplete:
<script src="#Url.Content("~/Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.js")" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$(":input[data-autocomplete]").autocomplete({
source: function (request, response) {
$.ajax({
url: this.element.attr('data-autocomplete'),
type: 'POST',
data: { id: request.term },
success: function (result) {
response(
$.map(result, function (item) {
return {
// Here we must map between the server side JSON
// and the autocomplete expected format
label: item.Value,
id: item.Id
};
})
);
}
});
},
minLength: 2
});
});
</script>
As far as the other controller action which returns a partial view you could keep it and it will be executed when the form is submitted using AJAX and the results of it will be injected into the #searchitems div.

Resources