Multi-page app in Framework7 - jquery-mobile

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.

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

bundles based on areas in 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");

jQuery mobile finds elements from first page when on second page

I've got a two page jQuery mobile app, and within the init function, the following code..
Call to the init function
$(document).on('pageinit', function(){
MyPages.init();
});
init: function() {
$('td[id$="drops"]').each(function() {
console.log("Element: " + $(this).attr('id'));
}),
};
I have elements in page one that match the above, such as '#early_drops', '#late_drops', etc. These elements do not exist on page 2, but when page 2 loads, the elements are displayed in the console just like when page 1 is loaded. What am I missing here?
Thanks very much,
-Adam vonNieda
By default jQuery loads pages using AJAX into the existing page in order to allow the animated transitions. If you don't want this you just need to 'turn off' the AJAX loading.
See description here: http://view.jquerymobile.com/1.3.2/dist/demos/widgets/links/
Links that point to other domains or that have rel="external", data-ajax="false" or target attributes will not be loaded with AJAX. Instead, these links will cause a full page refresh with no animated transition. Both attributes (rel="external" and data-ajax="false") have the same effect, but a different semantic meaning: rel="external" should be used when linking to another site or domain, while data-ajax="false" is useful for simply opting a page within your domain from being loaded via AJAX.
You can also disable AJAX across the entire app by default using global configuration: http://api.jquerymobile.com/global-config/

jQuery Mobile Losing Style After Updating DOM

A question similar to this has been posted several time, but I cannot find a solution that works. Hopefully, someone can help!
I am using jQuery Mobile 1.1 and jQuery 1.7.2, so I'm on the most recent stable releases. I want to create a dynamic page header. Using this HTML code, it works fine:
<div data-role="page" id="levela">
<div data-role="header" id="hdr_levela">
<h1>Title</h1>
</div>
</div>
So I then go to dynamically create the title. I change the HTML to this:
<div data-role="page" id="levela">
<div data-role="header" id="hdr_levela">
</div>
</div>
And added the following jQuery code:
// Set the header
var dirHeader = $('#hdr_levela');
dirHeader.append('<h1>' + title+ '</h1>');
The title appears, but is not styled. I have found several posts about this. In the jQuery Mobile Documentation, it says:
"However, if you generate new markup client-side or load in content via Ajax and inject it into a page, you can trigger the create event to handle the auto-initialization for all the plugins contained within the new markup. This can be triggered on any element (even the page div itself), saving you the task of manually initializing each plugin (listview button, select, etc.).
For example, if a block of HTML markup (say a login form) was loaded in through Ajax, trigger the create event to automatically transform all the widgets it contains (inputs and buttons in this case) into the enhanced versions. The code for this scenario would be:
$( ...new markup that contains widgets... ).appendTo( ".ui-page" ).trigger( "create" );
So I tried several things. After the above code, I added the following:
dirHeader.trigger("create");
This had no effect. So I tried to put it on the actual append itself:
dirHeader.append('<h1>' + folderName + '</h1>').trigger("create");
This had no effect. I then tried the process on the parent element (in this case, the id of the parent div is "levela"). So I tried this:
$('#levela').trigger("create");
This also had no effect. At this point, I am completely lost. Every solution involves doing one of the things I have tried and is just not working. I must be missing something incredibly basic but I just can't seem to find it.
Thanks in advance for your help!
You can update the content by calling .page:
See this working Fiddle Example!
// Set the header
var title = 'super hyper BuBu',
$dirHeader = $('#hdr_levela');
$dirHeader.append('<h1>' + title+ '</h1>').page();
I just solved a similar problem -- it appears that jQM headers and footers do not have the "create" method, so as far as I can tell, the css classes and roles need to be added manually.
For reference, I posted an example fix on this (old) question: JQuery Mobile trigger('create') command not working

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