Real time JavaScript to razor pages in MVC3 - asp.net-mvc

Imagine some javascript codes will be add razor pages.
<script type="text/javascript">
$(function () {
$('#photogallery a.lightbox').lightBox();
$('#photogallery').infiniteCarousel({ imagePath: '/Content/Images/Components/InfiniteCarousel/', autoStart: false });
$(".flows").collapsiblePanel();
$(".tab#Model.id").tabs();
});
</script>
This code need some html element defined css class by .tab and .flows.
There is no sense for flows but .tab#model.id build in run time -because it need model-.
I would like define an attribute for controller method and I would like to add automaticaly with code.
How
[JavaScript("menu.js")]
public ActionResult Menu(object param)
{
return PartialView(this.categoryService.GetAllCategories()[0]);
}
and razor view will have automaticaly produced code with
...
$(".tab#Model.id").tabs();
...
Is it phantasy or could be implemented in real life.
Thanks

Your Javascript block will work fine as-is.
Just put it in the view.

Related

Razor script Intellisense without the script tag

I load all my external script files async, when evrything is loaded, I have a callback that calls the remaining function.
<script>
function executeLayoutInitialization()
{
// Execute basic functions...
#RenderSection("deferredscripts", false)
}
</script>
On some of my views (.cshtml), I load deferred scripts like this:
#section deferredscripts
{
console.info("view loaded");
}
All of this works great, however, I lose JavaScript intellisense in doing so. To combat, I added script tag around the section. It looks like this:
<script>
#section deferredscripts
{
console.info("view loaded");
}
</script>
This now gives me intellisense. However, I don't like that every view now has an empty script tag created. Also, ReSharper 2017.3.2 thinks it's not JS, so it throws error like "; expected" on something like '#Url.Action("Load", "Action"){resharper_errorHere}'
So, my question is, is there a way I can have JS intellisense on my razor view without specifying the script tag? Or, is there a better way to solve this problem? Thank you.

Can't get this simple Google Autocomplete script to work (Rails)

I have this at the bottom of a form partial, which worked previously when I loaded it through application.html.erb, but have since decided to replace it in application.html.erb with Google Maps.
_new.html.erb (with the field appropriately id'd). straight up doesn't work, can't figure out why.
<script>
$(document).ready(function(){
var autocomplete = new google.maps.places.Autocomplete(document.getElementById("autocomplete"));
});
function initAutocomplete(){
}
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCFm7OzAKuPbEa48b_aZ4S6JqMGVUCwwFs&libraries=places&callback=initAutocomplete"
async defer></script>
Try moving
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCFm7OzAKuPbEa48b_aZ4S6JqMGVUCwwFs&libraries=places&callback=initAutocomplete"
async defer></script>
to the in application.html.erb head tag
Then put
initAutocomplete = ->
$(document).ready ->
autocomplete = new (google.maps.places.Autocomplete)(document.getElementById('autocomplete'))
return
Into a coffeescript for you front page, or use your existing script inline of the partial to test if you need to.

knockout + partials + mvc + correct way to bind

Dear fellow programmers
I got myself into a pickle. Ive been in to knockout for like 2 weeks now and im afraid i dont understand the basic idea of it. So be gentle with me.
Situation:
I got a master view layout page /Master to make it simple. Here i got 2 column layout.
On the left a listbox with patients, after clicking one, you will see prescriptions added to the listbox below it. pretty simple...
Dont mind the renderbody here, this is faulty. Just use this image to see 2 big parts. The red en and the yellow.
Now i got the Master working pretty well, when i click on a patient i want to load a specific partial view on the yellow part of the screen. The same with clicking a prescription , then i want to load the prescription partial on the yellow part.
I got these 2 editscreens working but without the master included. these pages look like this:
#model FysioNotes.WebMVC.Models.ViewModels.EditPatientViewModel
form + bindings here
#section scripts {
<script src="~/MyScripts/patientVm.js" />
<script>
$(function () {
ko.applyBindings(new editPatientVm(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model))));
});
</script>
}
You see that i use razor here to fill in the data in the editPatientVm. the js file looks like this :
var patientVm = function (data) ...
var editPatientVm = function (data) ...
var createPatientVm = function (data) ...
This is the same with the prescriptions .
Now when i try to load the prescription partial into the yellow part of the screen, i try to do it like this. And this is probably very faulty....
-- this is at the bottom of the master view --
<script type="text/javascript">
$(document).ready(function () {
$('#tablePrescriptions').on('click', 'tr', function (event) {
var selectedId = $(this).data("prescriptionid");
// this data gets filled without troubles
$(this).addClass('selectedrow').siblings().removeClass('selectedrow');
openDetail("prescription", selectedId);
});
and then this function
function openDetail(type, selectedId) {
if (debug)
alert(type + " : " + selectedId);
var url = baseurl + "/Prescription/Edit?prescriptionId=" + selectedId;
$("#mainContent").load(url);
//CHECK THIS
ko.cleanNode($("#mainContent")[0]);
$("#mainContent").load(url, function () {
//ko.applyBindings(new viewModel(), $("#mainContent")[0]);
ko.applyBindings(new editPrescriptionVm(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(new FysioNotes.WebMVC.Models.ViewModels.EditPrescriptionViewModel(12836)))), document.getElementById("mainContent"));
});
}
like you see , the fixed number 12836 is totally wrong to do it like this. But i wanted to just try if this would work and it did. But apparantly i cant send a js var to razor , because this is impossible.... so this let me to the idea that im doing something completely wrong
the master view has this at the bottom:
<script src="~/MyScripts/patientVm.js"></script>
<script src="~/MyScripts/prescriptionVm.js"></script>
<script>
$(function () {
ko.applyBindings(new masterVm(#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model))));
})
</script>
I think i need to put the viewmodels that i need in the partial into my viewmodel of the master maybe ? and then send it trough but this will mean that EVERY viewmodel needs to be on the master. This cant be good for initial loading ! And this seems wrong to me to do it like this , but ive been wrong before....
please help :(
#section scripts cannot work in partials views that are retrieved through ajax... you'll have to execute your code between those tags after the code that retrieves the view in the first place. #section scripts is kept into the request items and rendered when the page is rendered. But since this is ajax, the server has long passed the point where it would keep into account scripts defined between this section

Backbone Views defined in Head not working unless using Routes

I'm using the "rails-backbone" gem in my Rails 3.2 project. By this design my Backbone Views are loaded in the <head> tag. When using Routes everything works fine, but Views do not render if I try to use them directly without Routes. If I put the Views code in <body> everything works as expected.
Is there a way to make the Views work when defined in <head>?
Update:
in <body>:
<script type="text/javascript">
var lv = new ListView();
</script>
in javascript file included in <head>:
window.ListView = Backbone.View.extend({
el: $("#node"), // This does not work
initialize: function(){
_.bindAll(this, 'render');
this.el = $("#node"); // Works if I add this line
this.render();
},
render: function(){
$(this.el).append("<ul> <li>hello world</li> </ul>");
}
});
As I understand it #node does not exist yet, which is why it is not bound to el. I don't quite understands when happens here: var lv = new ListView(), I thought I was creating an instance from a Class (I guess I'm getting a clone of an Object?). Is there another way of making the code work by modifying the code in <body> instead of the included javascript?
Your problem is caused by using a jQuery selector as the value for el in the view.
Read this:
http://lostechies.com/derickbailey/2011/11/09/backbone-js-object-literals-views-events-jquery-and-el/
if you want something to work in the head, but after the DOM is ready, (And apparently since you're using jQuery) just set up your views in the DOMReady event via:
$(document).ready(function(){
...
//set up view here
...
});

Escaping JavaScript string literals in views

Is there a utility function for escaping JavaScript in ASP.NET MVC views? I often need to init a little snippet of JavaScript using some values from the view; for instance I may have something like:
<script type="text/javascript">
var page = new Page({ currentUser: "<%= Model.UserName %>" });
page.init();
</script>
I would expect something like:
<script type="text/javascript">
var page = new Page({ currentUser: "<%= Html.JavaScriptEscape(Model.UserName) %>" });
page.init();
</script>
I could, of course, write the function myself. But since there are already built-in utilities form HTML encoding, and since one of the selling points of ASP.NET MVC is that the <% %> is the default rendering mode, and since what I'm trying to achieve is quite common, it makes me wonder why I cannot find anything like that already built-in. Is there, for instance, an easy and elegant way to serialize an object to JSON in views?
Or am doing something against ASP.NET MVC principles? When I hit a problem like this, it usually makes it think that either I’m doing something wrong since I assume that the framework designers spent some time thinking about real world scenarios.
In .NET 4, The HttpUtility class has a variety of static encoding methods for various contexts, including a JavaScriptStringEncode method for this particular purpose.
It's often simpler to just use JSON deserialization, though.
In MVC 5 using Razor templates, the following is possible:
<script type="text/javascript">
var page = new Page({ currentUser: #Html.Raw(Json.Encode(Model.UserName)) });
page.init();
</script>
After some time working in ASP.NET MVC, I concluded that (most likely) there is no build-in helper for it. Of course, it's trivial to write your own. Here is it for the sake of completeness:
using System.Web.Mvc;
using System.Web.Script.Serialization;
namespace MyProject.Helpers
{
public static class JsonExtensions
{
public static string Json(this HtmlHelper html, object obj)
{
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
return jsonSerializer.Serialize(obj);
}
}
}
In a view, it can be used as follows:
<script type="text/javascript">
var page = new Page(<%= Html.Json(new { currentUser: Model.UserName } ) %>);
page.init();
</script>
In my case I needed a string not a json object and this is for Asp.Net Core:
#functions{
public Microsoft.AspNetCore.Html.IHtmlContent ToJS(string value)
{
return Html.Raw("'" + value.Replace("'", "\\'").Replace("\r", "\\r").Replace("\n", "\\n") + "'");
}
public Microsoft.AspNetCore.Html.IHtmlContent ToJS(int value)
{
return Html.Raw("" + value);
}
}
This will escape the ' and end of line characters. Also it leaves numbers (int) as a number. This could be overloaded to include float, decimal, etc. as needed.
So, I don't have to think about it or do anything different for each type:
var serverName = #ToJS(m.ServerName);
var appSiteUrl = #ToJS(m.SiteUrl);
var facebookId = #ToJS(m.FacebookAppId);

Resources