Orchard. How to render something before 'HeadScripts' shape? - c#

Sometimes javascript code needs some data from server (e.g. constants or configs shared between JS and C#). I don't want to pull this data via Ajax. I want to render this data into html page on server.
Let's say, I have a component which consits of C# server-side code and JS client-side code. Component defines some C# constants to be provided for a specific JS code. This definition can be done somehow in ResourceManifest. Defined C# constants should be rendered into html before JS script links. The first part of JS links is rendered in 'HeadScripts' shape.
The question is how to render something before 'HeadScripts' shape?
I tried to wrap 'HeadScripts' shape. But it didn't help.
Wrapper in IShapeTableProvider implementation:
builder.Describe("HeadScripts").Configure(desc => desc.Wrappers.Add("HeadScriptsWrapper"));
HeadScriptsWrapper.cshtml:
<script>
var ServerConstants = {
const1: 'value1',
const2: 'value2'
};
</script>
#Display(Model.Child)
The result is:
...
<script src="/.../jquery-1.11.1.js" type="text/javascript"></script>
<script src="/.../some.js" type="text/javascript"></script>
<script src="/.../onemore.js" type="text/javascript"></script>
...
<meta content="Orchard" name="generator" />
<meta content="utf-8" name="charset" />
...
<link href="/.../favicon.png" rel="shortcut icon" type="image/x-icon" />
<script>
var ServerConstants = {
const1: 'value1',
const2: 'value2'
};
</script>
As you can see code from wrapper is rendered after 'HeadScripts'.
Please help.

I've managed to render custom string before 'HeadScripts' shape.
public class BeforeHeadScriptsShapeProvider : IShapeTableProvider
{
private readonly Work<IOrchardServices> orchardServices;
public BeforeHeadScriptsShapeProvider(Work<IOrchardServices> orchardServices)
{
this.orchardServices = orchardServices;
}
public void Discover(ShapeTableBuilder builder)
{
builder.Describe("HeadScripts")
.OnCreated(created =>
{
orchardServices.Value.WorkContext.Layout.Head.Add(created.New.BeforeHeadScriptsShape());
});
}
[Shape]
public void BeforeHeadScriptsShape(HtmlHelper Html)
{
Html.ViewContext.Writer.WriteLine("<script type=\"text/javascript\"> alert('TEST');</script>");
}
}
I can't explain this code in details, but I've found that some shapes are rendered through TextWriter Output parameter. But Output always renders after 'HeadScripts'. 'HeadScripts' (which is a set of 'Script' shapes) uses writer from HtmlHelper Html parameter. So, using HtmlHelper Html allows you to render custom content before 'HeadScripts'.

Related

How to reference Google Map tag in a JS file

I'm working on ASP.Net MVC and we're using an external .JS file to place all javascript code.
I firstly placed the below Google Map code in the View and it is working nice displaying the map in the view page... but when I sent my code for code-review, code-review folks require me to reference it in the .JS file. I tried so many times to put it in a .JS file but I can't have it displayed in a view.
Seems like they want the google map initialization variable and the google map js script inside the js file airplanDetail.js and, only have the reference in the view page. They want clean code/view page
Can you please assist?
<div class="googleMapAPI">
#{
var googleAPIKey = ConfigurationSettings.AppSettings["CWU_GoogleAPI_Key"];
<script src="https://maps.googleapis.com/maps/api/js?key=#googleAPIKey&callback=initMap" type="text/javascript"></script>
}
So in the ASP.Net MVC view page, at the bottom, there's a the below code that refence to the JS file.
#section Scripts {
#Scripts.Render("~/Scripts/Views/Product/airplanDetail.js")
}
and inside the airplanDetails.js file there's a code looks like the below
$(function () {
Initialize();
});
function Initialize() {
google.maps.visualRefresh = true;
var propertyLatitude = document.getElementById("latitudId").value;
var propertyLongitude = document.getElementById("longitudId").value;
var propertyLocation = new google.maps.LatLng(propertyLatitude, propertyLongitude);
var mapOptions = {
zoom: 14,
center: propertyLocation,
mapTypeId: google.maps.MapTypeId.G_NORMAL_MAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var myLatlng = new google.maps.LatLng(propertyLatitude, propertyLongitude);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Location found'
});
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/green-dot.png')
}
Try putting the script tag in the section, ie:
<html>
<head>
#Scripts.Render("~/Scripts/Views/Product/airplanDetail.js")
</head>
<body>
</body>
</html>

How to add content to sections programmatically in MVC / ASP.NET?

In each of my views, I am constantly adding a style and script associated with the view. It is convention in the application we introduced, but we want to automatically apply this convention instead.
Currently our views look like this:
<p>This is the view!</p>
#section styles {
<link rel="stylesheet" href="~/Views/Home/Index.css" />
}
#section scripts {
<script src="~/Views/Home/Index.js"></script>
}
Is there a way to automate adding the styles and scripts? Perhaps in the base class of the controller, such as:
public class BaseController : Controller
{
string controller = RouteData.Values["controller"].ToString();
string action = RouteData.Values["action"].ToString();
string script = string.Format("<script src=\"~/Views/{0}/{1}.js\"></script>", controller, action);
string style = string.Format("<link rel=\"stylesheet\" href=\"~/Views/{0}/{1}.css\" />", controller, action);
// Todo: How to add script and style to sections programmatically???
}
You can use the controller/action name values in your views, and specifically, in your layout. Just edit your layout and in the head add:
<link rel="stylesheet" href="~/Views/#(ViewContext.RouteData.Values["controller"])/#(ViewContext.RouteData.Values["action"]).css" />
And before your closing body tag, add:
<script src="~/Views/#(ViewContext.RouteData.Values["controller"])/#(ViewContext.RouteData.Values["action"]).js"></script>

Getting full address of returned location from geo-autocomplete api

if you are not familiar with google's geo-autocomplete plugin let me just explain how mine works, i have a text-box, when you type a location inside the text-box the auto-complete plugin gives you a dropdown list of places with similar names. Upon selecting the place you want, the map is generated for you.
What i want is to get the full address of the returned location into a text-box.
During some research i did online i cam across the:
getPlace()
function and the property i want:
formatted_address
but my problem is this is my first time using google's 'geo-autocomplete' plugin so i have no idea how to use these functions correctly. Please help me if you have ever implemented something similar.
This is my code:
<!-- Google Maps API -->
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>
<!--
jquery.autocomplete.js requires a minor modification for geo_autocomplete to work
the following script includes the required mod
-->
<script type="text/javascript" src="geo-autocomplete/lib/jquery.autocomplete_geomod.js"></script>
<script type="text/javascript" src="geo-autocomplete/geo_autocomplete.js"></script>
<link rel="stylesheet" type="text/css" href="geo-autocomplete/lib/jquery.autocomplete.css" />
<!-- Google Maps API -->
<script type=text/javascript">
$(document).ready(function () {
$('#dialog-form').hide();
$('#btnCancel').css('cursor', 'pointer');
$('#btnPostAlert').css('cursor', 'pointer');
$('#btnCancel').click(function () {
$('#dialog-form').hide();
alert(place.name)
});
$('#btnPostAlert').click(function () {
$('#dialog-form').show();
});
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
$("#location").geo_autocomplete(new google.maps.Geocoder, {
mapkey: 'ABQIAAAAbnvDoAoYOSW2iqoXiGTpYBTIx7cuHpcaq3fYV4NM0BaZl8OxDxS9pQpgJkMv0RxjVl6cDGhDNERjaQ',
selectFirst: false,
minChars: 3,
cacheLength: 50,
width: 300,
scroll: true,
scrollHeight: 330,
details: $('#details'),
}).result(function (_event, _data) {
if (_data) map.fitBounds(_data.geometry.viewport);
)};
});
});
</script>
Can you please check it out.
I'm not sure what you mean by "geo-autocomplete plugin", but when you mean the places-autocomplete, you must observe the place_changed event of the autocomplete-instance (which fires when the user selects a place from the dropdown).
Inside the callback you may access the placesResult by using this.getPlace(), formatted_address is (when available) a property of the placeRsult, so you may retrieve it by using this.getPlace().formatted_address
Sample-code:
google.maps.event.addListener(autocomplete, 'place_changed', function() {
var address = this.getPlace().formatted_address||'';
alert(address);
});

MVC .Net 4 Razor Problems using <text> tag

Here is my code:
<text>
<script type="text/javascript">
#foreach (var script in Model.Content.StartupScripts)
{
#script
}
</script>
</text>
#script contains a javascript script, but this gets rendered by razor as:
<script type="text/javascript">
{
{
var instanceId = 'blah';
new RequestQueue(' blah
// etc
So...it looks like the tag is not applying to the #script variable because single quotes are being replaced with '. What am I doing wrong?
Thanks!
Since MVC is automatically encoding all output, you need to force it to display raw text. You can do that with #Html.Raw(script) HTML helper.

Setting default text in WYMEDITOR

I've got a question about using WYMEditor in ASP.NET MVC 3 with jQuery. I'd like to set default text in WYMEditor on my web page. If I'm doing in that way :
<script type="text/javascript">
jQuery(function() {
jQuery(".wymeditor").wymeditor( { html : '<strong>some text</strong>'});
});
There is no problem, and wymeditor shows well-formated text, but is I try it in that way :
<script type="text/javascript">
jQuery(function() {
jQuery(".wymeditor").wymeditor( { html : '#ViewBag.HtmlText'});
});
(HtmlText is variable where I keep : <strong>some text</strong>) the WymEditor shows me not formated text <strong>some text</strong>. I tried HtmlEncoding and etc, but it stil isn't working.
Try like this:
<script type="text/javascript">
jQuery(function() {
var html = #Html.Raw(Json.Encode(ViewBag.HtmlText));
jQuery('.wymeditor').wymeditor({ html: html });
});
</script>
And please get rid of this ViewBag as everytime I see it I get sick. Use view models and strongly typed views.

Categories

Resources