MVC partial views and Unobtrusive jQuery/Javascript - javascript

I'm struggling to work out how I should be authoring my partial views which use jQuery.
For example, in the partial view below, I am displaying a text box which is hooked up to the jquery autocomplete plugin.
Eventually I want the results to be shown with an "X" next to them which the user can then remove, but for the purpose of this example the selected text is simply appended to the sibling div.
Is my jQuery code OK sitting here in the partial view, or should I be putting it in an external file? If an external file is used, then another developer using the partial view will need to be aware that the external js file should be included - is that OK?
I suppose my question really is that, although I'm kind of OK with jQuery (finding elements in the DOM, calling actions asynchronously etc..), I need some sort of guidance on where to put all this code that will stop me getting in a mess.
Does any of what I have just typed make sense????
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<script language="javascript" type="text/javascript">
$(document).ready(function() {
$(".acEmployee").autocomplete({
source: ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby"],
select: function(event, ui) {
$(this).siblings().append(ui.item.value);
}
});
});
</script>
<div><div></div><input class="acEmployee" /></div>

If the JavaScript is "hookup" code then I don't mind it being in with the partial - as after all, everything it relates to is there.
If the JavaScript is "framework" code and can be reused all over the place, and isn't dependant on anything in the partial then I put it in its own file.
That's just what I do, but I'd be interested in hearing other peoples methods too.

If possible, keep all your js code in an external js files. That way you can put your jquery includes at the bottom of the page.
for .net mvc try something like:
<!--try fetching jquery from CDN, if CDN is down, fallback to local-->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined') {
document.write(unescape("%3Cscript src='<%:Url.Content("~/Scripts/jquery-1.5.1.min.js")%>' type='text/javascript'%3E%3C/script%3E"));
}
</script>
<script type="text/javascript" language="javascript">
var MVC_baseurl = "<%:Url.Content("~/") %>";
</script>
<script type="text/javascript" language="javascript" src="<%:Url.Content("~/Scripts/jquery-ui-1.8.10.custom.min.js")%>"></script>
<script type="text/javascript" language="javascript" src="<%:Url.Content("~/Scripts/plugins.js")%>"></script>
<asp:ContentPlaceHolder ID="BottomJavascript" runat="server">
</asp:ContentPlaceHolder>
You can then put your page-specific stuff in the content placeholders. , your master page specific plugins in plugins.js, and you can use
var path = MVC_baseurl + "Controller/Action"
and use that in your ajax calls etc...

Related

jQuery plugins conflict and script declaration order

I'm new to web development, and was having issues with two plug-ins. I already found a workaround to solve it, but I'm not convinced at all about what I did, so I ask you guys if you can enlighten me on what is this about.
The page in question uses SlimScroll and DataTables plugins. At first, I had an HTML file like this one.
<body>
<!-- STUFF -->
<!-- SCRIPTS -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="plugins/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="plugins/slimScroll/jquery.slimscroll.min.js" type="text/javascript"></script>
<script src="plugins/DataTables/datatables.min.js" type="text/javascript"></script>
<script src="assets/scripts/tablas.js" type="text/javascript"></script>
<script src="assets/scripts/general.js" type="text/javascript"></script>
At the bottom, general.js is used to handle click events and other stuff, and tablas.js has the code that picks up a file with data and displays it in DataTables. The relevant code from general.js:
$(document).ready(function() {
$('#contenedor-menu').slimScroll({
height: '100%'
});});
And the code for tablas.js:
$(document).ready(function() {
$('#tablita').DataTable( {
"ajax": 'data/COut2.txt',
} );});
With this structure, when I load the page, SlimScroll fails with the message in the console: "TypeError: $(...).slimScroll is not a function"
Then after touching around, I switched the order of the scripts in the HTML file. I put datatables first and then slimscroll.
<script src="plugins/DataTables/datatables.min.js" type="text/javascript"></script>
<script src="plugins/slimScroll/jquery.slimscroll.min.js" type="text/javascript"></script>
And now it works ok, with no errors.
Could somebody please explain to me what's going on?
Thanks in advance!
The use of multiple $(document).ready(function() { } is the main cause of this issue. There should be only one Document Ready event handler.
You may try using the pageLoad() function or onLoad() events
Not positive but it is usually best practice to put the scripts you absolutely need before everything else in the head. This is so that the content of the page does not finish loading until all the dependencies have been loaded first.
By reordering your scripts you may have a solution that will only work some of the time.
Put all the scripts you need to load in the head and your general.js script at the end of your body element.

JavaScript not being executed in a section under Razor

I've managed to get the following to execute properly, meaning that I've set the renering etc. correctly. I do get to see the alert window.
#{ Layout = "~/Views/Shared/_Default.cshtml"; }
<h1>Eye candies</h1>
#section Footie
{
<script type="text/javascript">
alert("Ola!");
</script>
}
However, when I change that to execute a different script, showing a cool globe with visitors, I see nothing, nada, ziltch! No error, no nothing. Just empty page.
When I paste the URL into a browser, I get a JS source code back, so I'm assuming that this part works. But I have no ideas left how to investigate it further.
#section Footie
{
<script src="#Url.Content("//ra.revolvermaps.com/0/0/5.js?i=0w5jyvctga6&m=0&s=180&c=ff0000&cr1=ffffff")"
async="async"
type="text/javascript"></script>
}
I've added a static HTML page and pasted in the script there. Works like a charm! So it's definitely related to script execution under a view in MVC (or possible Razor syntax).
Suggestions?
Take a look at the url you are passing to the Url.Content method
#Url.Content("//ra.revolvermaps.com/0/0/5.js?i=0w5jyvctga6&m=0&s=180
&c=ff0000&cr1=ffffff")
In the url, the & are already encoded to & Url.Content method is going to encode the & again and you will get the result as
"//ra.revolvermaps.com/0/0/5.js?i=0w5jyvctga6&amp;m=0&amp;s=180&amp;
c=ff0000&amp;cr1=ffffff"
Now you have &amp; :)
The solution is to either not use the Url.Content() method
<script type="text/javascript" src="//ra.revolvermaps.com/0/0/5.js?i=0w5jyvctga6&
m=0&s=180&c=ff0000&cr1=ffffff" async="async"></script>
or do not encode the url passing to Url.Content() method let the method take care of encoding it.
<script type="text/javascript" src="#Url.Content("//ra.revolvermaps.com/0/0/5.js
?i=0w5jyvctga6&m=0&s=180&c=ff0000&cr1=ffffff")" async="async"></script>

jQuery script only working if it's above a function

I am using Bootstrap as my template, and Laravel as my framework. As suggested within the examples, you should load your jQuery script at the bottom of the page - to speed up the loading.
Within my application, I have this function that checks if an alert exists in the session, and if so, show it:
$(document).ready(function() {
toastr.options = {
"closeButton": false
};
toastr. {
{
Session::get('flash_notification.level')
}
}('{{ Session::get('
flash_notification.message ') }}')
});
This is shown above where I load the jQuery script:
#if (Session::has('flash_notification.message'))
<script>
The above script is loaded here.
</script>
#endif
#yield('content')
</div>
<!-- Scripts -->
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
In order to get this working, I need to declare my jQuery file in the header of the template, but I know this isn't best practice. I initially thought that by using the $(document).ready() method, it would resolve this, but it doesn't.
Any help would be greatly appreciated.
It is best to put the script calls in the footer so they are loaded last. This means that any other JS you write will need to be below them. You could add your other JS to another file which is included after the jQuery load.
If you cannot, you could add it to the header and add the defer attribute to the script tag to defer it's loading.
Option 1 should be preferred though.

how to embed javascript in Asp.net MVC view

How can I insert javascript in asp.net MVC application(view)?
I am doing following things in my javascript:
1) Read values from DOM elements.
2) Send data to Controler action method from Jquery Ajax.
3) Validating my input.
4) Read/Write cookies
How can I insert javascript in View.
Should it be something like this?
<script src="../Scripts/Jquery-2.1.js" type="text/javascript"></script>
<script src="../Scripts/jquery.cookie.js" type="text/javascript"></script>
<script>
$(document).ready(function ()
{
$.cookie("pc", "Navada, US");
}
);
</script>
#{
ViewBag.Title = "ViewPage1";
}
<h2>ViewPage1</h2>
Thanks for your answer
Not sure if i understand your question right, but if so you may need to put your script tags into the head tag.
To be able to put your custom js things into head you could try looking at this example:
In your _Layout page add this between <head></head>:
#RenderSection("CustomScripts", required: false);
And on your page:
#section CustomScripts
{
<script src="#Url.Content("~/Scripts/foo.js")" type="text/javascript"></script>
}
EDIT: as #Liam correctly pointed out that the _Layout file could be in any other path, #StephenMuecke's clarification applied.

ASP.NET MVC jQuery autocomplete with url.action helper in a script included in a page

I have been building my first ASP.NET MVC web app. I have been using the jQuery autocomplete widget in a number of places like this:
<head>
$("#model").autocomplete({ source: '<%= Url.Action("Model", "AutoComplete") %>' });
</head>
The thing is I have this jQuery code in a number of different places through my web app. So i thought I would create a seperate javascript script (script.js) where I could put this code and then just include it in the master page. Then i can put all these repeated pieces of code in that script and just call them where I need too. So I did this. My code is shown below:
In the site.js script I put this function:
function doAutoComplete() {
$("#model").autocomplete({ source: '<%= Url.Action("Model", "AutoComplete") %>' });
}
On the page I have:
<head>
<script src="../../Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="../../Scripts/site.js" type="text/javascript"></script>
<script type="text/javascript">
doAutoComplete();
</script>
</head>
But when I do this I get an Invalid Argument exception and the autocomplete doesnt work. What am I doing wrong? Any ideas?Do i need to pass something to the doAutoComplete function?
The <%= will not be evaluated in your external javascript.
Solution: pass the URL as a parameter to your javascript function.
<script>
doAutoComplete('<%= Url.Action("Model", "AutoComplete") %>');
</script>
function doAutoComplete(url) {
$("#model").autocomplete({ source: url });
}
You need to put the function call in a script block, and make sure jquery is loaded before your site.js ...
<head>
<script src='path/to/jquery.js'></script>
<script src="../../Scripts/site.js" type="text/javascript"></script>
<script>
doAutoComplete();
</script>
</head>
EDIT:
Maybe the '<%= ... =%>' tag isn't being evaluated server-side, before the function gets sent to the browser? Here is an article on this: http://www.west-wind.com/weblog/posts/252178.aspx
Here is a quote from the post:
There's also a problem if you need
access to the [ASP.NET] variables in
.js files - you can't embed script
tags into a .js file so getting a
dynamic value into a static file is
problematic

Categories