I'm really hoping someone can help. I just got over one big hurdle in my current project, only to hit another. I have a deadline fast approaching, so any advice would be very much appreciated.
I am developing a mobile application for iPad using MVC4 and Jquery Mobile. At a certain point in my app, the user will trigger a pop-up box, which contains "yes" and "no" buttons. If the user clicks "yes", I want to send some parameters to an action in my controller, do some database work, and then return a partial view (with updated model) that will be displayed in my main view. I have the following jquery that executes upon click of a href button that is inside a pop-up.
$(function () {
$("#popupSubmit").bind("tap", tHandler);
function tHandler(event) {
$.post('#Url.Action("LoadTestData", "WO")',
{TestKey: lblTestKey.innerHTML, TestRequestNumber: lblTestServiceRequestNum.innerHTML },
function (data) { $('#detailsDiv').html(data); $('#detailsDiv').trigger("create"); });
}
});
In the above code, #popupSubmit is the href button, LoadTestData is an Action that returns a partial view, WO is the Controller, and #detailsDiv is a placeholder div in the main view. TestKey and TestRequestNumber are parameters that must be passed to the Action. Below is the code for the Action, LoadTestData. _ShowTestPartial is the Partial View.
[HttpPost]
public ActionResult LoadTestData(string TestKey, string TestRequestNumber)
{
//do database work
return PartialView("_ShowTestPartial", model);
}
Now, all of this code works on my desktop in Safari. However, this DOES NOT work on the iPad. I've tested, and the code does make it into the tHandler event when the button is clicked on the iPad, but there's something about the URL.Action or about returning a partial view in this way that the iPad just doesn't like.
Does anyone know how to solve this issue for iPad?
Edit (additional info from comments): To be clear, the partial view isn't being rendered at all on iPad, but it is on desktop Safari (and in Chrome for that matter). I have tried replaced "create" with "pagecreate" but this actually took away the JQM styling in the desktop browers and didn't change anything about the iPad.
It also doesn't seem to matter where I place the bind function...I've tried it as a separate function. I've tried it in .ready() and in .on('pageinit'). In all of these cases, it works on desktop Safari and Chrome, but not on iPad.
Also, as I said before, the .bind("tap") works on iPad. I've tested by putting other code in the tHandler. However something in the .$post does not work on iPad.
Thank you Omar, and anyone else who has any ideas. All are welcome!
Edit # 2: On Omar's advice I moved my function to $(document).on('pageinit'). I also added error catching on the $.post. Updated code below:
$(document).on('pageinit', function () {
$("#popupSubmit").bind("tap", tHandler);
function tHandler(event) {
$.post('#Url.Action("LoadTestData", "WO")', { TestKey: lblTestKey.innerHTML, TestRequestNumber: lblTestRequestNum.innerHTML })
.done(function (data) { $('#detailsDiv').html(data); $('#detailsDiv').trigger("create"); })
.fail(function (xhr, textStatus, errorThrown) { alert(xhr.responseText); })
}
});
Fortunately, this enabled me to see the error occurring on the iPad. Unfortunately, the error coming out of $.post is "An unknown error occurred while processing your request". Everything is still running smoothly on the desktop browsers with this code.
It turns out the answer was that, on the iPad the parameters were not getting passed to $.post. lblTestRequestNum and lblTestKey are labels on my JQM popup dialog box. See below:
<div data-role="popup" id="popupDialog" data-overlay-theme="a" data-theme="b" data-dismissible="false"
style="max-width:416px;" class="ui-corner-all">
<div data-role="header" data-theme="a" class="ui-corner-top">
<h1>Selection <label id="lblTestRequestNum" style="text-align:left; height:22px; font-size:14px;">#Model.TestRequestNumber</label></h1>
</div>
<div data-role="content" data-theme="a" class="ui-corner-bottom ui-content">
<h3 class="ui-title" style="text-align:center; height:22px;">Are you sure?</h3>
<label id="lblTestKeyLabel" style="text-align:left; height:22px; font-size:14px; margin-left:95px;">Test Key: </label>
<label id="lblTestKey" style="text-align:left; height:22px; font-size:14px;"></label>
<label id="lblTestType" style="text-align:left; height:22px; font-size:14px; margin-left:95px;"></label>
<a id="popupSubmit" data-role="button" data-inline="true" data-rel="back"
data-mini="true" data-theme="b" style="width:150px;" type="submit">Yes</a>
<a href="#" data-role="button" data-inline="true" data-rel="back"
data-mini="true" data-transition="flow" data-theme="b" style="width:150px;">No</a>
</div>
</div>
On the desktop, Safari was able to retrieve the parameters I needed from the labels in the popup. But on iPad, it could not. So, I simply found places outside of the pop-up, in my main view to display/retrieve my parameters from. Lesson learned: Don't expect iPad to be able to read anything from labels/inputs inside your pop-up dialog.
Related
I'm using Material Design Lite (http://getmdl.io) along with dialog-polyfill (https://github.com/GoogleChrome/dialog-polyfill) for the modal dialog boxes.
Everything works great on my desktop browsers (Chrome, Safari, etc.), but on iOS (both Chrome and Safari), I can't tap inside the modal dialog boxes. It just doesn't respond.
I've tried the suggestion I've seen posted several places to put "cursor: pointer" in the CSS, but either I'm not doing it correctly, or it's not working.
Here's a typical modal dialog from my code:
<dialog class="mdl-dialog" id="delete_alias_confirm_dialog">
<h4 class="mdl-dialog__title">
Delete alias
</h4>
<div class="mdl-dialog__content" id="delete_alias_confirm_dialog_content">
<p>
Alias [ALIAS NAME] has been successfully deleted.
</p>
<form action="#">
<div class="mdl-dialog__actions">
<button type="button" class="mdl-button mdl-button--raised mdl-button--colored" onClick="delete_alias_confirm_dialog.close()" id="delete_alias_confirm_dialog_ok_button">OK</button>
</div>
</form>
</div>
</dialog>
<script>
var delete_alias_confirm_dialog = document.querySelector('#delete_alias_confirm_dialog');
if (! delete_alias_confirm_dialog.showModal) {
dialogPolyfill.registerDialog(delete_alias_confirm_dialog);
}
var delete_alias_curr_name=""
function show_delete_alias_confirmation(clicked_element) {
delete_alias_curr_name=((clicked_element.parentNode).parentNode).parentNode.parentNode.querySelector('#alias_name').innerText
var delete_alias_dialog_delete_button=document.querySelector('#delete_alias_dialog_delete_button');
var delete_alias_dialog_alias_name=document.querySelector('#delete_alias_dialog_alias_name');
delete_alias_dialog_alias_name.innerHTML=delete_alias_curr_name
delete_alias_dialog.showModal();
delete_alias_dialog_delete_button.blur();
}
</script>
Check the order in which you load the CSS.
If you are loading dialog-polyfll.css before material.min.css that might be the source of the problem.
Also check if you don't have a dialog duplicate, this also results on a dialog that can't be closed on IOS.
I have a jQuery UI dialog with several tabs, sometimes, I need to pop up one of those tabs as a separate dialog (atop of tabbed initial dialog), so, can I achieve this by re-using the same dialog?
(of course with a bit run-time customizations, JavaScript/DOM HTML manipulations, but with the same <div></div> template initially defined and with the same HTML FORM elements IDs)
This is not the optimal solution, but could be an approach of what should you do.
HTML:
<div id="dialog" title="Basic dialog">
<div class="dtabs">
<ul>
<li>First
</li>
<li>Second
</li>
<li>Third
</li>
</ul>
<div id="tab1">
<p>First!</p>
</div>
<div id="tab2">
<p>Second!</p>
</div>
<div id="tab3">
<p>Third!</p>
</div>
</div>
</div>
<input value="Tab 1 on Dialog" type="button" alt="1" />
<input value="Tab 2 on Dialog" type="button" alt="2" />
<input value="Tab 3 on Dialog" type="button" alt="3" />
Javascript:
$(function () {
// Dialog without autoOpen just to hide it from viewport
$('#dialog').dialog({
autoOpen: false
});
$('input').click(function () {
// Clone the dialog and append it to body
// Get "tab" number to know which tab should I set as active later
var d = $('#dialog').clone().appendTo('body'),
tab = $(this).attr('alt')-1;
// Assign "dialog" behaviour and remove it when I close it
d.dialog({
autoOpen: false,
close: function (e, ui) {
$(this).dialog('destroy').remove();
}
});
// Tabs inside my dialog has "tabs" behaviour by JQueryUI
d.find('.dtabs').tabs({
active: tab
});
// Open up!
d.dialog('open');
});
});
http://jsfiddle.net/franverona/k7cuH/
Let me explain you what I did:
I create my dialog in pure HTML and using JQueryUI assign it a dialog behaviour.
Every button has a property that will tell me later what tab should I open in my future dialog.
When user click on button I clone my previous dialog, append it to body and get "tab" attribute. Then I assign it a dialog behaviour without autoOpen and with a function associated to close event to remove it from DOM (to avoid multiple dialogs on my HTML body).
Before open, I assign a tabs behaviour to all the content inside my recently created dialog (look that I'm using find function) and set as an active tab the correct tab using tab property retrieved before.
Now I'm ready to open my dialog with all set up.
I repeat: this isn't an optimal solution, but should work as a prototype of later development iterations.
Happy coding!
I am using jquery mobile and a dialog to display some multiple select boxes. Some of the content is dynamically created with Ajax based on the selections. I would like to make the Ajax call when the dialog is closed (through the regular x button). The main parts of the html look as follows:
<a href="#queryPage" data-rel="dialog" data-transition="slidedown" >Filter Results</a>
<div data-role="page" id="queryPage" data-theme="a">
<div data-role="header" data-theme="a">
<h1>Select Filters</h1>
</div>
<div data-role="content">
<form action="" method="get" id="filterForm">
<fieldset id ="filterFields"></fieldset>
</form>
</div>
</div>
I am currently making the call by running the code on page hide as follows:
$('#queryPage').live('pagehide', function(event) {
//code for ajax call
});
However, I would like to make the call when the dialog closes because some of the select lists are large and they create a new page that hides the queryPage even though the dialog has not been closed. I have tried:
$('#queryPage').bind('dialogclose', function(event) {
alert('closed');
});
and also tried
$('#queryPage').dialog({close:function(event, ui){
alert("closed");
}});
These I have put in a function called on page load but the alert is not shown when the dialog is closed. Any help will be appreciated.
There are no specific events for dialogs as they are simply pages that are displayed as a dialog. Try the pagehide event.
$("#MyDialog").bind("pagehide",function(){
alert("Dialog closed");
});
Also, the first line of your sample code has a link that is outside of a <div data-role="page"> which should not be done.
Pagehide can be delegated as such:
$(document).delegate("#MyDialog", "pagehide", function() {
alert("Dialog closed");
});
and you will also have access to the screen elements of the calling page.
Andleer shared the appropriate event for closing the dialog using jquery. however, we can also code in this way.
$(document).on("pagehide","#Dialog",function(){
console.log('Dialog has closed.');
});
I have used JQM SimpleDialog2 in my app. I am having one textbox and button in that dialog. i can't able to get the value from input while click on button in dialog. i have used blank mode.. Here is my code.. I am getting empty value from this code. please correct me.
<div id="myDialog" style="display:none"
data-options='{"mode":"blank","top":"10%","headerClose":false,"blankContent":true}'
<Center>please enter Your Amount here</center>
<input id="txtAmt" name="amy" value="" type="text" placeholder="Amount">
<div data-role="navbar" data-grid="a">
<ul>
<li>Submit</li>
<li>Cancel</li>
</ul>
</div>
function getAmount()
{
alert("amount: "+$("#txtAmt").val());
}
i didnt try this using SimpleDialog but this works just fine for me:
function getAmount(){
alert (document.getElementById('txtAmt').value);
}
By the way i would recommend using the built-in Popup-Dialog function instead of SimpleDialog. See here: http://jquerymobile.com/demos/1.2.0/docs/pages/dialog/index.html
I have a weird problem with a simple form with checkboxes..
The first time it's shown it looks fine.. But then after navigating back to the previous page and be to it again - the ui is not updates resulting in plain checkboxes without jQuery mobile style..
I've Googled like crazy and found a couple of hints like .fieldcontain(); but it's doesn't work =(
The data is being retrieved through knockout bindings..
Any good ideas?
Here's the code...
<div id="searchCitiesPage" data-role="page" data-theme="a" class="page searchCities">
<header data-role="header" data-theme="b">
</header>
<div data-role="content" class="content" data-theme="a">
<script id="countyListTemplate" type="x-jquery-tmpl">
<form id="fieldform" action="form.php" method="post">
<fieldset id="fieldsetgroup" data-role="controlgroup">
{{each BoligPortal.AdSearch.postalcodesInSelectedCounty}}
<input type="checkbox" name="checkbox-${zipcode}-${timestamp}" id="checkbox-${zipcode}-${timestamp}" class="zipcodecheckbox"/>
<label for="checkbox-${zipcode}-${timestamp}">${zipcode} ${city}</label>
{{/each}}
</fieldset>
</form>
</script>
<div data-bind="template: 'countyListTemplate'"></div>
<div class="submit">
Næste
</div>
</div>
I was having a problem like this too, but in my case, the checkboxes were being redrawn dynamically before loading the page. I tried refreshing:
$("input[type='checkbox']").checkboxradio("refresh");
But it gave me an error stating that checkboxradio hadn't been initialized. However, when I tried this instead:
$("input[type='checkbox']").checkboxradio();
It made the checkboxes appear correctly every time. I'm still fumbling in the dark with JQuery Mobile and can't say exactly what happens where and why (I think I'm initializing the checkboxes?), but I thought I would share for the next time someone like me googles their way to this thread.
You can add some javascript to re-initialize the jQuery Mobile markup for your checkbox on each page load. Something like this:
<script type="text/javascript">
$(function() {
$('[data-role=page]').live('pageshow',function(){
$('#fieldform').find('input').checkboxradio();
});
});
</script>
I would suspect this code
{{each BoligPortal.AdSearch.postalcodesInSelectedCounty}}
<input type="checkbox" name="checkbox-${zipcode}-${timestamp}" id="checkbox-${zipcode}-${timestamp}" class="zipcodecheckbox"/>
<label for="checkbox-${zipcode}-${timestamp}">${zipcode} ${city}</label>
{{/each}}
is being called again when you transition back to the page. I would suggest pulling the infomation/tags/etc.. before the page displays (on the first load) and display it statically. So when transitioning back it shows the same data.
of you could use one of the live events and restyle it before the page shows, example:
$('.zipcodecheckbox').live('pagebeforeshow',function(event, ui){
$("input[type='checkbox']").checkboxradio("refresh");
// or
$(".zipcodecheckbox").checkboxradio("refresh");
});