mvc5 - ajax call replaces all page not just the div - asp.net-mvc-4

I've seen this problem severall times and tried everything suggest - never the less my div is not replaced - instead all page is "replaced"
I'm using MVC5 .
For project reasons i can't post here the code - but this new project pretty much sums my issue.
public ActionResult TestPartial()
{
return PartialView("_pView");
}
View:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="~/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="~/Scripts/MicrosoftMvcAjax.js" type="text/javascript"> </script>
<div col-md-12">
#using (Ajax.BeginForm("TestPartial", "Home", new AjaxOptions
{
HttpMethod = "GET",
UpdateTargetId = "reportView",
InsertionMode = InsertionMode.Replace
}, null, new { id = "form" }))
{
<input type="submit" value="submit" />
}
'm using the latest jquery version 2.1.4
Any thoughts on why this is not adding my partial view to the div?
The partial view is just span text for this example.

Related

How do I build an Asp.Net Core Razor page control that allows users to sign their names?

I am building an Asp.Net Core web application using Razor.
The intended audience for this app will be using it on tablets.
Part of the application consists of several pages/forms that will require user signatures.
We could retrieve an image of a user's signature and display that on demand in the web page.
Is it possible to be more interactive and allow users to "sign" the form/page within the browser? Are there any 3rd party control libraries that would support this functionality?
I pretty sure this can be done on native applications, but can I achieve this through Asp.Net Core?
I found signature_pad in github, and it works for me.
You can take a look at the screenshots of my test steps first, and I will add the test code at the bottom.
Test Code
1. signature.cshtml
#*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*#
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/signature_pad#2.3.2/dist/signature_pad.min.js"></script>
<form method="POST">
<p>
<canvas width="500" height="400" id="signature"
style="border:1px solid black"></canvas><br>
<button type="button" id="accept"
class="btn btn-primary">
Accept signature
</button>
<button type="submit" id="save"
class="btn btn-primary">
Save
</button><br>
<img width="500" height="400" id="savetarget"
style="border:1px solid black"><br>
<input id="SignatureDataUrl" type="text">
</p>
</form>
<script>
$(function () {
var canvas = document.querySelector('#signature');
var pad = new SignaturePad(canvas);
$('#accept').click(function () {
var data = pad.toDataURL();
$('#savetarget').attr('src', data);
$('#SignatureDataUrl').val(data);
pad.off();
});
$('#save').click(function () {
$.ajax({
url: "/ForTest/get_signature",
type: "POST",
data: { base64png:$('#SignatureDataUrl').val()},
success: function (data) {
console.log("success");
},
error: function (hata, ajaxoptions, throwerror) {
alert("failed");
}
});
});
});
</script>
2. C# code
[HttpPost]
public string get_signature(string base64png) {
var dataUri = base64png;//"data:image/png;base64,iVBORw0K...";
var encodedImage = dataUri.Split(',')[1];
var decodedImage = Convert.FromBase64String(encodedImage);
System.IO.File.WriteAllBytes("signature_pic/"+DateTime.Now.ToString("yyyyMMddHHmmss")+"signature.png", decodedImage);
return "ok";
}
Tips
If you want test my code, you need create signature_pic folder like me.

AngularJS route not rendering data

I am trying to implement a very simple angular route. One page only to begin with, will build on once working.
Basically, if I directly display the data in the index.html page, it produces the desired result (count of triples) like so:
Your data looks like this ...
Count of data "records" or "triples": 4585
so I know my queries, factories etc. in themselves are OK.
If I then attempt to implement via a view and route, no data is displayed. Here is my code.
index.html like so:
<!DOCTYPE html>
<head>
<title>Summarisation Min.</title>
<link href="css/main.css" rel="stylesheet"/>
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<script src="https://code.angularjs.org/1.2.28/angular-route.min.js"> </script>
</head>
<html>
<h1>Your data looks like this ...</h1>
<body>
<div ng-app="summaryApp">
<div ng-controller="topSummaryCtrl">
<div ng-view></div>
</div> <!-- end topSummaryCtrl controller -->
</div> <!-- end summarryApp module -->
<script src="js/app.js"></script>
<script src="js/controllers/TopSummaryController.js"></script>
</body>
</html>
controller js like so:
app.controller('topSummaryCtrl', function($scope, itemSummary){
itemSummary.success(function(response) {
$scope.itemSummaryResults = response.results.bindings;
});
});
app.factory('itemSummary', function($http){
/* 1 count of data triples */
var query = encodeURIComponent('SELECT (COUNT(*) AS ?no) { ?s ?p ?o }');
var endpoint = "http://localhost:3030/dataset/query";
return $http.get("http://localhost:3030/dataset/query? query="+query+"&output=json&stylesheet=")
});
app js like so:
var app = angular.module('summaryApp',['ngRoute']);
app.config(function($routeProvider){
//set up routes
$routeProvider
.when('/', {
templateUrl: 'partials/count.html',
controller: 'topSummaryCtrl'
})
});
/partials/count.html like so:
<table>
<tr ng-repeat="x in itemSummaryResults">
<td>Count of data "records" or "triples": {{ x.no.value }}</td>
</tr>
</table>
This returns no data. Once I move it out to a separate file to attempt implementation using routes, I can't get the data to display.
I am using Fuseki server on localhost3030 as the SPARQL endpoint and running index.html just by double-clicking on it. I don't know if this might be an issue but have seen conflicting advice online so posting here.
Have spent a couple of days working on this at this stage and still new to Angular so entirely possible it's a dumb error but what? All help gratefully received.
Thanks for reading Hilary.
OK. I have a workaround but to be honest it defeats the purpose of using AngularJS in the first place so I would still like alternative suggestions.
The workaround is to define all JS in a single included JS file or within tags in the HTML and use to implement routing of sorts. The code looks like this (if all in HTML file).
<html>
<head>
<title>HHLDSummaryApp </title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-route.min.js"></script>
<script>
var summaryApp = angular.module("summaryApp", ['ngRoute']);
summaryApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/viewCounts', {
templateUrl: 'count.htm',
controller: 'topSummaryCtrl'
}).
otherwise({
redirectTo: '/viewCounts'
});
}]);
/* inject $scope object and data retrieval factories */
summaryApp.controller('topSummaryCtrl', function($scope, itemSummary){
itemSummary.success(function(response) {
$scope.itemSummaryResults = response.results.bindings;
});
});
summaryApp.factory('itemSummary', function($http){
/* 1 count of data triples */
var query = encodeURIComponent('SELECT (COUNT(*) AS ?no) { ?s ?p ?o }');
var endpoint = "http://localhost:3030/dataset/query";
return $http.get("http://localhost:3030/dataset/query?query="+query+"&output=json&stylesheet=")
});
</script>
</head>
<body>
<h2>Your Data Looks Like This ... </h2>
<div ng-app="summaryApp">
<div ng-view></div>
<script type="text/ng-template" id="count.htm">
<table>
<tr ng-repeat="x in itemSummaryResults">
<td>Count of data "records" or "triples": {{ x.no.value }} </a></td>
</tr>
</table>
</script> <!-- end viewCounts -->
</div>
</body>
</html>
As I said, this workaround essentially defeats the purpose of using angular as we only use it for the ng-repeat functionality so please suggest alternative solution if you can. Thanks.

Model in Layout breaks other pages

I have a design flaw based on my lack of MVC4 experience.
The issue is that I have a model in my Layout...
#model BasicFinanceUI.Models.LoginModel
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link href="#Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
<link href="#Url.Content("~/Content/bootstrap.min.css")" rel="stylesheet"/>
<title>#ViewBag.Title</title>
</head>
The reason it's on my Layout, is that the Login button is on the layout screen, and it launches a modal popup, which has fiends that use the model.
So, at the bottom of the layout, I have:
<div class="modal fade" id="login" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3>Login</h3>
<div class="modal-body">
#using (Html.BeginForm("LoginUser", "User"))
{
<p>
#Html.LabelFor(x => x.Username)
#Html.TextBoxFor(x => x.Username)
</p>
<p>
#Html.LabelFor(x => x.Password)
#Html.PasswordFor(x => x.Password)
</p>
<p>
#Html.LabelFor(x => x.RememberMe)
#Html.CheckBoxFor(x => x.RememberMe)
</p>
<div class="modal-footer">
<input type="submit" value="Login" name="btn_login" class="btn btn-default" />
<a class="btn btn-primary" data-dismiss="modal">Cancel</a>
</div>
}
</div>
</div>
</div>
</div>
I also have a Login and Logout button on my /Home/Index, so the user see's two login buttons when on the default page. One on the main page, and one in the header/menu, which is shared.
I think having the model, and probably all the Login screen code, on the Layout page, might be the problem here. How should I be implementing this?
I need the Login button on the Index.cshtml page (Default), and the button in the Layout's menu at the top. And both use the model popup code shown above.
First build the view like you have it but instead of using helpers just build the html fields. Make sure you put an id or a class on the fields that we can use as a selector
<input type="text" class="txtUserName" /> etc
then make sure you have jquery referenced on the page and put this on the bottom of your screen
<script type="text/javascript">
$(document).ready(function(){
$('.btnSubmit').on('click', function(){
$.ajax({
url: "#(Url.Action("Action", "Controller")",
type: "POST",
contentType: "application/json",
data: { UserName: $('.txtUserName').val(), Password: $('.txtPassword').val() }
cache: false,
async: true,
success: function (result) {
alert('Login Successful!');
window.location = "#Url.Action("Index", "Controller")";
}
});
});
});
</script>
then on your controller you need to have a method set up to receive the ajax call
[HttpPost]
public ActionResult Login(string UserName, string Password){
//Check the user name and password against the database
//from here http://stackoverflow.com/questions/10608198/asp-net-mvc3-returning-success-jsonresult
var result=new { Success="True", Message="Success"};
return Json(result, JsonRequestBehavior.AllowGet);
}

How to Suppress Navigation on Home Page of my MVC4 Application?

I'm using the standard MVC4 template in VS 2012. It came with a _layout.cshtml file which is as follows:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title - iLoveSport</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#Styles.Render("~/Content/css")
#Styles.Render("~/Content/kendo")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/kendo")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-left">
<img src="~/Images/logo.png" alt="ILoveSport Logo" />
</div>
<div class="float-right">
<section id="login">
</section>
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("AFL", "Index", "AFL")</li>
<li>#Html.ActionLink("NRL", "Index", "NRL")</li>
<li>#Html.ActionLink("State of Origin", "Index", "State of Origin")</li>
<li>#Html.ActionLink("Cricket", "Index", "Cricket")</li>
<li>#Html.ActionLink("Golf", "Index", "Gof")</li>
<li>#Html.ActionLink("Motorsport", "index", "Motorsport")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
#RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
#RenderBody()
</section>
</div>
<footer>
<div class="content-wrapper">
<div class="float-left">
</div>
</div>
</footer>
#Scripts.Render("~/bundles/jquery")
#RenderSection("scripts", required: false)
</body>
</html>
The _viewstart.cshtml contains the following:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
What must be modified so that the navigation in my _layout.cshtml page is suppressed on the home page only? The home page needs to have a button that will then trigger the inner page which is currently my home page. Do I create a new layout file suppressing the menu and change viewstart to load it instead? Or, can this be done via another means?
Thanks for your help and guidance.
Update:
My Home Controller now is as follows:
[ChildActionOnly]
public ActionResult NavigationMenu()
{
string controller = ControllerContext.
ParentActionViewContext.RouteData.Values["controller"].ToString();
string action = ControllerContext.
ParentActionViewContext.RouteData.Values["action"].ToString();
if (controller == "Home" && action == "Index")
return Content("");
else
return PartialView("_Menu");
}
My _layout.cshtml is as follows:
<nav>
#Html.Action("NavigationMenu","Partial")
</nav>
However, I receive a debug error stating:
System.Web.HttpException: The controller for path '/' was not found or does not implement IController.
This error is thrown on the layout.cshtml file. How should this be remedied?
You can define your navigation menu as partial view. And render this partial view in your layout.
Inside action method of this partial view, you can check for the controller and action. If it is your home page you can return empty content. Otherwise, return your navigation menu.
Partial View
<nav>
<ul id="menu">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("AFL", "Index", "AFL")</li>
<li>#Html.ActionLink("NRL", "Index", "NRL")</li>
<li>#Html.ActionLink("State of Origin", "Index", "State of Origin")</li>
<li>#Html.ActionLink("Cricket", "Index", "Cricket")</li>
<li>#Html.ActionLink("Golf", "Index", "Gof")</li>
<li>#Html.ActionLink("Motorsport", "index", "Motorsport")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>
Action Method
[ChildActionOnly]
public ActionResult NavigationMenu()
{
string controller = ControllerContext.
ParentActionViewContext.
RouteData.Values["controller"].ToString();
string action = ControllerContext.
ParentActionViewContext.
RouteData.Values["action"].ToString();
if(controller == "Home" && action == "Index")
return Content("");
else
return PartialView("_NavigationPartial");
}
Rendering Partial View
#Html.Action("NavigationMenu", "Partial")
I have not tested the code, but most of it should be fine.

ASP.NET MVC4 and Knockout js

I am trying to use knockout js in my project so I tried the simple Hello World example but i couldnt get it to work. I created a new MVC4 project and just copy do a simple binding below is my code
<script src="~/Scripts/knockout-2.1.0.js" type="text/javascript"></script>
<script type="text/javascript">
// Here's my data model
var viewModel = function (first, last) {
this.firstName = ko.observable(first);
this.lastName = ko.observable(last);
//this.fullName = ko.computed(function () {
// Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName.
//return this.firstName() + " " + this.lastName();
//}, this);
};
$(document).ready(function() {
ko.applyBindings(new viewModel("Planet", "Earth")); // This makes Knockout get to work
});​
</script>
<div class="liveExample">
<p>First name: <input data-bind="value: firstName" /></p>
<p>Last name: <input data-bind="value: lastName" /></p>
#*<h2>Hello, <span data-bind='text: fullName'> </span>!</h2>*#
</div>
Basically it will just display the value of the model on a textbox.
I already referenced the knockout.js in my project but it does not work
I also added the knockout js in my BundleConfig.cs
bundles.Add(new ScriptBundle("~/bundles/knockout").Include("~/Scripts/knockout-2.1.0.js"));
I didnt work
If you are using MVC, use the scripts section to declare your JS. This will move the declarations to the bottom of the HTML page, letting the HTML render first. Here's my version of your code that worked first time out of the box:
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div class="liveExample">
<p>First name:
<input data-bind="value: firstName" /></p>
<p>Last name:
<input data-bind="value: lastName" /></p>
#*<h2>Hello, <span data-bind='text: fullName'> </span>!</h2>*#
</div>
#section scripts {
<script src="~/Scripts/knockout-2.2.1.js"></script>
<script type="text/javascript">
var viewModel = function (firstName, lastName) {
this.firstName = ko.observable(firstName);
this.lastName = ko.observable(lastName);
};
$(function () {
ko.applyBindings(new viewModel("Planet", "Earth"));
});
</script>
}
try putting knockout in the of your document. Without any error messages the only thing I can say is I ran into a similar problem and that was the fix for me.
My example was driving me crazy because it worked in fiddle but not in MVC, I mentioned it to a designer friend of mine and he said it made since to him, basically that knockout needed to be fully downloaded before the page began to render.
Hope this helps