Changing Element Class With Javascript Fails When Using Turbolinks - javascript

I have the following code attempting to toggle a class on the body element:
$(document).on("turbolinks:load", function() {
// Minimalize menu
$(document).on('click', '.navbar-minimalize', function (event) {
$('body').toggleClass('mini-navbar');
})
...
It works on a fresh page load every time, but fails EVERY OTHER link navigation thereafter. Fresh page load (class toggle works), 1st link click (broken), 2nd link click (works), etc.
Note that I was using jQuery originally when I spotted the bug, then moved to vanilla JS to see if it was a jQuery issue. Needless to say, it wasn't.
I removed a bunch of other dependencies one by one and the only thing that resolves the issue is by removing Turbolinks and replacing turbolinks:load event with jQuery's document.ready.
When analyzing with Chrome Dev tools, it shows that the classlist is trying to be manipulated (highlights it yellow temporarily), but ultimately nothing changes.
I know this is very strange and probably unique to my codebase. I just can't figure the damn bug out.
-- UPDATE 1 --
Here is the relevant HTML markup. Note the 'a' tag class of 'navbar-minimalize' is the trigger. The body tag is the element which the js is trying to toggle the class.
<!-- topnavbar.html.erb -->
<div class="row border-bottom" id="vue-autocomplete-app">
<nav class="white-bg navbar navbar-static-top" role="navigation" style="margin-bottom: 0">
<div class="navbar-header">
<a class="navbar-minimalize minimalize-styl-2 btn btn-primary" href="#"><i class="fa fa-bars"></i> </a>
<form role="search" class="form form-inline navbar-form-custom" method="" action="">
<global-search></global-search>
</form>
</div>
</nav>
</div>
Then the rails templating code that loads the above template:
<!-- application.html.erb -->
<body class="fixed-sidebar">
<!-- Wrapper-->
<div id="wrapper">
<!-- Navigation -->
<%= render 'layouts/navigation' %>
<!-- Page wraper -->
<div id="page-wrapper" class="gray-bg">
<!-- Page wrapper -->
<%= render 'layouts/topnavbar' %>
...
-- UPDATE 2 --
If I move the toggle code outside of the turbolinks:load into a document ready, everything seems to work fine. With that said, it seems to be some sort of quirky behavior with turbolinks.
--
Any help? What's the issue here?

Related

how can I call a PHP page from a bootstrap modal window?

I have a doubt that I can't solve. From a PHP page I call a typical modal window in which I always had a button that updated or added or deleted records, but now I need to place 2 buttons and that the new button allows me to call a PHP page in which I have a code that downloads data and passes it to an Excel file. I don't know how to make the call to that page from the button in the modal window.
<div class="mb-3 row">
<div class="col-md-6 text-center">
<button type="submit" class="btn btn-primary">update</button>
</div>
<div class="col-md-6 text-center">
<button type="button" class="btn btn-success">download detail</button>
</div>
</div>
I would appreciate any help. Thanks
In Bootstrap, you can use same button classes for <a> tag as well:
The .btn classes are designed to be used with the <button> element.
However, you can also use these classes on <a> or <input> elements
(though some browsers may apply a slightly different rendering).
So your button should be done like this:
download detail

How to Execute Javascript in an AngularRoute View

I am writing a phonegap application using Angular's ngRoute as an MVC. This all works beautifully, except for my top bar which includes the trigger button for the slide out menu. as it sits now, the top bar has the same title for every page, so to fix this I moved the top bar inside of the route view, which now stops my slide out menu from working.
How can i get the javascript trigger to actually run properly inside a route view (i understand this has to do with the page, and all of its JS, rendering before the route view is actually loaded) and I also would LIKE to execute other JS in a route view as well. for example, one of the views handles GPS location and NFC chip reading and i would love to only execute those scripts when that view is active rather than all the time, which chews up battery listening for NFC chips and GeoData even when that view is not in use.
if this isnt possible or is a serious pain then id just as soon go back to conventional page changes instead of views, im just hoping that there is a way to do this.
Here is the relevant code illustrating the issue:
index.html:
<script type="text/javascript">
$(window).load(function() {
$('#menutoggle').toggle(function() {
$('#right').animate({
left: 200
});
}, function() {
$('#right').animate({
left: 0
});
});
});
</script>
<div id="menu">
<span class="logo-bar"></span>
<ul id="sidenav">
<li>
<a href="#/Checkin">
<img src="img/home.png">Check In
</a>
</li>
<li>
<a href="#/logout">
<img src="img/logout.png">Logout</a>
</li>
</ul>
</div>
<div class="content view-animate-container">
<div id="contentcontroller" ng-view class="view-animate wrapper">
</div>
</div>
CheckIn.html
<div id="right">
<div id="menubar">
<div id="menutoggle">
</div>
<div class="title">
Check In
</div>
</div>
</div>
Now the toggle button works fine on whatever view is initially loaded, however as soon as a page change occurs the menu toggle simply stops.
is there any way to remedy this?

Disable bootstrap's dropdown-toggle

I'm using bootstrap on WordPress using the _ib theme, and I would like to add in my own responsive menu for when window is less than 768px. By default bootstrap will convert the menu to a dropdown-toggle, which when clicked shows your original menu. What I would like to do is implement my own menu when it is used on a small device or at a low resolution.
How would I remove this dropdown-toggle? I have looked around the bootstrap JS files, but I'm no JS whizz, so I can't quite figure out how to simply scrap the dropdown-toggle.
Any help appreciated!
EDIT:
<div class="container">
<div class="row">
<div class="site-navigation-inner col-sm-12">
<div class="navbar navbar-default">
<div class="navbar-header">
<!-- .navbar-toggle is used as the toggle for collapsed navbar content -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse">
<span class="sr-only">Go to...</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<!-- The WordPress Menu goes here -->
<?php wp_nav_menu(
array(
'theme_location' => 'primary',
'container_class' => 'collapse navbar-collapse navbar-responsive-collapse',
'menu_class' => 'nav navbar-nav',
'fallback_cb' => '',
'menu_id' => 'main-menu',
'walker' => new wp_bootstrap_navwalker()
)
); ?>
</div><!-- .navbar -->
</div>
</div>
</div><!-- .container -->
I tried the simple method of just removing this .navbar-toggle as I don't need it, but that actually removes the entire menu even on a full page window...
When you look at you index php page. You will see your navigation divs.
To turn off the behavior you can remove the toggle class.
<div class = container>
Etc
One of the classes will be a toggle class. Simply remove it.
What version is it? 2 or 3.
You can just replace the code with yours. I'm familiar with joomla with is basically html surrounding php.
If your looking to modify the css you will need to override it. How you do this easily will depend on wether your template uses CSS LESS or a custom.css file. You could even remove the navigation diva and replace with your own code utilizing bootstrap layout classes.
Giving the version of bootstrap will help with this question.
Bootstrap uses media queries you need to find what query you are targeting. Bootstrap website is very informative on this
http://getbootstrap.com/getting-started/
There are examples of layouts here. Make sure your nav divs and classes are the same. It will work.
Please back up or comment out old code for reuse.
When I get to my PC il look at code if not fixed by then.
You cofusing me slightly here. You have a menu (bootstrap) one and you have a plugin that is also calling a menu?
Or
Do you have two menus on the same page? Or does your plugin rely on the the current menu?
Im confused what you want here. It looks like you have a menu as part of the template and then you are calling a module to create a menu in the form of a plugin. It will not work if this is the case.
The plugin menu may conflict with the existing menu. If you have your own existing menu why dont you just remove the entire template menu and then just let your plugin be called?
If I am way of the mark I apologize. However if a plugin is involved the code is an unknown!
Is the plugin an addon to the template? If not you may have a conflict
Think you may need to contact the developer of the plugin

Jquery mobile, change part of a page

I'm trying to change a part of a page, I know that this has been asked before but I cannot really find a good solution to my issue.
The red colour is the part of the page I want to change dynamically depending on what you click on the left side that is a panel.
Image: http://wstaw.org/m/2014/04/24/ask.png
HTML Code: http://pastebin.ubuntu.com/7322513/
<body id="framework">
<div data-role="page" class="page ui-responsive-panel">
<!-- header -->
<div data-role="header" data-theme="a">
<h1 id="titlepage">ICU</h1>
Menu
Add
</div>
<!-- /header -->
<!-- content that is replaced by ajax -->
<div id="content" data-role="content">
<h2>content</h2>
</div>
<!-- /content -->
<!-- Left menu panel -->
<div data-role="panel" data-position="left" data-position-fixed="false" data-display="overlay" id="nav-panel" data-theme="b">
<ul data-role="listview" data-theme="a" data-divider-theme="a" style="margin-top:-16px;" class="nav-search" id="nav">
<li data-icon="delete" style="background-color:#111;" data-theme="b">
<!--Removed data-rel="close" since there is a bug in jquery mobile https://github.com/jquery/jquery-mobile/issues/1405 -->
Close menu
</li>
<li data-filtertext="Inbox">
<a href="html/dummy.html">
<span class="ui-mail-icon-blue nav-ui-thumbnail"></span>
<span class="ui-li-count ui-btn-up-a ui-btn-corner-all" id="mail#">2</span>
<h1 class="ui-li-headline">Inbox</h1>
<p class="ui-li-desc" id="gotMail">Du har mail!</p>
</a>
</li>
<li data-filtertext="Startsida">
<a href="html/dummy2.html">
<span class="ui-start-icon nav-ui-thumbnail"></span>
<h1 class="ui-li-headline">Startsida</h1>
</a>
</li>
<li data-filtertext="Översikt">
<a href="html/dummy2.html">
<span class="ui-overview-icon nav-ui-thumbnail"></span>
<h1 class="ui-li-headline">Översikt</h1>
<p class="ui-li-desc">Antal elever (2)</p>
</a>
</li>
<!--Nav list divider-->
<li data-role="list-divider" role="heading" class="ui-button ui-li-divider ui-bar-a ui-li-has-count">
Avdelningar
<span id="departments#" class="ui-li-count ui-btn-up-a ui-btn-corner-all">2</span>
</li>
<!--/Nav list divider-->
<!--Auto generated departments-->
<li data-filtertext="Testpage">
<a href="html/dummy.html">
<span class="ui-department-placeholder nav-ui-thumbnail"></span>
<h1 class="ui-li-headline">Avdelning 1</h1>
<p class="ui-li-desc">Antal elever (2)</p>
</a>
</li>
<li data-filtertext="Testpage2">
<a href="html/dummy2.html">
<span class="ui-department-placeholder nav-ui-thumbnail"></span>
<h1 class="ui-li-headline">Avdelning 2</h1>
<p class="ui-li-desc">Antal elever (3)</p>
</a>
</li>
</ul>
</div>
Jquery Code:
function loadPage(page, title) {
$.ajax({
url: page,
async: false
}).done(function (data) {
$("#content").html(data);
$("#titlepage").html(title);
}).fail(function () {
alert("Gick inte att ladda");
});
}
I have done my own ajax loadpage that works but is there a way to use the jquery mobile internal since it feels like a hack.
Conclusion, is there a way to do this better? and how should i load script for each page, using the main-page header to load all of them at once or is there a way to load the script when that content is loaded.
Im using
Jquery jquery-2.1.0
JqueryMobile jquery.mobile-1.4.2
Best Regards
I have done my own ajax loadpage that works but is there a way to use the jquery mobile internal since it feels like a hack.
jQuery Mobile is based on Ajax Navigation; it uses Ajax to retrieve pages, load them into DOM and then initialize them before showing them. This been said, when you use Ajax to load external data, you are doing it the right way.
You can use $.ajax(), .load() or $.get(). However, bear in mind that you need to manually initialize data retrieved - in case it contains jQM widgets - using enhancement methods e.g. .enhanceWithin().
Should I load script for each page, using the main-page header to load all of them at once or is there a way to load the script when that content is loaded.
As you're using Single Page Model, it is safer (maybe you should) load all JS libraries and style sheets in head for each and every page. Nevertheless, jQM will load those links only once on first page's initialization, the rest of pages will be loaded/retrieved via Ajax. jQM loads first data-role=page it finds in any external page and neglects any thing else.
Why to load all JS and style sheets? Is to get jQM working again in case a user refreshes current page. In this case, the current refreshed / reloaded page becomes first page.
Binding events and adding listeners:
When using jQM, you need to stay away from .ready() and/or $(function(){}) and use Page Events. Except for some cases e.g. using External toolbars, panels or popups. Those External widgets need to be initialized manually on first run before page is loaded.
$(function () {
$("#ExternalPanel").panel();
});
As for adding listeners, use pagecreate event.
$(document).on("pagecreate", "#pageID", function () {
$("foo").off("click").on("click", function () {
/* do something */
});
});
You need to remove .off() previous bindings and then .on() add them again, since external pages go through pagecreate whenever they are shown. Because jQM removes external pages from DOM once hidden.
One final point on appending elements to active page. You need to be specific as where you want to add those elements retrieved by Ajax.
var activePage = $.mobile.pageContainer.pagecontainer("getActivePage");
$.get("URL", function (data) {
$("#foo", activePage).html(data).enhanceWithin();
}, "html");
Demo (1) - Code
(1) Click "inbox"

Why this Twitter Bootstrap 3 Modal Won't Fade?

I have what should be a very simple modal using Twitter Bootstrap 3. The modal displays no problem, but it doesn't fade in from the top, as it does in this example, http://getbootstrap.com/javascript/#modals. Instead, it just plonks itself on the screen.
Here's the trigger:
<a href='#registerEmail' data-toggle='modal' class='btn btn-primary btn-lg'>Sign up with Email</a>
Here's the modal:
<div class='modal fade' id='registerEmail' tabindex='-1' role='dialog'>
<div class='modal-dialog'>
<div class='modal-content'>
<div class='modal-header'>
This is the header
</div>
<div class='modal-body'>
This is the body
</div>
<div class='modal-footer'>
This is the footer
</div>
</div>
</div>
</div>
I am pretty sure that it was working before.
I checked out this other answer, Twitter Bootstrap: Modal popup won't fade, where the modal was nested within another .fade class, but that's not the case with my code above.
Also, I'm including the entire bootstrap javascript file (at the bottom of the page) so this can't be the problem. I am loading jQuery too (before the bootstrap js).
EDIT:
This is bizarre. In the process of creating a JS fiddle I went through and eliminated extraneous elements in the page, one at a time. When I commented out a line so that my own site-wide.js would not load in the document head, the problem ceased. I then restored the line that includes site-wide.js, but I can't recreate the problem???
Firstly, thanks for the comments above.
In the end I commented out some unnecessary javascript includes and that solved the problem. Presumably it was a namespacing issue? Interesting to see that it could manifest in such a subtle manner.

Categories

Resources