Bootstrap Tour only loads when I scroll the page - javascript

I have a problem with the Bootstrap tour.
My problem
When I redirect from one page to the other the init function will be called but does not automatically continue the tour. So the bootstrap tour gets not displayed. The page contains also an AJAX frame, where content will be loaded after the document.ready.
When I scroll the page a little bit, after the AJAX frame has loaded, the tour gets suddenly displayed.
Code
var quick_tour = undefined, initialized = false;
$(document).ready(function () {
setupTour();
});
function setupTour() {
quick_tour = new Tour({
name: "quick_tour",
storage: window.localStorage,
steps: [
{
element: "#news_container",
title: "Part 1",
content: "This is the Text number 1",
path: ""
},
{
element: "#brand_title",
title: "Part 2",
placement: "bottom",
content: "And this is number 2",
path: "second.php"
},
],
});
initTour();
}
function initTour() {
if (!initialized) {
if (quick_tour === undefined) {
setupTour();
}
quick_tour.init();
initialized = true;
}
}
function startTour() {
quick_tour.restart();
}
So the #news_container for Part 1 will be displayed directly after I clicked on a button which calls the function startTour(). Then after the first part, it will be redirected to the second page. Now the tour does not get displayed, only if I scroll.
What can I do? Can I create maybe a trigger to scroll the page just a little bit?
Thank you.

After I few try's with the event trigger $(window).scroll();, I finally fixed the bug by myself. Now I just updated the initTour function:
function initTour() {
if (quick_tour === undefined) {
setupTour();
}
quick_tour.init();
$(window).scroll(); //Performs an scroll
}

Related

Why Ext.MessageBox gets stuck after several clicks on "Ok" button?

I use MessageBox of ExJS framework to show dialog with "Ok" button.
// app.js
function showNoteMessage (title, message, fn, scope) {
return Ext.Msg.show({
title: 'Title example',
message: 'Message text',
buttons: Ext.MessageBox.OKCANCEL,
promptConfig: false,
fn: function () {
if (fn) {
fn.apply(scope, arguments);
}
},
scope: scope
});
}
// index.html
<button onclick="showNoteMessage()">Open dialog several times</button>
Steps to reproduce:
Open dialog with provided two buttons "Ok" and "Cancel".
Click on the "Ok" button
Open dialog one more time.
When you click on "Ok" one more time, the dialog gets stuck on the screen and unlock all content behind it.The buttons inside the dialog are disabled.
Current version Ext.js 2.4.2.571.
After click on "Ok" button or "Cancel", gray background disappears and dialog gets stuck with unlocking content under it. I try to wrap Ext.Msg.show into setTimeout but it looks like it works only locally.
Update
I continue working on this bug and found out that issue can be in this function:
// MessageBox.js
...
onClick: function(button) {
if (button) {
var config = button.config.userConfig || {},
initialConfig = button.getInitialConfig(),
prompt = this.getPrompt();
if (typeof config.fn == 'function') {
button.disable();
this.on({
hiddenchange: function() {
config.fn.call(
config.scope || null,
initialConfig.itemId || initialConfig.text,
prompt ? prompt.getValue() : null,
config
);
button.enable();
},
single: true,
scope: this
});
}
}
this.hide();
},
...
For some reason on the step with broken click it skips this part of code:
this.on({
hiddenchange: function() {
config.fn.call(
config.scope || null,
initialConfig.itemId || initialConfig.text,
prompt ? prompt.getValue() : null,
config
);
button.enable();
},
single: true,
scope: this
});
The issue was related to the old version of ExtJS. I was not able to update it, so found a workaround: to disable animation like this:
// app.js
...
Ext.Msg.defaultAllowedConfig.showAnimation = false;
Ext.Msg.defaultAllowedConfig.hideAnimation = false;
...

explicitly release sweetalert popup after ajax call

I'm using sweetalert to ask user for an input to rename a tag. And then I make an ajax call to change the tag on server. If succeeded, I call a small callback function(postAction) which will update the UI and renamed the tag on UI. It works fine as long as little call back function has a statement "swal("done!");", so user clicks on this little confirmation message box, and sweetalert message box is released. I'm trying to see if there is a function I can call to release the input sweetalert pop up without the additional "swal("done")" statement, so user will have 1 less click. Is there an easy way to do this?
All I can find now is to add a timer in the second pop up. swal("Done!", {timer: 500}); It's OK but not ideal.
renameTag = function(tagId)
{
swal({
title: "Rename Gallery Tag",
text: 'Please provide a new tag name',
content: "input",
button: {
text: "OK",
closeModal: false,
},
})
.then(name => {
var tagName = name.trim();
if (tagName.length == 0)
{
swal({
title: "Rename Gallery Tag Failed",
text: "Tag name cannot be empty",
icon: "error",
button: "OK",
});
return;
}
else
{
ajaxAction("POST"
, "/User/RenameGalleryTag"
, { 'index': tagId, 'name': tagName }
, "rename gallery tag"
, {
'reload': false
, postAction: function () {
$(".selected-tag").text(tagName);
swal("done!");
}
});
}
})
}
You should be able to close it like this
swal.close()

Adding multiple buttons in TinyMce in a loop doesn't work

I have a config list for buttons like this:
var config = [{
name: 'first',
insertionConfig: {
title: 'first button',
onsubmit: function(){
// do sth
}
}
},{
name: 'second',
insertionConfig: {
title: 'second button',
onsubmit: function(){
// do sth
}
}
}
]
and in my TinyMce plugin I want to add all buttons according to their config. So it would end up like this:
tinymce.PluginManager.add('myPlugin', function(editor, url) {
for (var i in config) {
item = config[i];
editor.addButton(item.name, {
text: item.name,
onclick: function() {
editor.windowManager.open({
title: item.insertionConfig.title,
onsubmit: item.insertionConfig.onsubmit
}
};
}
});
but when I click on first button, it shows the second button's title. all configs of buttons refer to last added button. I know problem is something about the 'item' in the loop (all buttons refer to same item object which is the last one) but I don't know how to fix it.
Try creating a locally scoped variable for item inside the onclick function:
The issue you are running into is how variables are managed in JavaScript at the time the function is actually run. The click function is not actually run until you click an item and at that time item is pointing to the last item in the array.
EDIT: Check out this TinyMCE Fiddle for how this may happen: http://fiddle.tinymce.com/REfaab/1

Ember.js - having a subnav display on application.hbs on click only without rendering a different template

I'm having issues trying to get a subnav to display on click in Ember. In my application template I have a nav bar, and at the root I have the index template which is a full browser width template sitting behind the navbar on application template. Looks like this:
What I want to happen is when 'ABOUT' is clicked, a subnav displays on the white horizontal bar directly below the main nav. The white horizontal bar is also part of the application template. That's the only thing on the page that I want to change though when 'ABOUT' is clicked. Then when when you click an item on the subnav, say 'STAFF' it renders the about.staff template.
My problem is getting this to happen on the application template. Because if the user is currently on the 'PROGRAMS' template, and then they click about, I want the user to stay on the programs template but the subnav to still drop down below the main nav.
I've tried nested routes:
Ew.Router.map ->
#.resource "about", ->
#.route "philosophy"
#.route "leadership"
#.route "staff"
#.route "affiliations"
#.route "conditions"
#.route "programs"
#.route "testimonials"
Then I tried rendering a named outlet in application hbs with the following ApplicationRoute
Ew.ApplicationRoute = Ember.Route.extend(
renderTemplate: ->
#.render
#.render 'about',
outlet: 'about',
into: 'application'
)
But I'm just getting an error:
Error while loading route: TypeError {} ember.js?body=1:382
Uncaught TypeError: Cannot call method 'connectOutlet' of undefined
I would like to do this without having to hack a bunch of jquery into it. I hope this makes sense, I really appreciate any help.
The way I've set up my sub nav, is just using a sub-nav.hbs template, and a SubNavController to manage the active state. I render it from my main template like this:
{{render 'sub-nav'}}
You could write code in your SubNavController to determine which links to show. Hope this helps a little.
Here's my SubNavController. This is for something like a "wizard" flow, so I don't want all the links to be enabled. (I'm also using an Ember StateManager object to manage the state of my app.)
MyApp.SubNavController = Ember.Controller.extend({
getAllStates: function() {
return [
{ name: "start", label: "Start", active: true, enabled: true, href: "#/myapp/start"},
{ name: "drivers", label: "Driver", href: "#/myapp/driver"},
{ name: "vehicles", label: "Vehicle", href: "#/myapp/vehicle"},
{ name: "details", label: "Details", href: "#/myapp/details"}
];
},
init: function() {
this.set('states', this.getAllStates());
this.setActive();
},
setActive: function() {
// TODO: Clean this up. it's a little hacky.
Ember.Logger.debug("current state: " + MyApp.stateManager.get('currentState.name'));
var i = 0,
newStates = this.getAllStates(),
statesLength = newStates.length,
activeIndex = 0;
for (i=0; i< statesLength; i++) {
newStates[i].active = false;
if (newStates[i].name===MyApp.stateManager.get('currentState.name')) {
newStates[i].active = true;
activeIndex = i;
}
}
for(i=activeIndex; i<statesLength; i++) {
delete newStates[i].href;
}
this.set('states', newStates);
}.observes('MyApp.stateManager.currentState')
});

ExtJS and this.control query

I have an issue with the next code block:
run: function(e, row){
var me = this;
var container = Ext.getCmp('centercontainer');
try {
container.removeAll();
} catch(e) { }
// This block is called from another file, I just put it here to show you.
me.panels = [{
xtype: 'tabpanel',
id: 'containertabpanel',
items: [{
itemId: 'package',
title: me.PackageTitle
},{
itemId: 'excursion',
title: me.ExcursionTitle
}]
}];
// Reset
container.setTitle(me.EditDestinationTitle + row.data.name);
container.add(me.panels);
me.tabs = container.getComponent('containertabpanel');
// console.log(Ext.ComponentQuery.query('#containertabpanel > #package'))
me.control({
// Work with
// 'tab': {
// Doesn't work
'containertabpanel > package': {
mouseover: me.doPackage
}
})
},
Anyone knows how do I get to catch the click event of "package" item of tabpanel component?
I saw when I use just "tab" selector on this.control query, that work, but I can't get only "package" tab component.
Thank you in advance.
In your definition of your tabpanel you can specify -
listeners:{
click:{
fn: function(){
//click handling code goes here
}
}
}
If I understood correctly this is controller code and you are trying to catch an item click on the panel which is one of many in a tabpanel
What you can do is identify your panel by any property that is unique to it via the component query syntax like this: button[myprop=blah]
This syntax will match any buttons on the page with the following config:
{
xtype:'button'
myprop:'blah'
}
In your case you can try tab[itemId=package]
What you also need to be careful about is controller can listening only for events that are fired by the components. Make sure the event you are listening for is fired (check the docs). You can always fire custom events if necessary.
You need to do this
me.control({
// Work with
// 'tab': {
// Doesn't work
'containertabpanel > #package': {
mouseover: me.doPackage
}
})

Categories