I've been working on a MVC 4 web app. I'm injecting a partial view into my index view, but no Resources that have been rendered in my layout page are being used by my partial view. For example, I can not use any jquery functions on any element inside the partial. So is there anything that could be causing this issue?
I've actually done it 2 ways: through razor and through jquery. I want to use jquery, but it wont work with it after its been rendered.
<script>
$("#Display div").click(function () {
var id = $(this).first().find("input").attr("value");
$.ajax({
type: 'GET',
url: '#Url.Content("~/Home/GetActors")',
data: {id:id},
success: function (result)
{
$('#Display').html(result);
}
});
});
</script>
`#Ajax.ActionLink("Edit", "GetActors", new { id = actor.ActorId }, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "Display", InsertionMode = InsertionMode.Replace })`
public PartialViewResult GetActors(int id)
{
return PartialView("GetActors",Db.Actors.Find(id));
}
Layout View
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<link href="~/Content/bootstrap-rating.css" rel="stylesheet" />
</head>
<body style="background:url(http://res.cloudinary.com/arcangel210291/image/upload/v1416947586/1389017_do9nat.jpg) no-repeat fixed; background-size:cover;">
<nav class="navbar navbar-inverse" role="navigation" style="border-radius:0px;">
<div class="container">
<ul class="nav navbar-nav">
<li><a><span style="color:#B99A77" class="glyphicon glyphicon-facetime-video"></span></a></li>
<li><a>Movies</a></li>
<li><a>Actors</a></li>
</ul>
<form class="navbar-form navbar-left" role="search">
<div class="input-group">
<div class="input-group-btn">
<button type="button" class="btn dropdown-toggle btnMovies" data-toggle="dropdown">ALL<span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><a>Somthing</a></li>
</ul>
</div>
<input type="text" class="form-control" placeholder="Search" />
<span class="input-group-btn">
<button type="button" class="btn btnMovies"><span class="glyphicon glyphicon-search"></span></button>
</span>
</div>
</form>
</div>
</nav>
<div class="container glass" id="NavContainer">
#RenderBody()
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
#Scripts.Render("~/bundles/starrating");
#RenderSection("scripts", required: false)
</body>
</html>
Index
#model IEnumerable<S00133799_CA2.Models.MovieModels.Movie>
<nav class="navbar navbar-inverse container" id="userControls">
<ul class="nav nav-pills nav-justified">
<li role="presentation">#Ajax.ActionLink("Create New!", "","", new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "Display", InsertionMode = InsertionMode.Replace }, new { #class = "btn btn-default btnMovies" })</li>
</ul>
<ul class="nav nav-pills nav-justified">
<li role="presentation" ><p class="navbar-text"><span class="glyphicon glyphicon-list"></span> Sort By : </p></li>
<li role="presentation">#Ajax.ActionLink("Name △", "OrderBy", new { OrderType = "Name" }, new AjaxOptions() { HttpMethod = "POST", UpdateTargetId = "Display", InsertionMode = InsertionMode.Replace }, new { #class = "btn btn-default btnMovies" })</li>
<li role="presentation">#Ajax.ActionLink("Date △", "OrderBy", new { OrderType = "Date" }, new AjaxOptions() { HttpMethod="POST", UpdateTargetId="Display", InsertionMode= InsertionMode.Replace }, new { #class = "btn btn-default btnMovies" })</li>
<li role="presentation">#Ajax.ActionLink("Rating △", "OrderBy",new { OrderType = "Rating" }, new AjaxOptions() { HttpMethod="POST", UpdateTargetId="Display", InsertionMode = InsertionMode.Replace }, new { #class = "btn btn-default btnMovies" })</li>
<li role="presentation">#Ajax.ActionLink("All Movies", "OrderBy", new { OrderType = "ChangeToMovies" }, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "Display", InsertionMode = InsertionMode.Replace }, new { #class = "btn btn-default btnMovies" })</li>
<li role="presentation">#Ajax.ActionLink("All Actors", "OrderBy", new { OrderType = "ChangeToActors" }, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "Display", InsertionMode = InsertionMode.Replace }, new { #class = "btn btn-default btnMovies" })</li>
</ul>
</nav>
<div id="Display" class="row">
#foreach (var movie in Model)
{
<div class='col-xs-6 col-md-4'>
<div class='thumbnail' style="cursor:pointer">
<img src="#movie.MovieImage" class="img-responsive" style="height:310px; width:100%" alt='...'/>
<div class='caption text-center panel panel-warning' style='margin-bottom:3%;padding:0;'>
<h4 style='background: #B99A77;color: #ffffff;margin-top: 0;padding: 2%;border-radius: 2px;'>#Html.DisplayFor(modle=>movie.MovieName)</h4>
<h5><b class="text-center">#Html.DisplayFor(model=> movie.ReleaseDate)</b></h5>
<input type="hidden" value="#movie.MovieId" />
</div>
</div>
</div>
}
</div>
<nav class="navbar navbar-inverse container" id="footernav">
<ul class="pager">
#if((int)Session["PageNo"] != 0)
{<li class="disabled"><a>Previous</a></li>}
else{
<li> #Ajax.ActionLink("Previous", "Previous", "", new AjaxOptions { HttpMethod="GET", UpdateTargetId="Display", InsertionMode=InsertionMode.Replace })</li>
}
<li>#Ajax.ActionLink("Next", "Next", "", new AjaxOptions { HttpMethod="GET", UpdateTargetId="Display", InsertionMode=InsertionMode.Replace })</li>
</ul>
</nav>
#section scripts
{
<script>
$(document).ready(function(){
$("#Display div").on("click",function () {
var id = $(this).first().find("input").attr("value");
$.ajax({
type: 'GET',
url: '#Url.Content("~/Home/GetMovies")',
data: {id:id},
success: function (result)
{
$("#userControls").hide();
$("#footernav").hide();
$('#Display').html(result);
}
});
});
});
</script>
}
Seams that you have is because you html is rendered on the page dynamically using ajax request after your selectors are assigned, you have 2 options:
1- reload your js files or code again after injecting your partial view.
2- use on or live for older jquery versions on your selectors and events (I recommend this if possible).
SOLVED
I actually Did somthing realy stupid. I placed the scripts into the partial itself to load them again like Amr has said i had done this before but left out one script that threw the whole thing. Thanks for the help anyway guys. Much appreciated
Related
I am trying in ASP.NET MVC in navbar put dropdown menu with select language. When I click on first dropdown button all navbar button need to change language. I wrote Language Controller and it works but my problem is that I want to have in navbar only show pictures of country and I try everything and always I see and letters and pictures.
I want to have only pictures of flag, without ENG.
One example of code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Brig</title>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="~/Scripts/modernizr-2.6.2.js"></script>
</head>
<body>
<div class="main_manu">
<div class="title">
<h2>Brig</h2>
<br />
<div class="navbar navbar-inverse navbar-fixed" id="navbarMenu">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse" id="navbar-colapse">
<ul class="nav navbar-nav">
<li class="dropdown">
#Html.LabelFor(model => model.ChoseLanguage) <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li><a>#Html.ActionLink("ENG", "Change", "Language", new { LanguageAbbrevation = "en" }, null)</a><img class="demo cursor" src="~/pictures/flag/gb.jpg" style="width:25%"></li>
<li><a>#Html.ActionLink("SPA", "Change", "Language", new { LanguageAbbrevation = "spa" }, null)</a><img class="demo cursor" src="~/pictures/flag/spa.png" style="width:25%"></li>
</ul>
</li>
<li>#Html.ActionLink(Resources.Resource.Home, "Index", "Home", new { area = "" }, new { #class = "navbar-brand" })</li>
<li>#Html.ActionLink(Resources.Resource.Services, "Info", "Services", new { area = "" }, new { #class = "navbar-brand" })</li>
<li>#Html.ActionLink(Resources.Resource.Gallery, "Gallery", "Gallery", new { area = "" }, new { #class = "navbar-brand" })</li>
<li>#Html.ActionLink(Resources.Resource.Apartment, "Apartment", "Apartment", new { area = "" }, new { #class = "navbar-brand" })</li>
<li>#Html.ActionLink(Resources.Resource.Contact, "SendEmail", "Contact", new { area = "" }, new { #class = "navbar-brand" })</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="container body-content">
#RenderBody()
<hr />
<footer>
<p>© #DateTime.Now.Year - Brig</p>
</footer>
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>
I will appreciate your help. Thank you.
i'm trying to login through a model inc asp net MVC 5, however, i can't seem to get the data from the form using serialize, there are no errors, it just shows nothing inside data
#using (Html.BeginForm("Login", "Account", new { returnUrl = Request.QueryString["ReturnUrl"] }, FormMethod.Post, new { id = "formModal" }))
{
#Html.AntiForgeryToken();
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="container">
<div class="form-login">
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">Login</div>
</div>
<div class="panel-body">
<div class="form-group">
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fas fa-user"></i>
</div>
</div>
#Html.EditorFor(model => model.Username, new { htmlAttributes = new { #class = "form-control", placeholder = "Username", autofocus = true } })
#Html.ValidationMessageFor(model => model.Username, "", new { #class = "text-danger" })
</div>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<div class="input-group-text">
<i class="fas fa-lock"></i>
</div>
</div>
#Html.EditorFor(model => model.Password, new { htmlAttributes = new { #class = "form-control", placeholder = "Password" } })
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
<div class="form-group">
<button id="btnSubmit" type="submit" class="btn primary btn-lg">
Entrar
</button>
</div>
</div>
</div>
</div>
</div>
}
<script type="text/javascript">
$("#btnSubmit").click(function () {
debugger
var formData = $('#formModal').serialize();
$.ajax({
type: 'POST',
url: '/Account/Login',
data: formData,
async: true,
success: function (data) {
}
});
return false;
});
what am i doing wrong? i saw some videos and i did exactly the same... I can reach the controller but there is no data
this is the controller
public class AccountController : Controller
{
public ActionResult Index()
{
return PartialView("_PartialLogin");
}
[HttpPost]
public ActionResult Login(LoginViewModel model, string ReturnUrl)
{
var user = Authenticate(model);
var ticket = new FormsAuthenticationTicket(
1,
user.Id.ToString(),
DateTime.Now,
DateTime.Now.AddHours(5),
model.RememberMe,
user.Roles.Select(c => c.Nome).FirstOrDefault()
);
return Redirect(ReturnUrl);
}
}
and here is view model
public class LoginViewModel
{
[Required]
[StringLength(8)]
public string Username { get; set; }
[Required]
[DataType(DataType.Password)]
public string Password { get; set; }
public bool RememberMe { get; set; }
}
no matter what, i cannot seem to get data from form using jquery, it's always null when i use serialize
EDIT
I forgot to mention, this form is inside a partialview, in a modal
#model Logistica.ViewModels.LoginViewModel
#{
Layout = null;
}
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<link href="~/Content/login.css" rel="stylesheet" />
<link href="~/Content/fontawesome-all.css" />
<script src="~/scripts/jquery-3.3.1.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="~/Scripts/bootstrap.js"></script>
<script src="~/Scripts/fontawesome/all.js"></script>
<!-- Modal -->
<div class="modal fade" id="modalLogin" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
</div>
</div>
</div>
</div>
I can't believe i could be so stupid, I thought this would be one of the possible options for my problem, form inside a form...
I am calling the login modal from _Layout and it was inside a form... I can't believe i wasted a day for this. It's my first time going backwards on making a mvc 5 project cause our IIS server does not allow host for Asp .NET Core 2.2 yet and totally forgot about the form on layout.
<form class="form-inline my-2 my-lg-0">
#if (User.Identity.IsAuthenticated)
{
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
}
else
{
<ul class="navbar-nav mr-auto">
<li class="nav-item">
#Html.Action("Index", "Account")
<a class="nav-link" href="#" data-toggle="modal" data-target="#modalLogin">Log In</a>
</li>
</ul>
}
</form>
Change url from url: '/Login/Account' to url: '/Account/Login' because your controller is Account not Login. I tried reproduce in local and it worked
$("#btnSubmit").click(function () {
debugger
var formData = $('#formModal').serialize();
$.ajax({
type: 'POST',
url: '/Account/Login',
data: formData,
async: true,
success: function (data) {
}
});
return false;
});
the data you post needs to map to one object { model: {}, ReturnUrl: "" }, ReturnUrl can come from the query string, but your action and form models are different.
Your form model is model: {}, and your action model is { model: {}, ReturnUrl: "" }
your name attributes on your form inputs should be model.Username, model.Password, vs Username, Password
I want a fixed navigation bar in every page but this layout is changing the contents of other pages that are using this layout. Is it because of the scripts? Please try to explain from the basics. I have included the screenshot of the home page. The registration form is getting shrinked.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - MY BOOKS</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
#Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { #class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
#RenderBody()
<hr />
#*<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>*#
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts",false)
</body>
</html>
Homepage
#model LogReg.Models.Login
<!DOCTYPE html>
<html>
<head>
<title>MyBooks Login Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<link href="/RegisterTemplate/css/font-awesome.min.css" rel="stylesheet" type="text/css" media="all">
<link href="/RegisterTemplate/css/style.css" rel="stylesheet" type="text/css" media="all" />
<link href="//fonts.googleapis.com/css?family=Raleway:400,500,600,700,800,900" rel="stylesheet">
</head>
<body>
<div class="signupform">
<h1>MyBooks Login Form</h1>
<div class="container">
<div class="agile_info">
<div class="w3l_form">
<div class="left_grid_info">
<h3>Welcome to MyBooks!</h3>
<h4>A place of Story makers, Dragon-tamers, Dream Catchers, Fact Finders and definitely a safer place.</h4>
<p>Books are the quietest and most constant of friends; they are the most accessible and wisest of counselors, and the most patient of teachers. </p>
</div>
</div>
<div class="w3_info">
<h2>Login to an Existing Account</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<form action="#" method="post">
<div class="input-group">
<span><i class="fa fa-user" aria-hidden="true"></i></span>
#Html.EditorFor(model => model.Email_ID, new
{
htmlAttributes = new
{
#class = "form-control",
#placeholder = "Enter Email Address",
required = "Required",
pattern = "[a-z0-9._%+-]+#[a-z0-9.-]+\\.[a-z]{2,3}$",
title = "example#email.com"
}
})
#Html.ValidationMessageFor(model => model.Email_ID, "", new { #class = "text-danger" })
</div>
<div class="input-group">
<span><i class="fa fa-user" aria-hidden="true" ></i></span>
#Html.EditorFor(model => model.Password, new
{
htmlAttributes = new
{
#class = "form-control",
#placeholder = "Enter Password",
required = "Required",
oninvalid = "this.setCustomValidity('Password cannot be empty')",
oninput = "setCustomValidity('')"
}
})
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
<div class="form-group">
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.Remember_Me)
#Html.ValidationMessageFor(model => model.Remember_Me, "Remember Me", new { #class = "text-danger" })
</div>
</div>
</div>
<button class="btn btn-danger btn-block" type="submit">Login</button>
</form>
}
</div>
<div class="clear"></div>
</div>
</div>
<div class="footer">
<p>© MyBooks Login form 2018. All Rights Reserved | Design by Aniket Prashar</p>
</div>
</div>
</body>
</html>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
I urge you to read an MVC tutorial or something similar as you do not yet understand the basic layout in ASP.NET MVC.
Assuming this is your layout, every page indicated to use this will have this layout and display the page content on the #RenderBody() meaning you should not reload scripts in your page view.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - MY BOOKS</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
#Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { #class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("About", "About", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</div>
</div>
</div>
<div class="container body-content">
#RenderBody()
<hr />
#*<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>*#
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts",false)
</body>
</html>
Controller:
[HttpGet]
public ActionResult Homepage()
{
return View(new LogReg.Models.Login());
}
Homepage View:
#{
ViewBag.Title= "MyBooks Login Page";
}
<link href="/RegisterTemplate/css/font-awesome.min.css" rel="stylesheet" type="text/css" media="all">
<link href="/RegisterTemplate/css/style.css" rel="stylesheet" type="text/css" media="all" />
<link href="//fonts.googleapis.com/css?family=Raleway:400,500,600,700,800,900" rel="stylesheet">
<div class="signupform">
<h1>MyBooks Login Form</h1>
<div class="container">
<div class="agile_info">
<div class="w3l_form">
<div class="left_grid_info">
<h3>Welcome to MyBooks!</h3>
<h4>A place of Story makers, Dragon-tamers, Dream Catchers, Fact Finders and definitely a safer place.</h4>
<p>Books are the quietest and most constant of friends; they are the most accessible and wisest of counselors, and the most patient of teachers. </p>
</div>
</div>
<div class="w3_info">
<h2>Login to an Existing Account</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<form action="#" method="post">
<div class="input-group">
<span><i class="fa fa-user" aria-hidden="true"></i></span>
#Html.EditorFor(model => model.Email_ID, new
{
htmlAttributes = new
{
#class = "form-control",
#placeholder = "Enter Email Address",
required = "Required",
pattern = "[a-z0-9._%+-]+#[a-z0-9.-]+\\.[a-z]{2,3}$",
title = "example#email.com"
}
})
#Html.ValidationMessageFor(model => model.Email_ID, "", new { #class = "text-danger" })
</div>
<div class="input-group">
<span><i class="fa fa-user" aria-hidden="true" ></i></span>
#Html.EditorFor(model => model.Password, new
{
htmlAttributes = new
{
#class = "form-control",
#placeholder = "Enter Password",
required = "Required",
oninvalid = "this.setCustomValidity('Password cannot be empty')",
oninput = "setCustomValidity('')"
}
})
#Html.ValidationMessageFor(model => model.Password, "", new { #class = "text-danger" })
</div>
<div class="form-group">
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.Remember_Me)
#Html.ValidationMessageFor(model => model.Remember_Me, "Remember Me", new { #class = "text-danger" })
</div>
</div>
</div>
<button class="btn btn-danger btn-block" type="submit">Login</button>
</form>
}
</div>
<div class="clear"></div>
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
#section Scripts will appear in the position of #RenderSection("scripts", required: false) inside your layout view meaning it will not be rendered after the </div> tag.
I'm having troubles adding google reCAPTCHA to my page.
in the Layout I have added the Google Recaptcha js
_layout
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
<script src='https://www.google.com/recaptcha/api.js'></script>
<script type="text/javascript">
<script type="text/javascript">
$(document).ready(function () {
$('#subject').on("change", function (e) {
e.preventDefault();
var selectedVal = $('#subject').val();
$.ajax({
// url: "/ContactUs/GetForm",
url: '#Url.Action("GetForm", "ContactUs")',
type: "POST",
data: { searchValue: selectedVal } ,
async: true,
success: function (data) {
$('#renderForms').empty();
$('#renderForms').append(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("An error has occured!!! " + xhr.status + " && " + xhr.responseText);
}
});
});
});
</script>
then in my index I select which form I want to show:
#Html.DropDownListFor(model => model.contactSelectListItems, new List<SelectListItem>
{
new SelectListItem() {Text = "option1", Value="option1"},
new SelectListItem() {Text = "option2", Value="option2"},
new SelectListItem() {Text = "option3", Value="option3"},
}, "--Choose--", new { id = "subject", #class= "dropdown-item" })
</div>
<div id="renderForms">
</div>
in both partial page there is a form where I do something similiar yet different viewmodels:
#using (Html.BeginForm("SendCustomerTeam", "ContactUs", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>CustomerTeamViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="container">
<div class="form-group form-group-sm col-sm-6">
<div class="row">
#Html.LabelFor(model => model.Phone, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-sm-9">
#Html.EditorFor(model => model.Phone, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Phone, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group form-group-sm col-sm-12">
<div class="row">
#Html.LabelFor(model => model.Inquiry, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-sm-12">
#Html.EditorFor(model => model.Inquiry, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Inquiry, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group form-group-sm col-sm-12">
<div class="row">
<div class="col-sm-12">
<div id="NotRobot">
<label>Are you Human?</label>
<div id='recaptcha' class="col-sm-12 g-recaptcha"
data-sitekey="#System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"]"
>
</div>
<div id="recaptchaMessage" data-verifyrecaptchatokenurl="#Url.Action("VerifyReCaptchaToken", "Home")" style="display:none;padding:10px;color:red;font-weight:bold;" class="error">You need to verify reCAPTCHA.</div>
</div>
</div>
</div>
</div>
<div class="form-group form-group-sm col-sm-6">
<div class="row">
<div class="col-sm-9">
<input id="Send" type="submit" value="Send" class="btn btn-default" />
</div>
</div>
</div> etc...
In my controller I handle it like this thou I would like to handle the reCAPTCHA as an ajax call I have yet to figure out how to do that.
public ActionResult Index()
{
ViewData["ReCaptchaKey"] = System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"];
//do something here
}
public static bool ReCaptchaPassed(string gRecaptchaResponse, string secret)
{
HttpClient httpClient = new HttpClient();
var res = httpClient.GetAsync($"https://www.google.com/recaptcha/api/siteverify?secret={secret}&response={gRecaptchaResponse}").Result;
if (res.StatusCode != HttpStatusCode.OK)
{
//logger.LogError("Error while sending request to ReCaptcha");
return false;
}
string JSONres = res.Content.ReadAsStringAsync().Result;
dynamic JSONdata = JObject.Parse(JSONres);
if (JSONdata.success != "true")
{
return false;
}
return true;
}
[HttpPost]
public ActionResult SendCustomerTeam(CustomerTeamViewModel model)
{
ContactViewModel contactModel = new ContactViewModel();
contactModel.CustomerTeamModel = model;
ViewData["ReCaptchaKey"] = System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"];
if (ModelState.IsValid)
{
if (!ReCaptchaPassed(
Request.Form["g-recaptcha-response"], // that's how you get it from the Request object
System.Configuration.ConfigurationManager.AppSettings["RecaptchaPrivateKey"]
))
{
ModelState.AddModelError(string.Empty, "You failed the CAPTCHA, stupid robot. Go play some 1x1 on SFs instead.");
return View(contactModel);
}
}
My problem is the reCAPTCHA never appears on my page.
Edit:
I've tried the following simplification to see if I could find the issue.
SimplePageViewModel
public class simplePageViewModel
{
public string Name { get; set; }
}
SimplePagePartialView
#model Contact_Portal.Models.simplePageViewModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>simplePageViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="container">
<div class="row">
<div class="form-group form-group-sm col-sm-6">
<div class="row">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-sm-9">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group form-group-sm col-sm-12">
<div class="row">
<div class="col-sm-12">
<div id="NotRobot">
<label>Are you Human?</label>
<div id='recaptcha' class="col-sm-12 g-recaptcha" style="padding:10px;"
data-sitekey="#System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"]">
</div>
<div id="recaptchaMessage" data-verifyrecaptchatokenurl="#Url.Action("VerifyReCaptchaToken", "Home")" style="display:none;padding:10px;color:red;font-weight:bold;" class="error">You need to verify reCAPTCHA.</div>
</div>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
in the controller I get the partial view shown through this line
return PartialView("View", contactModel.simplePageModel);
Still the same problem persist.
Could it be because I'm displaying my partial page containing the reCAPTCHA as part of an Jquery Ajax call ? like this:
$(document).ready(function () {
$('#subject').on("change", function (e) {
e.preventDefault();
var selectedVal = $('#subject').val();
$.ajax({
// url: "/ContactUs/GetForm",
url: '#Url.Action("GetForm", "ContactUs")',
type: "POST",
data: { searchValue: selectedVal } ,
async: true,
success: function (data) {
$('#renderForms').empty();
$('#renderForms').append(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("An error has occured!!! " + xhr.status + " && " + xhr.responseText);
}
});
});
I've now tried a entire new project where I've simplified it all the way down to one html file:
Index.cshtml
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - My ASP.NET Application</title>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<link href="~/Content/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="~/Scripts/modernizr-2.6.2.js"></script>
<script src='https://www.google.com/recaptcha/api.js'></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
#Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { #class = "navbar-brand" })
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
</ul>
</div>
</div>
</div>
<div class="container body-content">
<div id='recaptcha' class="col-sm-12 g-recaptcha" style="padding:10px;"
data-sitekey="#System.Configuration.ConfigurationManager.AppSettings["RecaptchaPublicKey"]"></div>
<hr />
<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
</body>
</html>
Still it is not visible it never appears. why is it not working ?
could it be that ASP.NET MVC is not supported by Recaptcha from google?
Your script src is wrong:
<script src='https://www.google.com/recaptcha/api.js async defer'></script>
to
<script src='https://www.google.com/recaptcha/api.js'></script>
Also could you check deveoper console, if there any error?
Well I found a solution I'm not happy with it but it works.
in my Layout file I've made a section like this:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script type="text/javascript">
function enableBtn() {
document.getElementById("subject").disabled = false;
}
$(document).ready(function () {
document.getElementById("subject").disabled = true;
});
</script>
Then in my view I created this
<div class="g-recaptcha" data-sitekey="*********PublicKEY*************" data-callback="enableBtn"></div>
And it seems to be working.
I wish I could make it work in the partial view because now I have to have it no matter what else will happen and not just on a submit.
I don't know if I can verify this one server side anymore as it is also outside my form. ?
Anyone with a better option would be welcomed.
EDIT:
I found a better solution for me. I changed my ajax call like this:
$('#subject').on("change", function (e) {
e.preventDefault();
var selectedVal = $('#subject').val();
$.ajax({
// url: "/ContactUs/GetForm",
url: '#Url.Action("GetForm", "ContactUs")',
type: "POST",
data: { searchValue: selectedVal } ,
async: true,
success: function (data) {
$('#renderForms').empty();
$('#renderForms').append(data);
if (!debug) {
document.getElementById("Send").disabled = true;
grecaptcha.render('Captcha', {
'sitekey': '**********PublicKey*********',
'callback': function() {
document.getElementById("Send").disabled = false;
},
'expired-callback': function() {
//document.getElementById("subject").selectedIndex = 0;
document.getElementById("Send").disabled = true;
//document.getElementById("renderForms").innerHTML = "";
}
});
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert("An error has occured!!! " + xhr.status + " && " + xhr.responseText);
}
});
});
Now it is working as I intended. At least in the user interface part.
I am trying to take textbox vale from one Page-1 to Page-2 i amusing below code ..but i am unable to do so.
Page-1.html
<div >
<div style="height: 400px">
<h2>Partial view-1</h2>
<p>The partial view of the content goes here...
<input type="text" name="reading" ng-model="reading" />
</div>
<div ui-sref="page2">Page 2</div>
</div>
Page-2.html
<div >
<div style="height: 400px">
<h2>Partial view-2</h2>
<p>The partial view of the content goes here...</p>
</div>
<div ui-sref="page3">Page 3</div>
<div ui-sref="autocomplete">AUTO COMPLETE</div>
</div>
Main.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="myApp">
<head>
<title></title>
<script src="../Scripts/angular.js"></script>
<script src="../Scripts/angular-ui-router.js"></script>
<script src="../Route/App.js"></script>
</head>
<body>
<h1>AngularJS Ui router</h1>
<h4>This is the Home Page</h4>
<div data-ui-view=""></div>
</body>
</html>
App.js
var myApp1 = angular.module("myApp", ['ui.router']);
myApp1.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when("", "/page1");
$stateProvider
.state("page1", {
url: "/page1",
templateUrl: "Page-1.html"
})
.state("page2", {
url: "/page2?param1",
templateUrl: "Page-2.html"
})
.state("autocomplete", {
url: "/autocomplete",
templateUrl: "autocomplete.html"
});
});
myApp1.controller('FirstCtrl', ['$scope', '$stateParams', '$state', function ($scope, $stateParams, $state) {
$state.go('page2', { 'param1': $state.params.param1 });
}]);
Please let me know what else should i do so that i can take value of texbox on page-1 to page-2 in angularjs
Following changes made to pass textbox value to another page
In Page-1.html
<div>
<div style="height: 400px">
<h2>Partial view-1</h2>
<p>
The partial view of the content goes here...
<input type="text" name="reading" ng-model="reading" />
</div>
<div ui-sref="page2({ myParam: reading })">Page 2</div>
</div>
In -Page-2.html
<div>
<div style="height: 400px">
<h2>Partial view-2</h2>
<p>The partial view of the content goes here...{{page1Value}}</p>
</div>
<div ui-sref="page3">Page 3</div>
<div ui-sref="autocomplete">AUTO COMPLETE</div>
</div>
App.js
var myApp1 = angular.module("myApp", ['ui.router']);
myApp1.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when("", "/page1");
$stateProvider
.state("page1", {
url: "/page1",
templateUrl: "Page-1.html"
})
.state("page2", {
url: "/page2?param1",
templateUrl: "Page-2.html",
params: { myParam: null },
controller: function ($scope, $stateParams) {
$scope.page1Value = $stateParams.myParam;
}
})
.state("autocomplete", {
url: "/autocomplete",
templateUrl: "autocomplete.html"
});});
myApp1.controller('FirstCtrl', ['$scope', '$stateParams', '$state', function ($scope, $stateParams, $state) {
}]);
If you want to use $state.go
Then make following modification in App.js and Page-1.html
App.js
var myApp1 = angular.module("myApp", ['ui.router']);
myApp1.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.when("", "/page1");
$stateProvider
.state("page1", {
url: "/page1",
templateUrl: "Page-1.html",
controller: 'FirstCtrl'
})
.state("page2", {
url: "/page2?param1",
templateUrl: "Page-2.html",
params: { myParam: null },
controller: function ($scope, $stateParams) {
$scope.page1Value = $stateParams.myParam;
}
})
.state("autocomplete", {
url: "/autocomplete",
templateUrl: "autocomplete.html"
});
});
myApp1.controller('FirstCtrl', ['$scope', '$stateParams', '$state', function ($scope, $stateParams, $state) {
$scope.redirectPage2 = function () {
var result = { myParam: $scope.reading };
$state.go('page2', result);
}
}]);
Page-1.html (For $state.go)
<div>
<div style="height: 400px">
<h2>Partial view-1</h2>
<p>
The partial view of the content goes here...
<input type="text" name="reading" ng-model="reading" />
</div>
<!--<div ui-sref="page2({ myParam: reading })">Page 2</div>-->
<div ng-click="redirectPage2()">Page 2</div>