Ajax.Beginform refreshing whole page - ajax

It redirects to whole new page instead of just updating the current one, I have unobtrusive scripts and web.config stuff. Why is this not working?
<div id="preview-image-placeholder"></div>
#foreach (var item in Model)
{
using (Ajax.BeginForm("PreviewImage/" + #item.Id.ToString(), "Music", null, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, UpdateTargetId = "preview-image-placeholder" },
new { #enctype = "multipart/form-data", #item.Id }))
{
#Html.AntiForgeryToken()
<input type="file" class="upload-image" id="upload-image-file_#item.Id" name="file" accept="image/*">
<button class="btn btn-default" id="btn-preview_#item.Id" style="display: none" type="submit"></button>
}
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
Controller:
[ValidateAntiForgeryToken]
[HttpPost]
public PartialViewResult PreviewImage(HttpPostedFileBase file, int id)
{
//Do other code stuff
return PartialView("_DisplayImage", song);
}
_DisplayImage partial view:
#model IEnumerable<MusicSite.Models.UploadedSong>
#using MusicSite.CustomHtmlHelpers;
#foreach(var item in Model)
{
if (#item.CoverImageBytes != null)
{
#Html.ImageFor(x => item.CoverImageBytes, #item.SongName + " Image", new { #id = "preview-image" })
}
}

Besides unobtrusive scripts you must add Microsoft Ajax libraries too (MicrosoftAjax.js and MicrosoftMvcAjax.js) so that Ajax.BeginForm works correctly.
Regards,

Related

Ajax.BeginForm does not insert partial view

Running ASP.NET MVC 2015 with C#.
Trying to add a partial view as a result of #using (Ajax.BeginForm(...)
All it does is to open a new page with my partial view in it. I found some answers in stackoverflow, but none works for me, unless I missed something.
Scenario:
index page here
Type A, B or C and partial view is expected below the current page
new page unexpected here
But it does open a new page instead
Controler:
public class TestController : Controller
{
public ActionResult Index()
{
return View();
}
[ChildActionOnly]
public ActionResult TestPartial()
{
ChoiceViewModel vm = new ChoiceViewModel();
return View(vm);
}
[HttpPost]
public ActionResult SelectChoice(ChoiceViewModel vm)
{
ModelState.Clear();
if (vm.MyChoice == "A")
return PartialView("APartial");
if (vm.MyChoice == "B")
return PartialView("BPartial");
if (vm.MyChoice == "C")
return PartialView("CPartial");
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
}
Index.cshtml:
<h2>Index</h2>
<div>
#Html.Partial("TestPartial")
</div>
<br/>
<div id="GoesHere">
</div>
TestPartial.cshtml:
#model TestPartial.ViewModels.ChoiceViewModel
#using (Ajax.BeginForm("SelectChoice", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "GoesHere", InsertionMode = InsertionMode.Replace }))
{
<div class="form-group">
<p>Give your choice please: A,B or C</p>
#Html.TextBoxFor(x => x.MyChoice, new { #class = "form-control" })
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Select">
</div>
}
APartial.cshtml (as well as B and C...)
<p>This is A choice</p>
Notes:
Yes, web.config has UnobtrusiveJavaScriptEnabled=true and ClientValidationEnabled=true
Yes, I installed the jquery.unobtrusive-ajax package
Can you tell me what I missed or did wrong ?
Thanks
The answer was that I was missing the unobtrusive-ajax inclusion line in my cshtml :
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>

How to pass data from View in Asp.NET MVC

i want to get the value of textbox for Controller
I used Ajax.ActionLink("Search","Result",new{id="**VALUE**"}, new AjaxOptions{...})
#* This is the Index.cshtml *#
<input id="cityName" type="text" class="form-control" placeholder="Enter a CityName">
#Ajax.ActionLink("Search", "Result", new { id = "I want to get the cityName" }, new AjaxOptions { HttpMethod = "Get", UpdateTargetId = "cityInfo", LoadingElementId = "loading" }, new { #class = "btn btn-default" })
<div id="cityInfo"> #When I click the actionlink , the controller will return a partialview
#Html.Partial("Result", Model)
</div>
#*This is the Result.cshtml*#
<p>
#if (#Model!=null)
{
#Model.cityInfo
}
</p>
this is the index.cshtml ->>
enter image description here
Thanks
public PartialViewResult Result(string cityName)//this is the controller
{
CityModel city = new CityModel(cityName);
city.getInfo();
return PartialView("Index",city);
}
You can write a function like below:
Ajax.ActionLink("Search","Result",new{id="id"}, new AjaxOptions{...}) //set temp value
$(document).ready(function(){
//init value
var value = $('#cityName').val();
var href = $('a').attr('href').replace('id', value);
$('a').attr('href', href);
});

Ajax.BeginForm only displaying partial View instead of parent & partial view on return

I have a parent View & a child View.
When posing with the Ajax.BeginForm, I'm expecting back the entire parent view plus the results of the partial view updated. Only the results of the partial view is displayed.
In addition, the "OnSuccess" method doesn't seem to be getting hit as I'm debugging.
Can someone please tell me what I'm doing incorrecty?
Controller:
public class HomeController : Controller
{
private DAL db = new DAL();
public ActionResult Index()
{
ViewBag.Message = "Welcome to YeagerTech!";
return View();
}
// GET: Categories/Create
public ActionResult Create()
{
return View();
}
// POST: Categories/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(Category category)
{
if (ModelState.IsValid)
{
try
{
await db.AddCategoryAsync(category);
}
catch (System.Exception ex)
{
throw ex;
}
}
return View(category);
}
public PartialViewResult ShowDetails()
{
//string code = Request.Form["txtCode"];
Category cat = new Category();
//foreach (Product p in prodList)
//{
// if (p.ProdCode == code)
// {
// prod = p;
// break;
// }
//}
cat.CategoryID = 1;
cat.Description = "Financial";
return PartialView("_ShowDetails", cat);
}
}
Parent View
#model Models.Models.Category
#{
ViewBag.Title = "Create Category";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Create Category</h2>
#using (Ajax.BeginForm("ShowDetails", "Home", new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "div1",
InsertionMode = InsertionMode.Replace,
OnSuccess = "OnSuccess",
OnFailure = "OnFailure"
}, new { #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<div class="body-content">
<h4>Category</h4>
<hr />
<div class="form-group">
<div class="col-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control", #placeholder = "Description" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-11 col-md-11 col-sm-11 col-xs-11">
<button type="submit" id="btnCategoryCreate" class="btn btn-primary"><span class="glyphicon glyphicon-save"></span>Create</button>
</div>
</div>
</div>
}
<div id="div1">
</div>
#*<div>
#Html.ActionLink("Back to List", "Index")
#Html.Hidden("categoryCreateUrl", Url.Action("Create", "Home"))
</div>*#
#section Scripts {
<script>
$(document).ready(function ()
{
function OnSuccess(response)
{
$('#form1').trigger("reset");
}
//if (typeof contentCreateCategory == "function")
// contentCreateCategory();
});
</script>
}
Partial View
#model Models.Models.Category
<h1>Cat Details</h1>
<h2>
Cat Code: #Model.CategoryID<br />
Cat Name: #Model.Description<br />
</h2>
EDIT # 1
Parent & child view displayed (due to a missing JS file, thanks to the mention of Stephen), plus was able to programmatically clear out the form with the OnSuccess method.
I had thought since that was JS, it needed to go in the Scripts section, but did not recognize it there.
Here is the finished code.
#using (Ajax.BeginForm("ShowDetails", "Home", new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "div1",
InsertionMode = InsertionMode.Replace,
OnSuccess = "OnSuccess",
OnFailure = "OnFailure"
}, new { #id = "frm1", #class = "form-horizontal" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary()
<div class="body-content">
<h4>Category</h4>
<hr />
<div class="form-group">
<div class="col-offset-1 col-lg-11 col-md-11 col-sm-11 col-xs-11">
#Html.EditorFor(model => model.Description, new { htmlAttributes = new { #class = "form-control", #placeholder = "Description" } })
#Html.ValidationMessageFor(model => model.Description, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-lg-11 col-md-11 col-sm-11 col-xs-11">
<button type="submit" id="btnCategoryCreate" class="btn btn-primary"><span class="glyphicon glyphicon-save"></span>Create</button>
<button type="reset" id="btnClear" class="btn btn-default"><span class="glyphicon glyphicon-eye-close"></span>Clear</button>
</div>
</div>
</div>
}
<div id="div1">
</div>
<script type="text/javascript">
function OnSuccess(response)
{
$('#frm1').trigger("reset");
}
function OnFailure(response)
{
alert("Whoops! That didn't go so well did it?");
}
</script>
A bit late for answer, but yet it might help someone else.
The issue might be that the javascript files required for Ajax.BeginForm are not loaded in your page.
Microsoft.jQuery.Unobtrusive.Ajax
Nuget package to search for
<package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.2.3" targetFramework="net45" />
of course that the version might differ.
Add reference to the page after your jQuery and it should work.

i'm stuck incrementing page variable in infinite scrolling with Ajax.BeginForm

I'm implementing infinite scroll in MVC 5, by Ajax.BeginForm invoking an action returns partial view, i'm struggling in incrementing the page variable it always send 1 to the action !!
Controller
public ActionResult Index()
{
home.Articles = GetArticlesByPage(home.Page);
return View(home);
}
public PartialViewResult NextPageArticles(int page)
{
home.Articles = GetArticlesByPage(page);
return PartialView("~/Views/Home/ArticlePostPartial.cshtml", home.Articles);
}
HomeViewModel
public class HomeViewModel
{
public IEnumerable<ArticleViewModel> _articles;
public IEnumerable<ArticleViewModel> Articles
{
get { return this._articles; }
set
{
this._articles = value;
Page++;
}
}
public int Page { get; set; }
public HomeViewModel()
{
Page = 0;
}
}
View
<div id="MainContainer" class="container-fluid">
#{Html.RenderPartial("ArticlePostPartial", Model.Articles);}
</div>
#using (Ajax.BeginForm("NextPageArticles", "Home", new { page = ??? }, new AjaxOptions
{
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "MainContainer",
LoadingElementId = "imgload",
OnSuccess = "OnSuccessAjax"
}))
{
<input type="submit" id="formbut" class="btn btn-danger hidden" />
}
Something like this should work for you.
<div id="MainContainer" class="container-fluid">
#{Html.RenderPartial("ArticlePostPartial", Model.Articles);}
</div>
#using (Ajax.BeginForm("NextPageArticles", "Home", new { page = Convert.ToInt32(Request.RequestContext.RouteData.Values["page"]) + 1 }, new AjaxOptions
{
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "MainContainer",
LoadingElementId = "imgload",
OnSuccess = "OnSuccessAjax"
}))
{
<input type="submit" id="formbut" class="btn btn-danger hidden" />
}

Uploading/Displaying Images in MVC 4

Anyone know of any step by step tutorials on how to upload/display images from a database using Entity Framework? I've checked out code snippets, but I'm still not clear on how it works. I have no code, because aside from writing an upload form, I'm lost. Any (and I mean any) help is greatly appreciated.
On a sidenote, why don't any books cover this topic? I have both Pro ASP.NET MVC 4 and Professional MVC4, and they make no mention of it.
Have a look at the following
#using (Html.BeginForm("FileUpload", "Home", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<label for="file">Upload Image:</label>
<input type="file" name="file" id="file" style="width: 100%;" />
<input type="submit" value="Upload" class="submit" />
}
your controller should have action method which would accept HttpPostedFileBase;
public ActionResult FileUpload(HttpPostedFileBase file)
{
if (file != null)
{
string pic = System.IO.Path.GetFileName(file.FileName);
string path = System.IO.Path.Combine(
Server.MapPath("~/images/profile"), pic);
// file is uploaded
file.SaveAs(path);
// save the image path path to the database or you can send image
// directly to database
// in-case if you want to store byte[] ie. for DB
using (MemoryStream ms = new MemoryStream())
{
file.InputStream.CopyTo(ms);
byte[] array = ms.GetBuffer();
}
}
// after successfully uploading redirect the user
return RedirectToAction("actionname", "controller name");
}
Update 1
In case you want to upload files using jQuery with asynchornously, then try this article.
the code to handle the server side (for multiple upload) is;
try
{
HttpFileCollection hfc = HttpContext.Current.Request.Files;
string path = "/content/files/contact/";
for (int i = 0; i < hfc.Count; i++)
{
HttpPostedFile hpf = hfc[i];
if (hpf.ContentLength > 0)
{
string fileName = "";
if (Request.Browser.Browser == "IE")
{
fileName = Path.GetFileName(hpf.FileName);
}
else
{
fileName = hpf.FileName;
}
string fullPathWithFileName = path + fileName;
hpf.SaveAs(Server.MapPath(fullPathWithFileName));
}
}
}
catch (Exception ex)
{
throw ex;
}
this control also return image name (in a javascript call back) which then you can use it to display image in the DOM.
UPDATE 2
Alternatively, you can try Async File Uploads in MVC 4.
Here is a short tutorial:
Model:
namespace ImageUploadApp.Models
{
using System;
using System.Collections.Generic;
public partial class Image
{
public int ID { get; set; }
public string ImagePath { get; set; }
}
}
View:
Create:
#model ImageUploadApp.Models.Image
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm("Create", "Image", null, FormMethod.Post,
new { enctype = "multipart/form-data" })) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Image</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ImagePath)
</div>
<div class="editor-field">
<input id="ImagePath" title="Upload a product image"
type="file" name="file" />
</div>
<p><input type="submit" value="Create" /></p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Index (for display):
#model IEnumerable<ImageUploadApp.Models.Image>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
#Html.DisplayNameFor(model => model.ImagePath)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ImagePath)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
#Html.ActionLink("Details", "Details", new { id=item.ID }) |
#Ajax.ActionLink("Delete", "Delete", new {id = item.ID} })
</td>
</tr>
}
</table>
Controller (Create)
public ActionResult Create(Image img, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
if (file != null)
{
file.SaveAs(HttpContext.Server.MapPath("~/Images/")
+ file.FileName);
img.ImagePath = file.FileName;
}
db.Image.Add(img);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(img);
}
Hope this will help :)
<input type="file" id="picfile" name="picf" />
<input type="text" id="txtName" style="width: 144px;" />
$("#btncatsave").click(function () {
var Name = $("#txtName").val();
var formData = new FormData();
var totalFiles = document.getElementById("picfile").files.length;
var file = document.getElementById("picfile").files[0];
formData.append("FileUpload", file);
formData.append("Name", Name);
$.ajax({
type: "POST",
url: '/Category_Subcategory/Save_Category',
data: formData,
dataType: 'json',
contentType: false,
processData: false,
success: function (msg) {
alert(msg);
},
error: function (error) {
alert("errror");
}
});
});
[HttpPost]
public ActionResult Save_Category()
{
string Name=Request.Form[1];
if (Request.Files.Count > 0)
{
HttpPostedFileBase file = Request.Files[0];
}
}

Resources