ASP.NET MVC Create function not working on page - c#

I've created a page that uses entity framework to retrieve/Display info in the database I've also got create functionality in a partial view on the same page but it doesn't save/insert data.
Here is my Home View:
#model IEnumerable<TerminalHost.Models.buildingInfo>
#{
ViewBag.Title = "Home Page";
}
<h3>We suggest the following:</h3>
<ol class="round">
<li class="one">
<h5>Please begin creating your network structure:</h5> <button id="modal-opener">Add a new building</button>
</li>
<li class="two">
</li>
</ol>
<div class="Container">
<div class="Box1">
#foreach (var item in Model)
{<div>
<h4 class="Heading">#item.buildingName</h4>
<h4 class="Heading">#item.buildingNumber</h4>
<p>#item.buildingDesc1</p>
<p>#item.buildingDesc2</p>
<p>#item.buildingDesc3</p>
</div>
}
</div>
</div>
<div id="Modal" title="Building Details">
#Html.Partial("buildForm", new TerminalHost.Models.buildingInfo())
</div>
Here is my partial View:
#model TerminalHost.Models.buildingInfo
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>buildingInfo</legend>
<div class="editor-label">
#Html.LabelFor(model => model.buildingNumber)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.buildingNumber)
#Html.ValidationMessageFor(model => model.buildingNumber)
</div>
....
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
And This is my controller:
public class HomeController : Controller
{
thDB _db = new thDB();
public ActionResult building()
{
var buildingModel = _db.buildings.ToList();//you have to remove the FirstOrDefault() extension method
return View(buildingModel);
}
public ActionResult buildForm()
{
return PartialView();
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult buildForm(buildingInfo buildinginfo)
{
if (ModelState.IsValid)
{
_db.buildings.Add(buildinginfo);
_db.SaveChanges();
return RedirectToAction("Index");
}
return PartialView(buildinginfo);
}
protected override void Dispose(bool disposing)
{
if(_db != null)
{
_db.Dispose();
}
base.Dispose(disposing);
}
}
I've attempted to replicate the same code as the scaffold template that is created to do the CRUD functions but they are separated out into different views whereas I want them all on one page.

What you need it's to tell your partial view the Action to call.
Could you change this line:
#using (Html.BeginForm())
To
#using (Html.BeginForm("builForm","Home"))
And in your Action:
HttpPost]
[ValidateAntiForgeryToken]
public ActionResult buildForm(buildingInfo buildinginfo)
{
if (ModelState.IsValid)
{
_db.buildings.Add(buildinginfo);
_db.SaveChanges();
return RedirectToAction("Index");
}
return PartialView(buildinginfo);//instead of return this you can redirect to Index so you can see the update. Just a suggestion
}

Related

C# ASP.NET MVC Create Button is not working on click

My create button isn't working when clicked on. Can someone please tell me where I went wrong?
I tried a few forums but they haven't solved the issue.
Controller:
using Rentals.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Rentals.Controllers
{
public class GenreController : Controller
{
private ApplicationDbContext db;
public GenreController()
{
db = new ApplicationDbContext();
}
// GET: Genre
public ActionResult Index()
{
return View(db.Genres.ToList());
}
//getaction
public ActionResult Create()
{
return View();
}
//post action to insert data into database
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Genre genre)
{
if (ModelState.IsValid)
{
db.Genres.Add(genre);
db.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
protected override void Dispose(bool disposing)
{
db.Dispose();
}
}
}
View (create.cshtml):
#model Rentals.Models.Genre
#{
ViewBag.Title = "Create";
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
}
<div class="form-horizontal">
<h3> Create new Genre</h3>
<hr />
<div class="form-group">
#Html.LabelFor(m=>m.Name, htmlAttributes: new { #class ="control-label col-md-2"})
<div class="col-md-10">
#Html.EditorFor(m=>m.Name, new {htmlAttributes = new {#class="form-control"}})
#Html.ValidationMessageFor(m=>m.Name,"", new { #class = "text-danger"})
</div>
</div>
</div>
<div>
<input type="submit" value="Create" class="btn btn-sm btn-success" />
#Html.Partial("_BackToListPartial")
</div>
When I click on the create button it should add to the database. For some reason when I click it, it's not doing anything.
Wrap the form around your HTML.
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h3> Create new Genre</h3>
<hr />
<div class="form-group">
#Html.LabelFor(m=>m.Name, htmlAttributes: new { #class ="control-label col-md-2"})
<div class="col-md-10">
#Html.EditorFor(m=>m.Name, new {htmlAttributes = new {#class="form-control"}})
#Html.ValidationMessageFor(m=>m.Name,"", new { #class = "text-danger"})
</div>
</div>
</div>
<div>
<input type="submit" value="Create" class="btn btn-sm btn-success" />
#Html.Partial("_BackToListPartial")
</div>
}

How do i pass multiple actionresults from home controller to index.cshtml view

This is my controller code. The first method is to get 5 post to display in the homepage.
The second method is to display recent post in the sidebar.
How do I link it to display in the View which already shows the posts for the Index action?
Controller:
namespace ThelmaBlog.Controllers
{
public class HomeController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
public ActionResult Index()
{
var posts = db.Posts.Include(p => p.Author).OrderByDescending(p => p.Date).Take(3);
return View(posts.ToList());
}
public ActionResult Sidebar()
{
var PostsTop5 = db.Posts.Include(path => path.Author).OrderByDescending(p => p.Date).Take(3);
return View(PostsTop5.ToList());
}
}
}
View:
#{
ViewBag.Title = "Home Page";
}
#model List<ThelmaBlog.Models.Post>
#foreach (var post in Model)
{
<div class="row">
<div class="post col-md-6">
<h2 class="title">#post.Title</h2>
<div class="about">
Posted on <i>#post.Date</i>
#if (post.Author != null)
{
#:by <i>#(post.Author.FullName + " (" + post.Author.UserName + ")")</i>
}
</div>
<div>
#Html.Raw(HttpUtility.HtmlDecode(post.Body))
</div>
</div>
</div>
}
#section Sidebar{
}
Change your Sidebar action so it returns a partial view:
public ActionResult Sidebar()
{
var PostsTop5 = db.Posts.Include(path => path.Author).OrderByDescending(p => p.Date).Take(3);
return PartialView("_Posts", PostsTop5.ToList());
}
Then, create a partial view, called _Posts.cshtml, with the following code:
#model List<ThelmaBlog.Models.Post>
#foreach (var post in Model)
{
<div class="row">
<div class="post col-md-6">
<h2 class="title">#post.Title</h2>
<div class="about">
Posted on <i>#post.Date</i>
#if (post.Author != null)
{
#:by <i>#(post.Author.FullName + " (" + post.Author.UserName + ")")</i>
}
</div>
<div>
#Html.Raw(HttpUtility.HtmlDecode(post.Body))
</div>
</div>
</div>
}
And, finally, change your Index view to this:
#model List<ThelmaBlog.Models.Post>
#{
ViewBag.Title = "Home Page";
}
#Html.Partial("_Posts", Model)
#section Sidebar{
#Html.Action("Sidebar", "Home")
}
By the way, neither of your actions return what you have described in your post. They both return exactly the same thing, which is the top 3 posts (not top 5).
add your sidebar content to new partialview and then render this partial view in index
#Html.Action("sidebar") // in your index page

Return Partial View Via Controller Method

I have a Search Partial View that I want to return but I want to return it by running it through an exisiting Partial View Result in the Controller instead of loading the view directly.
So, in the controller I have:
public ActionResult Index()
{
return View();
}
public PartialViewResult _GetSearch(List<Search> model)
{
return PartialView("_Search", model);
}
[ValidateAntiForgeryToken()]
public PartialViewResult _BeginSearch(string search)
{
var results = SearchModels(search).ToList();
return PartialView("_GetSearch", results);
}
And in the search view itself I have:
<div class="col-md-4">
<div id="modelSearch" class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-search"></i> Search by Model / Manufacturer</h3>
</div>
<div class="panel-body">
#using (Ajax.BeginForm("_BeginSearch", "Home", new AjaxOptions() { UpdateTargetId = "modelSearch" }))
{
#Html.AntiForgeryToken()
<div class="input-group">
#Html.TextBox("search", null, new {id = "name", #class = "form-control", placeholder = "Please enter a manufacturer or model"})
<span class="input-group-btn">
<button id="search" class="btn btn-default" type="submit"><i class="fa fa-search"></i></button>
</span>
</div>
if (Model != null)
{
<div class="searchResults fade">
#foreach (var s in Model)
{
<div class="result">
#switch (s.ResultType)
{
case "Man":
#s.Manufacturer
break;
case "Mod":
#s.Manufacturer #s.Model
<img src="~/Images/General/(#s.TierId).png" alt="Tier #s.TierId"/>
break;
}
</div>
}
</div>
}
}
</div>
</div>
</div>
When I try and run the code it tell me that it cannot find the _GetSearch view, which yes technically is right, but I'm not looking for a view I'm looking for a method in the controller.

Sending a phrase (variable) from searcher (from view) to controller, asp.net mvc

I'm trying to create searcher in asp.net. I'm so green about it. I'm trying to create in view and send to controller variable, which has text written in searcher. In that moment, I have smth like that -->
My question is, where and how create and send variable and give her data written in searcher?
Layout
form class="navbar-form navbar-left" role="search">
#using (Html.BeginForm("Index", "Searcher", FormMethod.Post, new { phrase = "abc" }))
{
<div class="form-group">
<input type="text" class="form-control" placeholder="Wpisz frazę...">
</div>
<button type="submit" class="btn btn-default">#Html.ActionLink("Szukaj", "Index", "Searcher")</button>
}
</form>
Controller
public class SearcherController : ApplicationController
{
[HttpGet]
public ActionResult Index(string message)
{
ViewBag.phrase = message;
getCurrentUser();
return View();
}
}
View
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<ul>
<li>#ViewBag.message</li>
</ul>
You're missing a key part of MVC -> the Model.
Let's create one first:
public class SearchModel
{
public string Criteria { get; set; }
}
Then let's update your "Layout" view (don't know why you had a form in a form?):
#model SearchModel
#using (Html.BeginForm("Index", "Searcher", FormMethod.Post, new { phrase = "abc" }))
{
<div class="form-group">
#Html.EditorFor(m => m.Criteria)
</div>
<button type="submit" class="btn btn-default">#Html.ActionLink("Szukaj", "Index", "Searcher")</button>
}
Then your action that serves that view:
[HttpGet]
public ActionResult Index()
{
return View(new SearchModel());
}
Then your post method would be:
[HttpPost]
public ActionResult Index(SearchModel model)
{
ViewBag.phrase = model.Criteria;
getCurrentUser();
return View();
}

Partial View to Add Data

So here, I need to add comment for video in one view.
I have the main view code like this that displaying video and comment for that video.
<!-- language: C# -->
#model AzureMediaPortal.ViewModels.ViewModelWatch
#{
ViewBag.Title = "Watch";
}
<div id="videoPlayer">
</div>
<h2>#Html.DisplayFor(model => model.media.Title)</h2>
<h3> By #Html.DisplayFor(model => model.media.UserId) at #Html.DisplayFor(model => model.media.UploadDate) </h3>
#Html.HiddenFor(model => model.media.Id)
#Html.HiddenFor(model => model.media.AssetId)
#Html.HiddenFor(model => model.media.FileUrl, new { id = "fileUrl" })
<div class="display-label" style="font-weight:bold">
#Html.DisplayNameFor(model => model.media.Description)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.media.Description)
</div>
<br />
<div class="display-label" style="font-weight:bold">
#Html.DisplayName("Category")
</div>
<div class="display-field">
#Html.DisplayFor(model => model.media.Category.CategoryName)
</div>
<h3>Comments</h3>
#foreach (var item in Model.comment)
{
<div class="display-label" style="font-weight:bold">
#item.UserId
</div>
<div class="display-field">
#item.Content
</div>
}
#Html.Partial("Post",new AzureMediaPortal.ViewModels.ViewModelWatch())
#section Scripts {
<script src="~/Scripts/playerframework.min.js"></script>
<script src="~/Scripts/media-player.js"></script>
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
mediaPlayer.initFunction("videoPlayer", $("#fileUrl").val());
</script>
}
and this the partial view
#model AzureMediaPortal.ViewModels.ViewModelWatch
#{
ViewBag.Title = "Post";
}
<h2>Add Comment</h2>
#Html.HiddenFor(model => model.cmnt.MediaElement.Id)
#using (Html.BeginForm("Post","Home",FormMethod.Post)) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Add Comment</legend>
<div class="editor-label" style="font-weight:bold">
#Context.User.Identity.Name
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.cmnt.Content)
#Html.ValidationMessageFor(model => model.cmnt.Content)
</div>
<p>
<input type="submit" value="Post" />
</p>
</fieldset>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
this is my ViewModel
public class ViewModelWatch
{
public MediaElement media { get; set; }
public List<Comment> comment { get; set; }
public Comment cmnt { get; set; }
}
and this is my controller
public ActionResult Watch(int id)
{
ViewModelWatch vm = new ViewModelWatch();
vm.media = _repository.GetMedia(id);
vm.comment = _repository.GetMediaComment(id);
return View(vm);
}
public ActionResult Post()
{
return View();
}
[HttpPost]
public ActionResult Post(Comment comment, int id)
{
if (ModelState.IsValid)
{
comment.UserId = User.Identity.Name;
comment.MediaElement.Id = id;
db.Comments.Add(comment);
db.SaveChanges();
return RedirectToAction("Watch");
}
return View();
}
I need to pass data from partial view and save it to database include the media.Id to know that comment inserted for the video.
Thanks so muchhh
putting scripts on a partial view is generally bad practice. Script gets inserted into the middle of the view. For saving information from a partial view I use ajax calls. To do that add a class to your post button
<input type="button" class="btnSubmit" value="Post" />
then in your script on the main page
$(document).on('click', '.btnSubmit', function(){
$.ajax({
url: '#Url.Action("Action", "Controller")',
cache: false,
async: true,
data: {
//put the data that you want to save from the partial here
id: $('#hiddenID').val(),
content: $('#Content').val()
},
success: function (_result) {
//can add something here like an alert, close a popup something along those lines
}
});
});
just make sure the inputs on your controller match exactly the names that you have defined here
[HttpPost]
public ActionResult Action(int id, string content){
//database call to save the fields
//see here for an example of returning json http://stackoverflow.com/questions/1482034/extjs-how-to-return-json-success-w-data-using-asp-net-mvc
return Json(json);
}
I would suggest using #Html.Action and get the create form from there. Also, once the comments are stored you can redirect to the parent action. That should automatically update the comments list.
But that would be a bad idea.
Rather you can put get your comments by calling action from ajax ($.ajax) and use pure.js to replace the older ones with the new comment list.

Categories

Resources