I have a hybrid mobile app using jQuery Mobile. At one point, in iOS, it loads a Modal window which contains a drop down box. I have a JavaScript function, in another file, that populates the drop down with different options, depending on a parameter. This works fine in Black Berry because it uses another page, instead of a modal, but in iOS the function to fill the drop down doesn't execute, I'm guessing its running before the the modal.
So I was reading about it and I think I need to use a Callback.
The modal gets initiated with:
app.modal.init(app.views.MODAL_REJECT);
I had tried to just call the function after it
getDropDownOptions(app.myvar);
But that didn't work.
How would I use a Callback in this case? I read about it but I really don't understand how to apply it.
Thanks
More Info / Update:
Something like this?:
fromBT: function () {
if (hwc.isIOS()) {
var _callback = function () {
mySelect = $('#reason-code');
myOptions = {
1: 'AAAA',
2: 'BBBB',
3: 'CCCC',
};
$.each(myOptions, function (val, text) {
mySelect.append(
$('<option></option>').val(val).html(text)
);
});
}
app.modal.init(app.views.MODAL_WINDOW(_callback));
} else if(hwc.isBlackBerry()){
app.loadPage(app.views.BB_PAGE, true);
}
}
So fromBT is called by a button, if is iOS I open a Modal window, but I want to add options to a select/dropdown inside the modal window.
Related
We are implementing a rather complex single page application and decided to use the "Jquery-context-menu" toolbox. However, we have a fundamental question, and after two days of searching, and reading stuff on the web we are somewhat out of ideas.
The basic question is: If and if yes, how, it will be possible to access the update function (i.e the disable function) from outsite the menu, while the menu is still upon?
The scenario:
We are implementing a game. We use the "jquery context menu" as a context menu for an icon that can be activated by the user (think of a rpg type of icon). After activating it via a click it will be deactvitated automatically (after a few seconds) and then be ready for reactivation again after a while. What we what is that the menu is capturing this state of the icon, by enabling or disabling the menu, while the menu is held open.
There is one example of how to change the visibility of a menu item, via a button press in the same menu, as can be found here:
http://medialize.github.io/jQuery-contextMenu/demo/disabled-changing.html
However, we aim to update the menu from outsite (via a knockout subscribe call). So we would like to do something like:
myknockoutobservable.subscribe(function(newValue){
correctRefernceToThis.data('disableItem1', newvalue)});
while the disabled function looks somehitng like:
disabled: function(key, opt) {
return !this.data('cutDisabled')};
OR, if this does not work we maybe could directly call the update fucntion
myKnockoutobservable.subscribe(function(newValue){
$.contextMenu.op.update(correctRefernceToOpt,correctRefernceToroot)});
and then querying the knockout observable in the callback
if (!myKnockoutobservable) {
return true;}
else {
return false;
The main problem seems to be that we don't reference the context correctly, so we don't have a handle on the correct this, opt, to root, variables, from outside of the Jquery context menu (At least that is our current opinion). We would be very happy if someone could help us finding a solution, or even some good ideas what to try (what we haven't yet).
Thanks you for your help! I understand your approach and it is indeed exactly what we have done:-) I might have not been so clear on this issue but this is the current code od the disabled callback.
disabled: function(key, opt) {
if (!self.item._blocks.Feature._processedStack().canBeActivated()) {
return true;
}
else {
return false;
}
}
This works such that when the menu in closed and reopned again the state is updated. However the update is NOT working while the menu is still open because nothing is triggering the menu to update to the new value.
At the moment we are trying to solve the issue with a different library, will keep you updated.
best, Caspar
You won't subscribe, you'll just have an observable in your viewmodel that you set to true or false, and the menu item will toggle in response. The disabled member of your menu item will look like this:
disabled: function() {
return myobservable();
}
As James Thorpe commented, you'll want to create a custom binding handler to set up your context menu.
It sounds like you're working with several unfamiliar tools. Here is a Fiddle with a minimal example: http://jsfiddle.net/sv3m7ok8/
Update
It occurred to me that since the context menu doesn't bind to a single element, but uses a selector, it makes more sense to do the binding on the body tag. So an updated example: http://jsfiddle.net/sv3m7ok8/1/
Updated again
I now understand that you are specifically trying to get the menu item to enable/disable while the menu is open (and that it doesn't do that normally). I had to go under the covers to get at the menu item node, and hook up a subscription to set the disabled class on it.
init: function (element, data, allbindings, data) {
var dynamicDisable = false;
$.contextMenu({
selector: '.context-menu-one',
callback: function (key, options) {
var m = "clicked: " + key;
window.console && console.log(m) || alert(m);
},
items: {
"edit": {
name: "Clickable",
icon: "edit",
disabled: function (opt, key) {
if (!dynamicDisable) {
var node = key.items.edit.$node[0];
data.disableMenu.subscribe(function (dis) {
$(node)[dis ? 'addClass' : 'removeClass']('disabled')
});
dynamicDisable = true;
}
return data.disableMenu();
}
}
}
});
}
My fiddle sets an interval to toggle disableMenu. You can watch the menu item become active and gray.
http://jsfiddle.net/sv3m7ok8/3/
I'm using bootstrap3-dialog library from https://nakupanda.github.io/bootstrap3-dialog/
The problem is, everytime the dialog shows (alert, confirm or custom dialog), the body's scrollbar is gone and never come back when dialog closed. I could add this line on every dialog's onhide property, but that would be time consuming:
$('body').css('overflow','scroll')
Is there any other way to trigger that function every time the modal closes?
I was going through the code of bootstrap modal and they have this:
resetScrollbar: function() {
var openedDialogs = this.getGlobalOpenedDialogs();
if (openedDialogs.length === 0) {
this.$body.css('padding-right', BootstrapDialogModal.ORIGINAL_BODY_PADDING);
}
},
Which is called on:
hideModal: function() {
this.$element.hide();
this.backdrop($.proxy(function() {
var openedDialogs = this.getGlobalOpenedDialogs();
if (openedDialogs.length === 0) {
this.$body.removeClass('modal-open');
}
this.resetAdjustments();
this.resetScrollbar();
this.$element.trigger('hidden.bs.modal');
}, this));
}
I can't seem to figure out what would cause this code to not bring the scrollbar back. It seems to be working fine on their website.
If you are comfortable, I would suggest debugging the hideModal function of the api itself and figure out why it is not working and maybe put the above css snippet in there as a work around.
Or maybe post your code on plunkr, jsfiddle so we can look at what is going on.
I'm using the Win8 Grid View Template to display infos from a news site. In the lower menu bar i have implemented a function wich shuts off the titles, so that only the pictures are still visible.
This function is in a "global.js" file which is included in the "default.html" so it's available everywhere and it looks like this:
//function to turn titles off and on
function titleToggle() {
var titles = document.getElementsByClassName("item-overlay");
for (var i = 0; i < titles.length; i++) {
if (Global.titlesAreOn) {
titles[i].style.display = "none";
}
else {
titles[i].style.display = "";
}
}
Global.titlesAreOn = !Global.titlesAreOn;
};
So when i call this function from the menu bar it works for the first items, but when i scroll the end of the groupedItems view (hubview) the titles are still there. When i then scroll back to the beginning the titles are there again too.
I'm also calling the titleToggle function from the ready() function of the "groupedItems.js" to check whether or not to display the titles depending on a global variable. When i do that (whenever i come back to the hubpage) it works all the way, just as expected.
ui.Pages.define("/pages/groupedItems/groupedItems.html", {
navigateToGroup: function (key) {
nav.navigate("/pages/groupDetail/groupDetail.html", { groupKey: key });
},
ready: function (element, options) {
appbar.winControl.disabled = false;
appbar.winControl.hideCommands(["fontSizeBt"]);
appbar.winControl.showCommands(["titleToggle"]);
if (Global.titlesAreOn == false) {
Global.titlesAreOn = true;
Global.titleToggle();
}
I made a short video to show the problem, because its kinda hard to explain --> http://youtu.be/h4FpQf1fRBY I hope you get the idea?
Why does it work when i call it from the ready() function?
Does anyone have an idea? Is it some kind of automatic item caching in order to have better performance? And how could this be solved?
Greets and thanks!
First, here is why this might be happening - WinJS is using single page navigation for the app experience. This means that when you navigate to a new page, actually you don't. Instead the content is removed from the page and the new content is loaded in the same page. It is possible that at the moment you press the button not all elements have been loaded in the DOM and therefore they cannot be manipulated by your function. This is why when you call it from the ready() function it works - all contents are loaded in the DOM. It is generally better to do things in the ready() function.
About the behavior when you slide back left and the items are again reloaded with titles - for some reason the listView items are reloading. Maybe you are using live data from the news site and they are refreshing with the listView control's template again. I cannot know, but it doesn't matter. Hiding the elements is not the best approach I think. It is better to have two templates - one with a title element and one without. The button click handler should get the listView controls(they have to be loaded) and change their templates.
ready: function (element, options) {
var button = document.getElementById('btn');
button.addEventListener("click", btnClickHandler);
}
And the handler:
function btnClickHandler(e) {
var listView = document.getElementById("listView").winControl;
var template2 = document.getElementById("template2");
listView.itemTemplate = template2;
};
I'm trying to learn pure native JavaScript, so please, don't suggest using frameworks to solve the task. I know the're awesome and learning them will be the first thing I'm going to do when I'm done with pure JS :)
Now, the question. Fiddle
As you can see, I have two custom dropdowns there. Each of them can be opened and controlled both with mouse and keyboard. The last thing I need to do to solve this task is to implement the following functionality: opening one dropdown should close the other one, and clicking outside the dropdown should close any of the opened dropdowns (assuming only one can be opened at a time).
I've tried adding an onclick listener to the document, which would close the dropdowns if any of them were open but not used before, but after I've clicked the document once, the dropdowns are not showing any more. But that's not even a solution for half of the problem. since I allocate flags bIsOpen to the objects, I can't access them from another object to see if it's triggered.
Give me a hint, please :)
Move the opening and closing logic into their own functions:
DropDown.prototype.open = function (e) {
...
}
DropDown.prototype.close = function (e) {
...
}
And
this.htmlDropDown.onclick = function (e) {
if (this.bIsOpen) {
this.open(e);
} else {
this.close(e);
}
}
(Make sure that the open and close functions adjust bIsOpen, not the onclick handler.)
Then, add a list of all the current dropdowns that exist:
function DropDown(htmlObject) {
DropDown.dropdowns.push(this);
...
}
DropDown.dropdowns = []; // no 'prototype'
And finally, in the open-er, close all the other dropdowns:
DropDown.prototype.open = function (e) {
var dropdown;
for (var i = 0; i < DropDown.dropdowns.length; i++) {
dropdown = DropDown.dropdowns[i];
if (dropdown !== this) {
dropdown.close();
}
}
...
}
I have Drag/Drop functionality in my page embedded using YAHOO.js which is initalized at load of the page. When 'alert' is put in the init function, the Drag/Drop is working otherwise
it is not. Using Firebug I had debugged the code and seen when init function is called but not looping through the function when no alert is put.
This function should work when ALT key is pressed. I am using velocity template engine over JavaScript.
Sample code:
<script type="text/javascript" language="JavaScript">
var myLogger;
var dd1, ddTrashCan; // draggable div objs
#if ($displayOptions.isDoDragDropJavaScript())
YAHOO.util.Event.addListener(window, "load", DD_TestInit);
#end
function display(data) {
var output = "<div>" + data.text + "</div>";
element.innerHTML=output;
}
function DD_TestInit() {
#if ($showLoggerDiv)
initLogger();
#end
//display("date");
initDragObjects();
}
function logMsg(strMsg) {
if (myLogger)
myLogger.debug(strMsg);
}
function initDragObjects() {
//alert('---');
if (dd1) dd1.unreg();
if (ddTrashCan) ddTrashCan.unreg();
YAHOO.util.DDM.mode = YAHOO.util.DDM.POINT;
YAHOO.util.DDM.clickTimeThresh = 10;
## init constant drag objects, draggable div and droppable trash, resp.
dd1 = new lineSched_Draggable("dragDiv1");
ddTrashCan = new lineSched_Droppable("TrashCan");
}
What I had found is whenever I put an alert or call any window.open() this works fine.
Any clue whats happening here.
There is timer event which is delaying the process.My feeling is that this is a timing issue. The page is not fully in place when on load. The alert slows the process down, essentially the page is in place by the time the user clicks Ok on the alert. Clearly, we can’t deploy the app with an alert. But, we can look into different places to put the initialization. We can try to place it the same place I added the timing, when the page receives the last table. The page should be fully formed at this point and the function should work properly.