bundles based on areas in MVC - asp.net-mvc

I want to bundle one js file for each area and I am able to do it. But, the problem is to refer .
I dont want to refer all areas js in _Layout.cshtml because it is going to load all areas js files.
I can change js based on the area but our _layout will load only once from there it is only ajax calls.
Which is the right place to refer the js area wise in my case ?

this is what sections are for:
_Layout.cshtml
<head>
#RenderSection("head", false)
...
</head>
the false parameter means not required, that is what you want in this case.
then in your child view
#section head{
#Bundle.Scripts.Add("my scripts location");
}
note that the children get rendered first in MVC framework, so if there is javascript in this view it will start to be executed before the layout. So always use Document Load event or Window Ready , self executing code will fail if it is dependent on the scripts referenced in the Layout
or you can try something like this:
store the area you are in somewhere in your ViewModel , I'll use the ViewBag just for the example. Then create a separate bundle of scripts for each area whereever you register your bundles . Then you can do something like
#Bundle.Scripts.Add("/scripts/" + ViewBag.Area + "/myscripts");

Related

Can I make a partial template that have readonly fields when used by show and not when used by edit and create?

I've partial templates that are used by the show, edit and create form.
In the show-form I don't want them editable, it can be confusing for the user.
Is there a simple solution for this otherwise I need a different template for the show-form or... why use a template then.
I've tied this and created 2 scripts, one that disables and one that enables.
Script 1.
$(document).ready(function(){
$('.elements').attr('readonly',true);
$('.elements').prop('disabled',true);
});
Script 2.
$(document).ready(function(){
$('.elements').attr('readonly',false);
$('.elements').prop('disabled',false);
});
Then I stored those scripts in assets\javascript.
It worked good in show but both edit and create went read-only too.
It seems like everything that is put in this directory is automatically used in each form, because even though I removed the call from the forms, it was working.
Here I show where I originally added the script-call:
<asset:javascript src="myScript_1.js"/>
</body>
</html>
I was going to add it as a comment but then it started to get long and complicated to follow.
why store it in assets ?
simply add a function block to the templates that need it
_template1.gsp
<script>
$(document).ready(function(){
setReadOnly('${someDefinition}')
function setReadOnly(value) {
if (value==='READONLY') {
$('.elements').attr('readonly',true).prop('disabled',true);
}
}
})
</script>
If this function needs to be shared by a bunch of pages, you could add it to an assets / javascript file but rather than declare it in application.js call the js file <asset:javascript tags specificially on each page
and maybe a variable that you pass to template to say when it should be called
or put that above template1 as a master template and call in each of the other templates that needs the js file (So many options)
Now on the main controller doing action
def MyController {
def view() {
String mode='READONLY'
render view: 'index', model:[instance:params,mode:mode]
}
}
the in index.gsp
if js is there then it will pick up mode and set readonly for that controller action or pass that from one template to another, the controller does not have to define actual mode, the main master view page or index page could define mode too
Maybe you need to play/understand then implement you can't rush these things otherwise you will end up wasting time and rewriting
Just to ensure we are on the same page.
By default the application.js file in the javascript folder has a tree line enabled - this by default then reads in all js files. If you wish to manually call js in different places you will need to remove this line and declare each and every js file that you use like the other lines provided in that file.
So that is the price to pay (no more auto loading js files) until declared in application.js
But then most importantly as you have noticed these are global js functions and really nothing new should be going in there that hasn't got a function something() { } a function call.
They will then react when the actual function is called rather than how you had it which was open for call from any old page since it happened as documents opened regardless

How to keep related Partial page/HtmlHelpers, scripts and css together and not separate references

I have a form that has a button next to person textbox that brings up a person Bootstrap Modal Search Window.
the html I put in a partial page and reference it
#{await Html.RenderPartialAsync("_PersonControlPartialHtml","PersonControl1");}
#{await Html.RenderPartialAsync("_PersonControlPartialHtml","PersonControl2");}
which adds a textbox and button.
Then I add a bootstrap modal html to the page that only has to appear once per page
#{await Html.RenderPartialAsync("_PersonControlModal");}
Then the javascript event code and css for the above.
#section Header {
<script src="~/css/personcontrolscript.css"></script>
}
and
#section Scripts {
<script src="~/js/personcontrolscript.js"></script>
}
The html I could put in an htmlhelper but I still need to add 3 references to the page if I want to add it to a page.
Is there not an easier way?
There are ways to reduce this but those ways come with trade offs. So it really depends on which approach best fits your needs.
So for example you could eliminate adding the .css reference in the header section via two different approaches:
1) you could place those styles in a global.css file that is already loaded for ever page; or
2) you could use inline styles on you html and eliminate these css classes.
Both of these solutions of course have downsides. Approach one means that the size of the global.css styles will be larger and take a bit more time to load even if the first page used on the site doesn't need them. Approach 2 seems to fly in the face of conventional wisdom that you should almost never use inline styles and it will make the markup more verbose. But either solution would allow you to eliminate the need for including a seperate ~/css/personcontrolscript.css reference every time you have a person control on the page.
As for the need to include ~/js/personcontrolscript.js, that could be solved one of two ways:
1) include the javascript code in a global.js file that is loaded for every page; or
2) put that javascript code inline in the _PersonControlPartialHtml and add code to it to make sure that it only gets injected the first time the partial is used on the page.
As for the bootstrapModel, I'm a little less clear on what that code looks like so I can't say for sure but probably it could leverage an approach similar to one mentioned for css or js.
With regard to rendering your partials, I don't think there is any way to eliminate that given that it's the primary representation of the functionality you are adding to the page.

How to include one js script in all views except the landing page

I am converting css template into MVC application. Needless to say, I am just a beginner into webdesign. Template contains reference to one js script, which needs to be included on all pages except the landing page.
<script type="text/javascript" src="js/slider_func_innerpage.js"></script>
How to achieve it in MVC without creation of another master page? I tried to put this line in all views except of default view, but nothing happened. Ideally, I would like to handle this in my _Layout.cshtml file. Is it possible to set there some "if" condition, which would, if true, call partial view containing that single line I posted above? Or is there a more elegant way to load that js file into all views with the exception of the default one?
If you do not prefer to create another layout for landing page (Why not ? This seems to be the right way of doing it) , you might consider conditionally loading this js file in your layout.
So in the view for landing page, set a flag to the ViewBag dictionary
#{
ViewBag.IsLandingPage = true;
}
Now in the layout, check this flag and if it is not null and true, Exclude the inclusion of your js file
#{
if (ViewBag.IsLandingPage == null)
{
<script type="text/javascript" src="js/slider_func_innerpage.js"></script>
}
}

Multi-page app in Framework7

I've developed several multipage applications using jQuery Mobile (JQM) and am planning to use Framework7.
In JQM I create several HTML pages along with their respective JS files
login.html
login.js
home.html
home.js
payment.html
payment.js
All js files are linked in their respective html pages
<div data-role="page">
<script src="js/login.js"></script>
</div>
When a page is opened using $.mobile.changepage, page events (pageinit, pageshow etc) in the respective js get triggered. All control events are handled as $('#element').on('click', function(e){});
I'm, however, unable to implement this functionality in Framework7. Need guidance on this. I tried adding JS to HTML files but it did not get added.
First thing to notice,Framework7 needs initialization before running any script.So you need to add framework7 js first in html page.And for framework7 application the approach for pages is little different than jQM.
There are two types of pages you can create in F7.
1) you can create all pages inside single html file.
2) multiple html pages.
F7 has specific View definitions which are important while creating a html page.So main View is required in F7.And after initialization of f7 you need to initialize main-view as well.
To navigate between pages you need to use router api.For ie:
mainView.router.load(selector) // selector can be data-page/html file name
Mainview is object of View which needs to init after F7 init.
var myApp = new Framework7({
// ...
});
/* Initialize views */
var mainView = myApp.addView('.view-main', {
dynamicNavbar: true
})
var anotherView = myApp.addView('.another-view');
Download the F7 master from Git and check the example folder.It will give you good idea about all the view and pages.
Hope this helps
mainView.router.loadPage('ur_page.html');
Will solve your page navigation in your app/site.

ASP.NET MVC editor template javascript location

We have an editor template that contains approx 40 lines of jquery. I tried dropping this script into a <asp:Content> block to keep all of the javascript in one location within the page. However, I get the following error message content controls have to be top-level controls in a content page.
Is there any way to get this working so we don't have script dotted around our final output pages or could someone recommend the best practice for storing javascript used within ASP.NET MVC templates? At the moment I'm thinking of pulling the code into a separate file and referencing it within the master page but this means it gets pulled into every page which isn't really ideal.
Thanks in advance.
It would be easier for later maintenance, if you keep the javascript into a separate file and reference it where ever it is needed. Also, if you feel that placing all script into a single file will increase unnecessary loading of scripts, where not needed, then break the scripts into separate files based on functionality/modules in which it is useful etc. strategy and then reference them instead.
Also, it was said that always, keep/reference the scripts at the bottom of the page so that page loading will be faster.
as siva says, bottom of the page is the 'ideal'. however, as for seperate files. this is only going to be practical as long as you don't reference asp.net elements from the page - ie:
<asp:Content ContentPlaceHolderID="jsCode" ID="jsCode1" runat="server">
<script type="text/javascript">
$(document).ready(function() {
getPoundsData();
});
function getPoundsData() {
var id = $("#ID").val();
var URL = '<%=Url.Action("GetPounds", "FundShareholder")%>';
var params = { id: id };
if (id != null)
SendAjaxCache("#" + $("#ShareholderID option:selected").text() + " RSP#", URL, params, null, ListDataShareholderPounds);
}
function ListDataShareholderPounds(data) {
if (data.length != 0) {
$('#shareholderPounds').html("");
$('#shareholderPounds').show();
$('#shareholderPounds').html(data);
}
};
</script>
</asp:Content>
notice the:
var URL = '<%=Url.Action("GetPounds", "FundShareholder")%>';
part in the js. what 'we' do is to add a content section to the master page at the very bottom to hold our js stuff. however, this only works inside the ViewPage (aspx) object. the ascx pages are 'ignorant' of any master page content sections.
We are currently working on systemizing the process whereby we save 'partial' js files with asp.net references inside them and then inject them into the page-flow via a filterattribute. we're at an early stage with this but the nice thing about this approach is that the partial js is treated as a file and is therefore cached for future visits to that page.
anyway, that's our current approach, would be interested to discover if peeps are using any similar mechanisms to inject js that contains asp.net object references.
cheers...
[edit] - here's a heads up on the approach i'm talking about (this wasn't our original inspiration, but is quite similar, tho is webforms, rather than mvc) - http://www.west-wind.com/WebLog/posts/252178.aspx or this one which IS mvc: http://poundingcode.blogspot.com/2009/12/injecting-javasript-into-aspnetmvc-with.html.
Finally found the article that inspired our 'search' in this: ASP.NET MVC routing and paths is js files plus http://codepaste.net/p2s3po

Resources