Persist form values between pages - jquery-mobile

In my PhoneGap app I have a form page in which there is a contacts button. When the user clicks it the contacts page appears to select a contact and then returns to the form to submit it. In the JSFiddle when returning to the form the entered data still in the form, but in my app when I return to the form all the entered data has been removed so the user needs to fill the form again.
How can I keep the entered form data in the fields when returning to it from the contacts page?
When the user clicks the done button in the contacts page I use this code to pass the selected data to the formPage.
JSFiddle
$('#Done').on('click', function(){
$.mobile.changePage('FormPage.html', {
dataUrl: 'FormPage.html?paremeter=' + selectedContact + ' ',
data: {
'paremeter': '' + selectedContact + ''
},
reloadPage: false,
changeHash: false
});
});

You can use a popup instead of a separate page.
Here is your updated FIDDLE
Your page 2 is now a popup within the first page. It includes a DIV that is scrollable and a listview which is dynamically populated with 100 items:
<div data-role="popup" id="page2" data-position-to="window">
<div id="scrollDiv">
<ul data-role="listview" id="contactsList">
</ul>
<div>
</div>
#scrollDiv{
max-height: 450px;
width: 300px;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
On pageinit I add 100 contacts and then creat a click handler for the contacts that writes the selected contact id back to a field in the form and closes the popup:
$(document).on("pageinit", "#FormPage", function(){
var contactsList;
for (var i = 0; i< 100; i++){
contactsList += '<li>contact ' + i + '</li>';
}
$("#contactsList").append($(contactsList));
$("#contactsList").listview("refresh");
$(".contactLink").on("click", function(){
var msg = 'you selected contact: id = ';
msg += $(this).data("contactid");
$("#selContact").val(msg);
$("#page2").popup( "close" )
});
});

Related

Add button inside Kendo MVC DatePicker

I have a Kendo MVC DatePicker as belowed, it will render as a textbox with a button (with calendar icon) within it which can trigger the date picker UI.
In my scenario, I need to insert a button to clear the value of the textbox, just on the left of the calendar button.
What my problem is that, is it possible (and how can I) insert another custom button inside the textbox rendered?
<div class="col-md-2 ">
#(Html.Kendo().DatePicker()
.Name("InspecitonDate")
.Value(DateTime.Now.AddMonths(-3)).Format("dd/MM/yyyy")
.HtmlAttributes(new { style = "width: 100%" })
)
</div>
Kendo date picker adds attribute data-role so select all the controls through jQuery on page with attribute data-role = datepicker
<script>
$(document).ready(function () {
var dt = $("[data-role='datepicker']");
//For each control insert an icon button calling js function clearDate to clear date input
$.each(dt,
function (i, d) {
$("#" + d.id).before("<span class='fa fa-times' onclick=\"clearDate('" + d.id + "')\"></span>");
});
});
function clearDate(inputId) {
$("#"+inputId).data("kendoDatePicker").value(null);
}
I would suggest to write this code in some common js file so that all kendo date controls in every page can be changed. You may add some style too to move icon to right
.k-picker-wrap > span.fa-times {
position: absolute;
right: 35px;
top: 8px;
color:#01ace4;
cursor: pointer;
}
There is no such built-in option, so you need to do it yourself. So you need to append the needed extra button on document.ready

JQuery multiple select filter bug

I have a multiple select with a filter. Filtering works properly, but when you select a filtered item it does not change to the selected state (there is no tick in the box of the selected item).
I followed the instructions of the offical JQuery Mobile page. The only difference is that they do not use a multiple select. Is there a workaround to have the filter functionality with multiple select boxes?
JQuery Mobile filterable select
My select:
<form>
<div class="ui-field-contain">
<label for="title-filter-menu">Placeholder:</label>
<select id="title-filter-menu" multi data-native-menu="false" class="filterable-select">
<option>Select fruit...</option>
<option value="orange">Orange</option>
<option value="apple">Apple</option>
<option value="peach">Peach</option>
<option value="lemon">Lemon</option>
</select>
</div>
</form>
JS
( function( $ ) {
function pageIsSelectmenuDialog( page ) {
var isDialog = false,
id = page && page.attr( "id" );
$( ".filterable-select" ).each( function() {
if ( $( this ).attr( "id" ) + "-dialog" === id ) {
isDialog = true;
return false;
}
});
return isDialog;
}
$.mobile.document
// Upon creation of the select menu, we want to make use of the fact that the ID of the
// listview it generates starts with the ID of the select menu itself, plus the suffix "-menu".
// We retrieve the listview and insert a search input before it.
.on( "selectmenucreate", ".filterable-select", function( event ) {
var input,
selectmenu = $( event.target ),
list = $( "#" + selectmenu.attr( "id" ) + "-menu" ),
form = list.jqmData( "filter-form" );
// We store the generated form in a variable attached to the popup so we avoid creating a
// second form/input field when the listview is destroyed/rebuilt during a refresh.
if ( !form ) {
input = $( "<input data-type='search'></input>" );
form = $( "<form></form>" ).append( input );
input.textinput();
list
.before( form )
.jqmData( "filter-form", form ) ;
form.jqmData( "listview", list );
}
// Instantiate a filterable widget on the newly created selectmenu widget and indicate that
// the generated input form element is to be used for the filtering.
selectmenu
.filterable({
input: input,
children: "> option[value]"
})
// Rebuild the custom select menu's list items to reflect the results of the filtering
// done on the select menu.
.on( "filterablefilter", function() {
selectmenu.selectmenu( "refresh" );
});
})
// The custom select list may show up as either a popup or a dialog, depending on how much
// vertical room there is on the screen. If it shows up as a dialog, then the form containing
// the filter input field must be transferred to the dialog so that the user can continue to
// use it for filtering list items.
.on( "pagecontainerbeforeshow", function( event, data ) {
var listview, form;
// We only handle the appearance of a dialog generated by a filterable selectmenu
if ( !pageIsSelectmenuDialog( data.toPage ) ) {
return;
}
listview = data.toPage.find( "ul" );
form = listview.jqmData( "filter-form" );
// Attach a reference to the listview as a data item to the dialog, because during the
// pagecontainerhide handler below the selectmenu widget will already have returned the
// listview to the popup, so we won't be able to find it inside the dialog with a selector.
data.toPage.jqmData( "listview", listview );
// Place the form before the listview in the dialog.
listview.before( form );
})
// After the dialog is closed, the form containing the filter input is returned to the popup.
.on( "pagecontainerhide", function( event, data ) {
var listview, form;
// We only handle the disappearance of a dialog generated by a filterable selectmenu
if ( !pageIsSelectmenuDialog( data.prevPage ) ) {
return;
}
listview = data.prevPage.jqmData( "listview" ),
form = listview.jqmData( "filter-form" );
// Put the form back in the popup. It goes ahead of the listview.
listview.before( form );
});
})( jQuery );
CSS
.ui-selectmenu.ui-popup .ui-input-search {
margin-left: .5em;
margin-right: .5em;
}
.ui-selectmenu.ui-dialog .ui-content {
padding-top: 0;
}
.ui-selectmenu.ui-dialog .ui-selectmenu-list {
margin-top: 0;
}
.ui-selectmenu.ui-popup .ui-selectmenu-list li.ui-first-child .ui-btn {
border-top-width: 1px;
-webkit-border-radius: 0;
border-radius: 0;
}
.ui-selectmenu.ui-dialog .ui-header {
border-bottom-width: 1px;
}
I found out, that the right option is selected, but the shown selected state in the filtered list is wrong.
If you have the options
a1
b1
c2
d2
with an filter "1" you get
a1
b1
you can correctly select each of them.
If you filter "2"
you get
c2
d2
if you select c2 (which is the first option of the selected list and the third of the original list) jquerymobile tries to show selected state on the !third! option of the !filtered list". thats the bug.
However, with the basic filtered select example ist works (first one in http://view.jquerymobile.com/master/demos/selectmenu-custom-filter/)
Problem here: The filter bar (search input) is above the select Header (Closing icon + Label).

auto-scroll grid in jqm

I have a simple webapp consisting of a main page that contains a grid with 3 columns.
<div data-role="content">
<div class="ui-grid-b" id="main">
</div>
</div>
At runtime this grid is expanded with new rows by clicking a button.
$(document).on('pageinit', '#page-home', function() {
$('button').on('click', function() {
var table = $('#main');
var blocka = $('<div class="ui-block-a">One</div>');
var blockb = $('<div class="ui-block-b">Two</div>');
var blockc = $('<div class="ui-block-c">Three</div>');
blocka.appendTo(table);
blockb.appendTo(table);
blockc.appendTo(table);
});
});
Now I have the problem that if there are more rows added (let's say 10) then the last rows run out of screen.
Is there a simple way to automatically scroll to the last row everytime a new one is created?
I know that I can get the element by calling table.find('.ui-block-a:last') but I don't know how to scroll to the found element.
Thanks in advance!
As suggested in this answer: How to go to a specific element on page?
Add the following after blockc.appendTo(table) in your click handler:
$('html, body').animate({
scrollTop: blocka.offset().top + 'px'
}, 'fast');
Here is fiddle demo: http://jsfiddle.net/ezanker/5ap48/

jquery ui dialog is creating two dialogs

A screenshot : http://d.pr/i/A4Kv
This is my dialog code:
function popupbox(title,html,buttonTxt,buttonAction) {
var buttons = {};
if(buttonTxt != null) {
buttons[buttonTxt] = buttonAction;
}
buttons['Cancel'] = function() {
jQuery(this).dialog('destroy').remove();
};
var p = jQuery('<form class="dialoginnerbox">' + html + '</form>');
p.dialog({
autoOpen: false,
resizable: false,
modal: false,
width: 'auto',
height: 'auto',
maxHeight: 600,
maxWidth: 980,
title: title,
close: function(event, ui){
jQuery(this).dialog('destroy').remove();
},
buttons: buttons
});
p.dialog('open');
}
Any ideas?
---- UPDATE ----
I swapped out the returning html for some dummy text and that fixed it.. so something with the html that is being put into the popup is making it open twice...
Malformed html and inline script tags cause jquery ui dialog to open multiple dialogs.
With jQueryUI dialogs; jQuery may consider valid html as malformed html in some cases. The reason I say this is I ajax loaded the html for my dialog with valid html and valid html comments. I got double dialog boxes until I removed the html comments from the ajax loaded html. Example...
content.htm
<div id="myDialogContent">Alert!</div><!-- Here is an innocent looking comment -->
dialog.js
$.get( '/content.htm', function( html ){
$( html ).dialog();
});
This would produce a double dialog. If the html begins or ends with an html comment, the same dialog issue occurs. The only way around is to either remove the html comment or wrap the html text in another html tag like so...
dialog.js
$.get( '/content.htm', function( html ){
$( '<div>'+html+'</div>' ).dialog();
});
This would produce one dialog.
function display_dialog() { if($('.dialog_wrapper').length) {
return;
}
$('<div class="dialog_wrapper"</div>').dialog({
autoOpen: true,
modal: true,
A workaround for this problem is to use a counter:
var count = 0;
var $dialog = $('<div></div>') .dialog({ ...
autoOpen: false,
modal: true,
height: 625,
width: 500,
title: pagetitle
...
});
if (count > 0) {
$dialog.dialog("destroy").remove();
count = 0;
}
$dialog.dialog('open');
count++;
worked for me... for the dialog issue, but i am getting multiple requests on the server ...
something like that: when i click for the first time on the link, it sends on information to the server. When i click for the second time (without refreshing the browser) it sends the same information twice. When i click for the third time, three requests are sent to the server, and so on...
If you wrap your html in a single tag, it may clean it up.
The inclusion of divs inside the html may cause a dialog for each one unless there's a layer above:
This didn't work for me:
<hr /> blah blah blah
<h3>blahblahtitle</h3>
<div id=somestufffirst>here's the stuff</div>
<div id=someotherstuff>here's some more stuff</div>
But this did:
<div>
<hr /> blah blah blah
<h3>blahblahtitle</h3>
<div id=somestufffirst>here's the stuff</div>
<div id=someotherstuff>here's some more stuff</div>
</div>

display jquery dialog till data is loaded

I have 2 div one to load data from an ajax request and another to display Jquery dialog with gif image which says loading.
The jquery dialog is displayed when the page is requested while the ajax function gets the data from the controller. I want to close the dialog when the ajax function completes the request but not sure hot to do it.
here is the code
Page
<style>
.ui-dialog-titlebar-close{
display: none;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
//define config object
var dialogOpts = {
title:"Retreving Donation Details",
modal: true,
autoOpen: true,
height: 200,
width: 250,
closeOnEscape: false,
resizable: false,
};
$("#ajaxload").dialog(dialogOpts); //end dialog
$("#ajaxload").dialog("open");
});
</script>
//jquery dialog
<div id = "ajaxload" style ="display:none; background-color:Green; text-align:center;">
<br />
<img alt="loader" src = "../../Content/loader.gif" id = "loader" height="100" width ="100" style = "margin:auto; text-align:center; vertical-align:middle;" />
</div>
//Div to load data
<div id="dataload"><div>
Thanks in advance
You can close it when the ajax requests stop using the ajaxStop event, like this:
$(document).ajaxStop(function() {
$("#ajaxload").dialog("close");
});
When all concurrent jQuery AJAX requests finish, this event fires, and you can hide the dialog then. Another (same effect) format is to bind the event directly, like this:
$("#ajaxload").ajaxStop(function() {
$(this).dialog("close");
});

Resources