Working with mvc partial view and history.js - c#

I'm using history js, https://github.com/browserstate/history.js/ to and Mvc Partial view, here is my code
In Partial Home
<a id="CreateUser" class="btn btn-primary">Create User </a>
and in my #section scripts to push new url and load partial content in 'state change event'
$('#back').click(function (e) {
History.pushState({ state: 1 }, "Create User", "/System/User/Create/");
});
in contoller there is also logic to load partial view if its ajax call and full view if not, this is to protect from user if they press refresh when in ~/System/User/Create/.
any way my script onClick script in section doesnt work user in /System/User called from Partial View or Ajax, I can solve this by attaching OnClick Event inside outside #section scripts so it became like this:
<a id="CreateUser" class="btn btn-primary">Create User </a>
<script>
$('#back').click(function (e) {
History.pushState({ state: 1 }, "Create User", "/System/User/Create/");
});
</script>
#section scripts
{
<script>
$('#back').click(function (e) {
History.pushState({ state: 1 }, "Create User", "/System/User/Create/");
});
</script>
}
but this is redundant and pain to maintain I know this happend because #section doesnt work with Ajax/Partial, anyway is there's cleaner alternative other than this.

Nevermind findout that '.click' need to be rebind after loading ajax, but with .on('click' there is no need to rebind event handler, so I now just need script on click event in global js.

Related

c# razor, how to use html button to run a method?

I want to use the button to run a c# method how to do that? Now if i make a button with
<button type="button" onclick="#class.method()" >execute method</button>
it just executes that method on page load but doesnt do that on button click.
This can be done using standard form or ajax form.
Option 1 - Standard form:
add asp-page-handler attribute to the button and specify the relevant method name, and on the back end create the relevant method with OnPost prefix.
<form method="post">
<button type="button" asp-page-handler="RunMethod">execute method</button>
</form>
Backend method:
public IActionResult OnPostRunMethod()
{
//do whatever...
}
Option 2 - ajax form:
Use data-ajax-url="?handler=RunMethod" directly inside the form attributes or you can use a script to assign the relevant method handler to the form, with this approach you can use multiple buttons inside the same ajax form:
<form method="post" id="myForm"
data-ajax="true"
data-ajax-method="post"
data-ajax-loading="#loading"
data-ajax-failure="failed"
data-ajax-update="#updateMsg">
<button type="submit" id="RunMethod">execute method</button>
</form>
#section Scripts{
<partial name="_ValidationScriptsPartial" />
<script src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.min.js"></script>
<script>
failed = function (xhr) {
alert('Status: {xhr.status}, Status text: {xhr.statusText}');
}
$("#RunMethod").on("click", function () {
$("#myForm").attr("data-ajax-url", "?handler=RunMethod");
});
});
</script>
}
Backend method:
public IActionResult OnPostRunMethod()
{
//do whatever...
}
see samples here
You need to create a handler method in the Razor page and use asp-page-handler attribute. See here for more information.

JQuery dialog box from asp.net web project

So I am trying to implement a dialog box pop up when the user clicks on a menu button on my page for example About-Button which will display information regarding the web page. So, I have implemented a jquery function and a ascx page for the above.
$(document).ready(function() {
$('#aboutButton').click(function(event) {
alert( "Thanks for visiting!" );//testing
$(function () {
$("#aboutButtonDiv").load('aboutButton.ascx');
$("#aboutButtonDiv").dialog({
backdrop: 'static',
draggable: false,
position: {
my: "center top",
at: "center top+100",
of: window
},
dialogClass: "no-close",
resizable: false,
height: 'auto',
width: 500,
modal: true,
buttons: {
"OK": function () {
$(this).dialog("close");
}
}
})
})
})
$(".menu-close").hide();
});
My ascx code is a simple div tag
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="aboutButton.ascx.cs" Inherits="WebProj.aboutButton" %>
<!DOCTYPE html>
<html>
<body>
<div id="aboutButtonDiv" title="About">
<p>Hello this is my first dialog using JQuery</p>
</div>
</body>
When I am clicking the button the click event is firing(I can see the Thanks for visiting message) but the dialog which I want doesn't pop-up. Am I missing something in Jquery code. In my main web page I have the following button
<li class="menutab-list">
<a href="#" type="link" id="aboutButton" data-toggle="modal" data-target="#modalAbout">
<span class="listing-text">About</span>
</a>
</li>
Your code works fine when I tested it. So it probably has something to do with missing jQuery UI files or parts of it.
In order for the Dialog to work you need the jQuery UI library. And even if you have that it could be that it is missing the specific Dialog part.
Go to http://jqueryui.com/download/ and create your download by selecting the options that you need or download the full package. You can check the includes on the third line of jquery-ui.js which parts are included.
And there is a jquery css file as well, with some icon images in the download that are also needed for the dialog to work properly.

Controller returning PartialView overwriting entire View

I'm POSTing and trying to re-load a partial view with the new data using Ajax like this:
Index.cshtml
<div id="left-column">
#Html.Partial("~/Views/Project/_ProjectList.cshtml", Model.ProjectList)
</div>
~/Views/Project/_ProjectList.cshtml
#using (Ajax.BeginForm("Create", "Project", new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "left-column"
}))
{
<h3>Create a new project</h3>
<div class="form-group">
<label for="new-project-name">Name</label>
<input type="text" class="form-control" id="new-project-name" name="Name" placeholder="Example" />
</div>
<button type="submit" class="btn btn-primary">Create Project</button>
Cancel
}
Then my Controller returns the PartialView after some db work:
[HttpPost]
public PartialViewResult Create(Project newProject)
{
db.Projects.Add(newProject);
db.SaveChanges();
var projectList = db.ProjectLists.SingleOrDefault(pl => pl.Id == 1);
return PartialView("~/Views/Project/_ProjectList.cshtml", projectList);
}
I would expect the _ProjectList partial view to load into the #left-column element with the new projectList passed in by the Controller, but instead, the entire View is being overwritten, so the entire body of the new HTML source looks basically like this:
<body>
<!-- all the stuff from the _ProjectList partial -->
</body>
It's worth noting that after the partial view returns, the URL reads /Project/Create, which I wouldn't expect.
I've included jquery-validate and jquery-validate-unobtrusive, and the console isn't showing any errors, so that shouldn't be the problem.
Any idea what's going on?
When using Ajax.BeginForm helper method to do ajax form posting, you need to include the jquery.unobtrusive-ajax.js file as well. This file has the code to handle the submit button click event and send the form asynchronously rather than doing the normal form submit.
If you do not include this file, the form submit will be normal. My guess is that you missed to include this file and hence missing the ajaxified form submit experience.
So make sure to load this file after jQuery
#Scripts.Render("~/bundles/jquery")
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
Here is the link to nuget page if you want to add this file via nuget package manager.
Benjy got it in a comment above. It was a jQuery version issue. I'm running 3.1.0, and jquery.unobtrusive-ajax stopped working with jQuery version 1.9.

jQuery Click - Doesn't work when page 1st loaded, but works if page is reloaded

I have an issue with the jQuery click function. I am trying to integrate jQuery Mobile Autocomplete into an C# MVC application.
It the following code doesn't work when the page first loads. However, it works if I reload/refresh the page.
HTML:
<ul data-role="listview" class="selectitems" data-filter="true" data-inset="true" data-filter-reveal="true" data-filter-placeholder="Search Ingredients...">
#foreach (var i in Model.ingredientList){
<li data-id="#i.id" data-unit="#i.useUnit.symbol">#i.title</li>
}
</ul>
Script:
<script src="/Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.mobile-1.3.2.min.js" type="text/javascript"></script>
$(document).ready(function () {
$('.selectitems > li').on('click', function () {
$('input[data-type="search"]').val($(this).text());
$("ul:jqmData(role='listview')").children().addClass('ui-screen-hidden');
$('#hdnIngredientID').val($(this).data('id'));
$('#txtUseQtyDetails').val($(this).data('unit'));
$('#hdnIngredientTitle').val($(this).text());
$('#txtQty').focus();
});
$('.ui-input-clear').on('tap', function () {
$('#hdnIngredientID').val('');
$('#txtUseQtyDetails').val('');
});
});
Any assistance would be appreciated.
UPDATE:
jQuery-mobile autocomplete hides the list items until user input happens using CSS "display: none;". Would this prevent the click function from being assigned? If so, how do I work around this?
FURTHER UPDATE:
Found that the "live" function is depreciated. Changed it to "on" instead. Unfortunately this didn't fix the problem :-(
Could it be because the "li" items are hidden by CSS when the page is loaded?
I've deployed it here:
http://rar_mobile_dev.runarestaurant.com/Ingredient/Create?recipe_id=15240
(username: test, password: test)
You could try using on() in stead of click.
$(document).on('click', '.selectitems > li', function(){
$('input[data-type="search"]').val($(this).text());
$("ul:jqmData(role='listview')").children().addClass('ui-screen-hidden');
$('#hdnIngredientID').val($(this).data('id'));
$('#txtUseQtyDetails').val($(this).data('unit'));
$('#hdnIngredientTitle').val($(this).text());
$('#txtQty').focus();
});

JQuery AJAX Post Inside Partial View

In my C# MVC4 application, I have two main views: "Index" and "Index_Perm." The logged-in user's role is what determines which of these views is rendered. "Index" contains a view called "PMain" and Index_Perm" contains a view called "PMain_Lim." "PMain" and "PMain_Lim" contain another partial view called "Analysis." Inside of "Analysis", I have this script:
<script type="text/javascript" charset="utf-8">
$(document).ready(function () {
$('#SubmitAverage').click(function () {
var $form = $('#form1');
$.ajax({
type: "POST",
url: "Home/Average",
data: $form.serialize(),
success: function () {
alert("Edit successful");
},
error: function () {
alert('failure');
}
});
});
});
</script>
My issue is that, when "Index" is the main view being accessed this script runs correctly when the Submit button is clicked. When "Index_Perm" is the main view however, when the button is clicked, the AJAX post fails with the error: The resource you are looking for has been removed, had its name changed, or is temporarily unavailable. The directory or file specified does not exist on the Web server. After some investigation in Firebug, I see that it is trying to access: mylocalhost/Home/Index_Perm/Home/Average instead of: mylocalhost/Home/Average which is specified as the url to send the POST in my script.
Here is the applicable portion of code which is identical in "PMain" and "PMain_Lim" which contains the button that is tied to the script:
<div id="Analysis" title="Analysis">
#Html.Action("Analysis", "Home", Model)
</div>
</section>
<section>
<h3>
<button class="btn" id="SubmitAverage" value ="SubmitAverage" name="action:SubmitAverage" type="button">Submit Averages</button>
</h3>
</section>
<section>
<div id="OtherView" title="OtherView" class="OtherChanges">
#Html.Action("OtherView", "Home", (string)ViewBag.SearchKey)
</div>
</section>
Any ideas why its ignoring what I've specified as the URL to use in the JQuery AJAX POST and/or how to correct it?
Use the urlhelper in your ajax post
url: '#Url.Action("Average","Home")',

Categories

Resources