I am using ASP.NET MVC, I have finished my project and I copied the .sln solution files to the server.
When I run it on the server, everything ok, but there is showing exceptions for the Popup forms.
I have this controller
-- The Get method
public ActionResult Remove(int id)
{
Person Person_to_remove = new Person() { Person_Id = id };
return View(Person);
}
-- The Post method
[ActionName("Remove"), HttpPost]
public ActionResult Remove_post(int id)
{
DB.Remove(id);
return RedirectToAction("Index");
}
And these views:
Index View
<table>
<tr>
<th>Name</th>
<th>Remove?</th>
</tr>
#foreach (var row in Model)
{
<tr>
<td>#row.Name</td>
<td>
Remove
<script type="text/javascript">
function Open() {
window.open('#Url.Action("Remove", new { id = row.Id })', 'popup', 'width=450,height=250');
return false;
}
</script>
</td>
</tr>
}
</table>
Remove View (As a popup window)
#using (Html.BeginForm())
{
<main>
<div>
<h3>Confirm removing:</h3>
<h1>#Model.Name</h1>
<br />
<div class="row">
<div>
<button type="submit" onclick="updateParent();">Confirm</button>
<a onclick="window.close()">Cancel</a>
</div>
</div>
</div>
</main>
}
The Index view use a default "Layout" layout and the Remove view use a "Popup" layout on the shared folder
This is the updateParent() script running on the "Popup" layout
<script type="text/javascript">
function updateParent() {
window.opener.location.reload();
window.close();
}
</script>
On my computer the app works fine, but when running on the server the popup views won't post the form, they just close without updating the data.
But when using the same URL from the Popup window into a new tab, it works. but is not desired behaviour.
I don't know what is going on, i only changed the IP in the connection string.
The problem was that the form was closing before submitting. Thanks to derloopkat for the tip.
To solve this I change Razor #Html.BeginForm() to name the form "PopUp".
Html.BeginForm(null, null, FormMethod.Post, new { name = "PopUp", id = "PopUp" })
then modify the updateParent method, to submit the form.
<script type="text/javascript">
function updateParent() {
document.forms["PopUp"].submit(); <-- Added
window.opener.location.reload();
window.close();
}
</script>
Don't know if it's the best way, but it works.
Related
I'm using view components to render a list of strings in HTML. The component has a button that when clicked, should toggle which list of strings is shown. When the button is clicked, only the view component should be reloaded, not the entire page.
I have the component list showing properly but I'm not sure how to get the button hooked up so that it only refreshes the view component
In ~ViewComponents I have ShowWords:
public class ShowWords : ViewComponent
{
public IViewComponentResult Invoke(bool ShowAll)
{
if (ShowAll)
{
return View(new List<string> { "showing", "all", "of", "the", "strings" });
}
else
{
return View(new List<string> { "not", "showing", "all", "strings" });
}
}
}
In ~Pages/Shared/Components/ShowWords I have Default.cshtml:
#model List<string>
<table>
<thead>
<tr>
<th>STRINGS</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.Count(); i++)
{
<tr>
<td>#Model[i]</td>
</tr>
}
</tbody>
</table>
The view component is called with this:
<vc:show-words show-all="true" />
#*How do I get this button to refresh the view component?*#
<form method="post">
<input type="submit" value="Toggle"/>
</form>
I'm able to get the button working if I bind it to a property and then post it but that reloads the entire screen not just the view component. What's the best way get just the view componenet to refresh when the button's clicked? Any help is appreciated.
Try to use ajax to call action which returns a view component.Here is a demo:
View(change input's type to button,so that the form will not be submitted when clicking the button):
<div id="component">
<vc:show-words show-all="true" />
</div>
#*How do I get this button to refresh the view component?*#
<form method="post">
<input type="button" value="Toggle" onclick="Refresh()"/>
</form>
#section scripts
{
<script>
function Refresh() {
$.ajax({
type: "GET",
url: "RefreshViewComponent",
success: function (data) {
document.getElementById("component").innerHTML = data;
}
});
}
</script>
}
action:
public IActionResult RefreshViewComponent()
{
return ViewComponent("ShowWords", new { ShowAll = false });
}
result:
I am creating an ASP.NET Core 3 MVC application that has a Customers tab in addition to the Home tab. On the Customers tab there is an input box where the user adds a search criterion (number of days) and a Search button. When the button is clicked then a list of Customer Ids is shown underneath (using jQuery and a Partial View). When the user clicks on a customer Id then the customer information is shown in a different page. However when I click on the browser's back button or on the 'Customers' tab then the criterion added and the search results disappear.
I have tried using the ResponseCache attribute to retain the search results but I could not make it work. I have also tried using the Cache Tag Helper but again was not successful. Anyone can help?
CustomersController
public class CustomersController : Controller
{
private readonly DbContext _context;
public CustomersController(DbContext context)
{
_context= context;
}
public IActionResult Index()
{
return View();
}
public IActionResult DisplayCustomerIdList(string searchText)
{
List<CustomerDetailViewModel> customers = _context.GetAll().ToList();
CustomerIndexViewModel model = new CustomerIndexViewModel()
{
Customers = customers
};
return PartialView("_CustomerIdListView", model);
}
public IActionResult Detail(decimal? Id)
{
Customer customer = _context.GetCustomerById(Id);
CustomerDetailViewModel model = new CustomerDetailViewModel(customer);
return View(model);
}
}
Index.cshtml
#{
ViewData["Title"] = "Customers Page";
}
#section Scripts {
<script type="text/javascript" src="~/lib/jquery/dist/jquery.min.js"></script>
<script>
var url = '#Url.Action("DisplayCustomerIdList", "Customers")';
$('#search').click(function () {
var keyWord = $('#NumberOfDays').val();
$('#searchResults').load(url, { searchText: keyWord });
return false;
})
</script>
}
<body>
<div class="input-group mb-3 w-50">
<input type="text" class="form-control mr-2" placeholder="Number of days" autocomplete="off" id="NumberOfDays">
<button id="search" class="btn btn-outline-info mb-2">Search</button>
</div>
<div id="searchResults"></div>
</body>
_CustomerIdListView.cshtml
#model MyProject.Models.CustomerIndexViewModel
<div class="card border-info mb-3 shadow" style="width:220px; height: 625px; overflow-y: scroll;">
<div class="card-header">Customer Ids</div>
<div class="list-group">
#foreach (CustomerDetailViewModel customerdetails in Model.Customers)
{
<a asp-controller="Customers" asp-action="Detail" asp-route-id="#customerdetails.CustomerId" class="list-group-item list-group-item-action">
#customerdetails.CustomerId
</a>
}
</div>
</div>
Detail.cshtml
#model MyProject.Models.CustomerDetailViewModel
<h3>Customer Information</h3>
<ul>
<li>#Model.CustomerId</li>
<li>#Model.FullName</li>
</ul>
Do the search via a GET request (rather than post). That way, the actual URL the user is sent to includes the query.
<form action="/foo" method="get">
I have figured out why this was not working and thought to add it here in case someone else has the same issue.
It turns out that the jQuery .load() method creates a POST request when the input parameter is an object (and a GET request when it is a String). So, because the ResponseCache attribute does not work with POST requests, the caching was not working.
I am loading a big excel file to the database. I want my users to see that there is an activity going on. I started but didn't know how to proceed.
My ActionResult Index method has two parameters. How do I define this in my javascript.
On the click of the submit button I want the animated image to show and then stop when processing is complete
I understand I have to hide the div somehow. Not sure how to do this.
Please assist. Here is my code below.
#model SampleTemplate.Models.ResultViewModel
#{
ViewBag.Title = "Index";
}
<h2>File upload section</h2>
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="uploadSection">
<div id="divloading">
<p style="position:absolute; top:30%; left:45%;color: Red;">
Excel file in process, please wait...<img src="../../Images/animated.gif" />
</p>
</div>
<div>
<p class="headerSection">Select script</p>
<p>
<select name = "genericId">
<option value="12.1">12_1_flat_goods</option>
<option value="12.2">12_2_mats_bm</option>
</select>
</p>
</div>
<div id="spacebetween">
<p class="headerSection">Path to source file: </p>
<p class="spacebelow"><input type="file" name="file" value="" /> </p>
<p><button id="submi" name="Submit" onclick="JavascriptFunction();">Submit</button></p>
</div>
</div>
}
<script type="text/javascript" language="javascript">
function JavascriptFunction() {
var url = '#Url.Action("","Home")';
$("#divLoading").show();
}
</script>
...Here is my method
[HttpPost]
public ActionResult Index(HttpPostedFileBase file, ResultViewModel resModel)
{
//code to upload excel file goes here. No need to show this.
}
I have used Knockout.js for this before, and found it to be really clean and simple.
Check it out here: http://knockoutjs.com/
Your page would look something like this:
Knockout ViewModel javascript file -
function TestViewModel() {
var self = this;
self.itemsToDisplay = ko.observableArray([]);
//this property can be used to hold the bool for when you first hit the upload button
self.uploadStarted = ko.observable(false); // when page is loaded, this is false
//this is a property that will hold the bool value to show/hide the gif after the upload has started
self.uploadCompleted = ko.observable(false); // when page is loaded this is false
ko.applyBindings(self);
};
Then back in your View -
(Note: You will need to reference the knockout.js script in your View)
<div data-bind="visible: !uploadCompleted() && uploadStarted()">
// your gif image reference will go here
// it will only be displayed when uploadCompleted is false and uploadStarted is true
</div>
<button type="button" id="uploadButton" name="Submit">Upload</button>
<script type="text/javascript">
var viewModel = new TestViewModel();
// make an ajax call to your controller method to upload your content
// on success set your loaded property to true to hide your gif
$('#uploadButton').click(function() {
viewModel.uploadStarted(true);
$j.ajax({
type: "POST",
url: "../home/Index",
data: ko.toJSON({ file: file, resModel: model}),
contentType: "application/json",
success: function (data) {
// your controller will return your values in data
// update your viewModel properties
viewModel.itemsToDisplay(data);
viewModel.uploadCompleted(true);
viewModel.uploadStarted(false);
}
});
});
</script>
Hope that helps.
Best of luck!
I currently have a view page that lists users as a gallery with their image but i also want to create a view page that lists the users by name. I want to use one controller for both of them and i created a ListView page and in the orginial View page which shows users by image - I have a link to view the ListView page. I tried clicking on the link but the page is not showing up. Here is what i have:
Image view page
<h2>Users</h2>
<div>
Click Here for List view
</div>
<section id="Images">
<section id="users" data-bind="foreach: Users">
<div id="nameImage">
<figure id="content">
<img width="158" height="158" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
<figcaption>
...
</figcaption>
</figure>
<p data-bind="text:Name"></p>
</div>
</section>
</section>
#section scripts{
#Scripts.Render("~/bundles/user" + ViewBag.Layout.AppVersionForUrls)
<script type="text/javascript">
(function ($) {
$.views.User.GetUser('#url');
})(jQuery);
</script>
}
List view page
<div class="accordion-inner">
<div data-bind="foreach: Users">
<div>
<img width="158" height="158" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
<p data-bind="text:Name"></p>
</div>
</div>
#section scripts{
#Scripts.Render("~/bundles/user" + ViewBag.Layout.AppVersionForUrls)
<script type="text/javascript">
(function ($) {
$.views.User.GetUser('#url');
})(jQuery);
</script>
}
Controller
public ActionResult View(int id)
{
// get the menu from the cache, by Id
ViewBag.SideBarMenu = SideMenuManager.GetRootMenu(id);
ViewBag.UserApiURL = "/api/User/" + id.ToString();
return View();
}
public ActionResult ListView(int id)
{
// get the menu from the cache, by Id
ViewBag.SideBarMenu = SideMenuManager.GetRootMenu(id);
ViewBag.RosterApiURL = "/api/User/ListView" + id.ToString();
return View();
}
The concept in MVC is that you never link to views, you link to an action in a controller, that then decides (based on parameters passed) which view and with what model should be rendered. So, if your controller is called UsersController, the
Click Here for List view
line should be:
Click Here for List view
or even better
#Html.ActionLink("ListView")
Problem is : I do have Index.cshtml as
#{
ViewBag.Title = "Search";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script src="#Url.Content("../../Scripts/jquery.unobtrusive-ajax.min.js") type="text/javascript"></script>
<h2>Answer's are </h2>
<div id="result">
#Ajax.ActionLink("Search Wiki",
"WikiAns",
new AjaxOptions{
UpdateTargetId = "result",
InsertionMode=InsertionMode.Replace,
HttpMethod="GET",
LoadingElementId="progress"
})
</div>
<div id="progress" style="display: none">
<img src="#Url.Content("../../Content/Images/ajax-loader.gif")" alt="loader" />
</div>
Now i do have partial view model _WikiAns:
#model IEnumerable<Questions.Models.WikiAnsClass>
<h2>Our Links</h2>
<table>
#foreach (var item in Model) {
<tr>
<td>
#item.content
</td>
</tr>
}
</table>
Now using above i want is that...on clicking Search Wiki action link, id="result" get all partial view rendered in it. But its not happening. Instead of its going to a page "localhost:80/Search/WikiAns" and showing the result there. but i want to it to stay at localhost:80/Search and replace its "result" id. but its not working this way.
Here is my action called WikiAns
public ActionResult WikiAns()
{
//Code to follow...
var wikians = //code to follow
return PartialView("_wikiAns", wikians);
}
What's the problem ?
Also how can i implement this Ajax GIF loader...i mean showing it while action gets executed. ?
Please suggest
Thanks
#Pbirkoff may be right about this but you can go through my post of very easy to implement demo of your scenario and build it up from there.
http://mazharkaunain.blogspot.com/2011/05/aspnet-mvc-razor-render-partial-view.html
http://mazharkaunain.blogspot.com/2011/04/aspnet-mvc-render-partial-view-using.html
You need to include Microsoft Ajax scripts at your page or layout.