I'm using the kendo controls with MVC. I have a basic uploader working, but I need to create them dynamically and handle that code on the back end. Here's my simple example that's working
<input name="attachments" type="file" id="attachments" />
<script type="text/javascript">
$(document).ready(function () {
$("#attachments").kendoUpload({
async: {
saveUrl: '#Url.Action("Save", "AppConfig")',
autoUpload: true
}
});
});
</script>
[HttpPost]
public ActionResult Save(IEnumerable<HttpPostedFileBase> attachments)
{
if (SaveUploadedFile(attachments, "Background"))
{
return Content("");
}
else
{
return Content("error");
}
}
However, what I need to do is create the ids dynamically and handle it on the backend. So this is how I'm making the file uploaders
#foreach (var item in Model) {
string fid = String.Format("{0}{1}", #item.fieldType, #item.appConfigId.ToString());
<input name="#fid" id="#fid" type="file" />
<script type="text/javascript">
$(document).ready(function () {
$("##fid").kendoUpload({
async: {
saveUrl: '#Url.Action("Save", "AppConfig")',
autoUpload: true
}
});
});
</script>
}
Now I get that the HttpPostedFileBase argument has to match your id of your html element, but I have no idea how to modify the code behind, so that I can take in multiple uploaders. Any ideas?
Why don't you just use the multiple functionality of the Uploader? It is enabled by default.
Related
I'm trying to create an autocomplete text box using Jquery UI.
I can see that GetActiveItems works fine and i got a json result , but I can't see the autocomplete on the screen. I think that the problam is in the 'OnActionExecuted' when the ActionResult is being execute.
Please help me :)
thanks,
Siri
View:
<input type="text" id="mpvalue" name="mpvalue" />
<script type="text/javascript">
$(document).ready(function () {
$('#mpvalue').autocomplete({
source: '#Url.Action("GetActiveItems")'
});
})
</script>
Controller:
public ActionResult GetActiveItems(string term)
{
var result = from e in db.Items
where (e.IsBlock != true) && (e.Description.ToLower().Contains(term))
select e.Description;
return Json(result, JsonRequestBehavior.AllowGet);
}
I'm trying to implement the autocomplete function in my website, but won't work properly.
Here is the code of my view:
<script src="~/Scripts/jquery-ui-1.8.20.js" type="text/javascript"></script>
<script src="~/Scripts/jquery-ui-1.8.20.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function () {
$("#SearchString").autocomplete({
source: "/Test/AutocompleteSuggestions",
minLength: 1,
select: function (event, ui) {
if (ui.item) {
$("#SearchString").val(ui.item.value);
$("form").submit();
}
}
});
});
</script>
#using (Html.BeginForm())
{
<p>
Find by name: #Html.TextBox("SearchString")
<input type="submit" value="Search" /></p>
}
Here is code of my autoComplete controller action:
public JsonResult AutocompleteSuggestions(string searchstring)
{
var suggestions = from s in db.Students
select s.Name;
var namelist = suggestions.Where(n => n.ToLower().StartsWith(searchstring.ToLower()));
// return namelist.ToList();
return Json(namelist, JsonRequestBehavior.AllowGet);
}
Can anyone help me ?
Thanks in advance
you are trying to pass IQueryable. try replacing it with
return Json(namelist.ToList(), JsonRequestBehavior.AllowGet);
if that still doesnt work.
try replacing "searchString" to "term"
public JsonResult AutocompleteSuggestions(string term)
Ive read an article that you must use the "term" query string. but Im not pretty sure about it.
i have four different forms on my page and each are ajax forms.
I'm sending post request for first form with ajax to MVC Controller, it basically returns ViewData["TEST"] back to me.
I want to use ViewData on my view and i need set this to a hidden field for use other forms.
How i can reach it without using normal submit ?
Here is my code:
#using (Ajax.BeginForm("Index", new AjaxOptions{ HttpMethod = "POST" }))
{
<script type="text/javascript"> alert('#(ViewData["TEST"])'); </script>
<input type="text" name="name" />
<input type="button" onclick="javacript:SubmitAjax();" />
}
<script type="text/javascript">
function SubmitAjax() {
$.ajax({
type: 'POST',
data: $("#form0").serialize(),
url: "/Home/Index",
timeout: 2000,
async: false,
success: function (data) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(message_Error);
}
});
}
And Controller;
[HttpPost]
public ActionResult Index(string name)
{
ViewData["TEST"] = "TESTSTRING";
return View();
}
No ViewData !!!! . Simply return the content.
[HttpPost]
public ActionResult Index(string name)
{
return Content("TESTSTRING");
}
and to set this in the hidden field,you can do so int he success event of your ajax function
success: function (data) {
$("#hiddenElementID").val(data);
},
Also do not hard code the Path to action method like that. Always make use of the HTML helper methods.
Replace
url: "/Home/Index"
with
url: "#Url.Action("Index","Home")"
I personally prefer to avoid the AjaxBeginForm method and would like to write some clean handwritten javascript code to handle this.
#using(Html.Beginform())
{
<input type="text" name="name" />
<input type="submit" id="saveName" value="Save" />
}
<script type="text/javascript">
$(function(){
$("#saveName").click(function(e){
e.preventDefault();
$.post("#Url.Action("Index","Home")",
$(this).closest("form").serialize(),
function(data){
$("#yourHiddenElementID").val(data);
});
});
});
</script>
EDIT : As per the comment.
If you want to return multiple items, You can return JSON
Ex 2 : returning anonymous type to JSON
[HttpPost]
public ActionResult Index(string name)
{
return JSON(new { status : "true", ItemCount=35, UserName="Marc"} );
}
Ex 1 : returning a ViewModel to JSON
Assuming you have a class like
public class Result
{
public string Status { set;get;}
public int ItemCount { set;get;}
public string UserName { set;get;}
}
Now you can use this class and return it as JSON
[HttpPost]
public ActionResult Index(string name)
{
return JSON(new Result { Status : "true",
ItemCount=25, UserName="Scott"} );
}
PartialView
#model OsosYeni23072012.Models.TblMeters
<h3>
Model.customer_name
</h3>
<h3>
Model.meter_name
</h3>
Controller
[HttpGet]
public ActionResult MeterInfoPartial(string meter_id)
{
int _meter_id = Int32.Parse(meter_id);
var _meter = entity.TblMeters.Where(x => x.sno == _meter_id).FirstOrDefault();
return PartialView("MeterInfoPartial", _meter);
}
Razor
#Html.DropDownList("sno", new SelectList(Model, "sno", "meter_name"), "-- Select Meter --", new { id = "meters"})
#Html.Partial("MeterInfoPartial")
I want to load partial view, if dropdownlist change. But I dont know How can I do this. I cant find any example about this. I do this with actionlink. But I did not with dropdown before.
controller parameter meter_id equals dropdownlist selectedvalue.
Thanks.
You could subscribe to the .change() event of the dropdown and then trigger an AJAX request:
<script type="text/javascript">
$(function() {
$('#meters').change(function() {
var meterId = $(this).val();
if (meterId && meterId != '') {
$.ajax({
url: '#Url.Action("MeterInfoPartial")',
type: 'GET',
cache: false,
data: { meter_id: meterId }
}).done(function(result) {
$('#container').html(result);
});
}
});
});
</script>
and then you would wrap the partial with a div given an id:
<div id="container">
#Html.Partial("MeterInfoPartial")
</div>
Also why are you parsing in your controller action, leave this to the model binder:
[HttpGet]
public ActionResult MeterInfoPartial(int meter_id)
{
var meter = entity.TblMeters.FirstOrDefault(x => x.sno == meter_id);
return PartialView(meter);
}
Be careful with FirstOrDefault because if it doesn't find a matching record in your database given the meter_id it will return null and your partial will crash when you attempt to access the model.
<script type="text/javascript">
$(function() {
$('#addnews').click(function() {
$.ajax({
url: '#Url.Action("AddNews", "Manage")',
type: 'GET',
cache: false,
}).done(function(result){
$('#containera').html(result);
});
});
});
</script>
<script src="../../Scripts/MicrosoftAjax.debug.js" type="text/javascript"></script>
<script type="text/javascript">
function loginOK()
{
var item = document.getElementById('statusLabel');
item.innerHTML = "OK";
document.getElementById('LoadImg').style.visibility = 'hidden';
}
function process()
{
var lab = document.getElementById('statusLabel');
lab.innerHTML = 'Checking...';
lab.style.color = 'Black';
document.getElementById('LoadImg').style.visibility = 'visible';
}
function fail()
{
var lab = document.getElementById('statusLabel');
lab.innerHTML = 'Login is being used';
lab.style.color = 'Red';
document.getElementById('LoadImg').style.visibility = 'hidden';
}
</script>
<div style="width:30%; float:left;">
<label for="Login">Login:</label>
<%= Html.TextBoxFor(model=>model.Login) %>
<%= Html.ValidationMessageFor(model=>model.Login) %>
<img id="LoadImg" alt="" src="../../Content/Images/ajax-loader.gif" style="visibility:hidden;"/>
<br />
<label id="statusLabel" />
<br />
<%=Ajax.ActionLink("CheckLogin","CheckLoginAvailability", "Account",
new AjaxOptions { UpdateTargetId = "statusLabel", OnBegin = "process", OnFailure = "fail", OnSuccess="loginOK"})%>
</div>
and, in the AccountController:
[AcceptVerbs(HttpVerbs.Post)]
public void CheckLoginAvailability(string login)
{
//do some job
}
And, FireBug says that /Account/CheckLoginAvailability is not found. Also, after callback that ActionLink is hidden. Why ?
You are talking about Ajax.BeginForm in your question but this is nowhere to be seen in the markup you provided. There are a couple of issues that I can see with your code:
Your action method doesn't return an ActionResult. Yeah I know, you will say that this is possible, right, but that's against any good practices, conventions and rendering your controllers unit-test friendly.
You are using Microsoft Ajax which will mix markup and javascript which IMHO is bad for multiple reasons: increasing bandwidth which of course leads to decreased performance, incapacity to externalize javascript into separate files in order to cache them by client browsers, having to write things like document.getElementById, innerHTML, style.color, style.visibility, etc... which is not guaranteed to work cross browser.
Here's what I would suggest you to improve this. While this doesn't answer your question, take it as an alternative approach.
As always the first thing to deal with is to define a model which in your case might look something like this:
public class LoginViewModel
{
public string Login { get; set; }
}
Of course you might wish to add other fields such as Password, but this is out of scope for the moment. The next step is to write a controller dealing with this model (in parallel you should be already setting a unit-test for the future controller to prepare the ground):
public class HomeController : Controller
{
public ActionResult Index()
{
// Simply return the Login form
return View(new LoginViewModel());
}
[HttpPost]
public ActionResult Index(LoginViewModel model)
{
// Deal with the actual authentication, etc...
throw new NotImplementedException();
}
[HttpPost]
public ActionResult CheckLoginAvailability(LoginViewModel model)
{
// TODO: query your datasource to determine whether
// model.Login is taken
// For this purpose we will suppose that it is taken
bool isLoginTaken = true;
// return a JSON object containing the result
return Json(new { IsLoginTaken = isLoginTaken });
}
}
The last part is to paint the screen:
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<SomeNs.Models.LoginViewModel>" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Login</title>
<!-- Use a separate CSS to avoid mixing markup with styling -->
<link rel="stylesheet" type="text/css" href="<%: Url.Content("~/content/site.css") %>" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<!-- Always use HTML helpers when dealing with Urls -->
<script type="text/javascript" src="<%: Url.Content("~/scripts/login.js") %>"></script>
</head>
<body>
<% using (Html.BeginForm()) { %>
<%: Html.LabelFor(x => x.Login) %>:
<%: Html.TextBoxFor(x => x.Login) %>
<%: Html.ValidationMessageFor(x => x.Login) %>
<br/>
<!-- Always use HTML helpers when dealing with Urls -->
<img id="loadImg" alt="" src="<%: Url.Content("~/content/images/ajax-loader.gif") %>" style="display:none;" />
<br />
<div id="statusLabel"></div>
<br />
<!-- Give this link an id so that we can easily identify it from javascript -->
<%: Html.ActionLink("CheckLogin", "CheckLoginAvailability", "Home", null, new { id = "checkLogin" })%>
<input type="submit" value="Login" />
<% } %>
</body>
</html>
And the last part is to unobtrusively attach our javascript (using jQuery of course) in the login.js file:
// When the DOM is ready
$(function () {
// Attach a click handler to the checkLogin link
$('a#checkLogin').click(function () {
// When this link is clicked send an AJAX POST request
// to the address this link is pointing to
$.ajax({
type: 'POST',
url: this.href,
// Pass as parameter in the POST body the login
// entered by the user
data: { login: $('#Login').val() },
beforeSend: function () {
// show the spinner image before sending any AJAX request
// to inform the user of an ongoing activity
$('#loadImg').show();
},
complete: function () {
// hide the spinner image when the AJAX request completes
// no matter if it succeeded or not
$('#loadImg').hide();
},
success: function (result) {
// if the AJAX request succeeds
// query the IsLoginTaken property
// of the resulting JSON object
if (result.IsLoginTaken) {
// Show the status label with red if the login is taken
$('#statusLabel').html('Login is being used').css('color', 'red');
} else {
// Show the status label in black if the login is not taken
$('#statusLabel').html('OK').css('color', 'black');
}
}
});
return false;
});
});
As #SLaks says actions can return void but, I think the action signature is such that it is required to return an action result and you can return EmptyResult if you don't want to return anything.
see this http://www.asp.net/mvc/tutorials/asp-net-mvc-controller-overview-cs
try changing your AccountController to
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CheckLoginAvailability(string login)
{
//do some job
return new EmptyResult();
}