jQuery mobile radio list with data-type="horizontal" fails in dynamic form - jquery-mobile

Here is an example HTML page that demonstrates the issue:
<!DOCTYPE html>
<html>
<head>
<title>My Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.css" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.1.1/jquery.mobile-1.1.1.min.js"></script>
</head>
<body>
<div data-role="page">
<div data-role="header">
<h1>My Title</h1>
</div><!-- /header -->
<div data-role="content" id="cp">
<form id="form">
<div data-role="fieldcontain">
<fieldset data-role="controlgroup" data-type="horizontal" data-mini="true">
<legend>Test 1:</legend>
<input type="radio" name="r1" id="r1a" value="none" checked="checked" /><label for="r1a">A</label>
<input type="radio" name="r1" id="r1b" value="detail"/><label for="r1b">B</label>
<input type="radio" name="r1" id="r1c" value="measure"/><label for="r1c">C</label>
</fieldset>
</div>
</form>
</div><!-- /content -->
</div><!-- /page -->
<script type="text/javascript">
$(document).ready(function() {
var form = $('#form');
form.append('<div data-role="fieldcontain">');
form.append(' <fieldset data-role="controlgroup" data-type="horizontal">');
form.append(' <legend>Test 2:</legend>');
form.append(' <input type="radio" name="r2" id="r2a" value="none" checked="checked" /><label for="r2a">A</label>');
form.append(' <input type="radio" name="r2" id="r2b" value="detail"/><label for="r2b">B</label>');
form.append(' <input type="radio" name="r2" id="r2c" value="measure"/><label for="r2c">C</label>');
form.append(' </fieldset>');
form.append('</div');
form.trigger('create');
});
</script>
</body>
</html>
Save this page and load it in a borwser. You will see that the "Test 1" radio list comes up horizontal (as it should because of the data-type="horizontal" attribute). However the "Test 2" radio list, which is added dynamically, comes up vertically, which is the default setting. It seems the data-type="horizontal" has no effect on the dynamically created radio list.
Is there a refresh or event anyone knows about which I should trigger somewhere in the DOM to get this to work?

The problem is the way you are adding your new elements to the form. If you change your javascript function to this you'll see that it works:
$(document).ready(function() {
var form = $('#form');
var newElement = '';
newElement += '<div data-role="fieldcontain" data-type="horizontal">';
newElement += ' <fieldset data-role="controlgroup" data-type="horizontal">';
newElement += ' <legend>Test 3:</legend>';
newElement += ' <input type="radio" name="r3" id="r3a" value="none" checked="checked" /><label for="r3a">A</label>';
newElement += ' <input type="radio" name="r3" id="r3b" value="detail"/><label for="r3b">B</label>';
newElement += ' <input type="radio" name="r3" id="r3c" value="measure"/><label for="r3c">C</label>';
newElement += ' </fieldset>';
newElement += '</div>';
form.append(newElement);
form.trigger('create');
});
Think about it this way: Each time the append() function is used the browser attempts to add whatever you've given it to the DOM. But because you have broken your elements across different calls to append() the browser has to try to make sense of it. So when you have this:
form.append('<div data-role="fieldcontain">');
The browser sees that you've left off a closing div tag and tries to fix it for you by adding it. This means your next call to append() will not go inside the div you just added but after it because the browser has automatically closed it for you.
You should add complete, well-formed elements to avoid this issue.

Related

when submit button is click the input data has been disappear how can I rectify?

when submit button is clicked the input data is disappear in html How can I rectify the problem?
<html>
<head>
<title>hhhh</title>
</head>
<body>
<form id="form">
<input type="text" id="username" placeholder="username" />
<input type="submit" id="btn" />
</form>
</body>
<script>
var a = document.getElementById("username");
var b = document.getElementById("btn");
b.addEventListener("click", () => {
console.log(a.value);
});
</script>
</html>

Render html form into main html page using AngularJS app method

I am very new to AngularJS and trying to understand how AngularJS can use along with ASP.NET-MVC5 application. In my first attempt I want to run AngularJS app from basic HTML page (in my case index.html) where app holding form template in html format, also I have add global variable, controller, service via factory and directives but I cannot manage to run this app 'employee-form' inside index.html. In order to test if angularJS is initialize and working properly, I have added very basic angularjs code inside in html and it works.. I am not sure where I have done mistake
AngularFormsApp.js (global variable)
var angularFormsApp = angular.module('angularFormsApp', []);
efController.js
angularFormsApp.controller('efController',
function efController($scope, efService) {
$scope.employee = efService.employee;
});
efService.js
angularFormsApp.factory('efService',
function () {
return {
employee: {
fullName: "Khurram Zahid",
notes: "The ideal employee, just don't mess with him",
department: "IT Development",
perkCar: true,
perkStock: false,
perkSixWeeks: true,
payrollType: "none"
}
}
});
efDirective.js
angularFormsApp.directive('employeeForm',
function () {
return {
restrict: 'E', //E stands for element, meaning we want to use this directive as element
templateUrl: '~/App/EmployeeForm/efTemplate.html'
}
});
efTemplate.html (form)
<div class="form-group">
<label for="fullName">Name</label>
<input type="text" id="fullName" name="fullName" class="form-control" />
</div>
<div class="form-group">
<label for="notes">Notes</label>
<input type="text" id="notes" name="notes" class="form-control" />
</div>
<div class="form-group">
<label for="department">Department</label>
<select id="department" name="department" class="form-control">
<option>Engineering</option>
<option>Marketing</option>
<option>Finance</option>
<option>IT Development</option>
</select>
</div>
<br/>
<span><b>Perks</b></span>
<div class="checkbox">
<label><input type="checkbox" value="perCar"/>Company Car</label>
</div>
<div class="checkbox">
<label><input type="checkbox" value="perkStock" />perk Stock</label>
</div>
<div class="checkbox">
<label><input type="checkbox" value="perkSixWeeks" />perk Six Weeks</label>
</div>
<input type="submit" value="Submit Form" />
index.html
<!DOCTYPE html>
<html>
<head >
<title>Angular JS</title>
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<script src="Scripts/angular.min.js"></script>
<script src="App/AngularFormsApp.js"></script>
<script src="App/EmployeeForm/efController.js"></script>
<script src="App/EmployeeForm/efService.js"></script>
<script src="App/EmployeeForm/efDirective.js"></script>
</head>
<body ng-app="angularFormsApp">
<div class="AngularJSTestBlockCode">
<div>
<input type="text" ng-model="name" />
<br />
<h1>Hello {{name}}</h1>
</div>
<br /><br />
<div>
{{458/8}}
</div>
</div>
<div>-------------------------------------------------------</div> <br/><br/>
<div ng-controller="efController">
<employee-form>????????????????????
</div>
You need a route provider to render your html page. Here is your example
.config(['$stateProvider',function($stateProvider) {
$stateProvider.state('dashboard', {
url:'/dashboard',
templateUrl: 'views/dashboard/main.html',
})
.state('dashboard.create-example',{
templateUrl:'views/example/create.html',
url:'/create-example',
controller:'Ctrl'
})
then in your controller(efController.js) put this $state.transitionTo('dashboard.create-example'); to render your page to any html you want

Handling sessions for the new/edit process in jquery mobile

Having one html file called index.html.Here I'm having one page for list view(group).Another one(pg_add-group) is for both new and edit view.
If I hit the Add button from list view,the new form opened correctly.If I select any of the product from list view,its correctly uploaded the details to the edit view.
Its done by getting date from session.Now if I again try to add product, its containing old session data in the new form.The new form should contain with empty details.Can you help me to do this ?
Here is my coding,
pg_add-group
<div id="pg_add-group" data-role="page">
<form name="frm_add-group" id="frm_add-group" action="" method="post">
<div data-role="header" data-transition="fixed">
<h1 id="add-group-header"></h1>
Back
</div>
<div data-role="main" class="ui-content" >
<div id="add_sms-group_notification" class="center-wrapper-error" data-icon="right"></div>
<label for="group_name" class="ui-hidden-accessible"></label>
<input type="text" name="group_name" id="group_name" placeholder="Enter Group Name" />
<label for="group_desc" class="ui-hidden-accessible"></label>
<textarea name="group_desc" id="group_desc" placeholder="Enter Group Decription"></textarea>
<div class="containing-element">
<label for="group_published">Published</label>
<select name="group_published" id="group_published" data-theme="b">
<option value="1" >Yes</option>
<option value="0" >No</option>
</select>
<input type="hidden" name="group_id" id="group_id" />
</div>
<div class="containing-element">
<button type="submit" name="submit" value="submit" data-theme="a" data-icon="check">Submit</button>
<button type="reset" name="reset" value="reset" data-theme="a" data-icon="delete" >Reset</button>
</div>
<div data-role="footer" data-position="fixed">
<h1 id='add-book-footer'></h1>
</div>
</form>
</div>
test.js
From he below coding
group_id is comes from the list view's selected group id.
session data ses_group contains the list of groups.
$('#pg_add-group').on('pageshow', function(event) {
var group_list = $.parseJSON(sessionStorage.getItem("ses_group"));
var group_id = sessionStorage.group_id;
$.each(group_list, function(ctr, obj) {
if(group_id == obj.groupid){
$('input[id=group_name]').val(obj.groupname);
$('textarea[id=group_desc]').val(obj.groupdesc);
$('input[id=group_id]').val(obj.groupid);
$("#group_published").val('0').slider('refresh');
}
});
$( ".input[id=group_name]" ).textinput( "refresh" );
$( ".textarea[id=group_desc]" ).textinput( "refresh" );
});
Working example: http://jsfiddle.net/Gajotres/2AVWQ/
Usage:
Take a look at provided code, every element used has a custom attribute called data-default-value, it is used to determine which element is a default one. Basically use provided code to reset any form.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>jQM Complex Demo</title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
<meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.css" />
<!--<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>-->
<script src="http://code.jquery.com/mobile/1.4.2/jquery.mobile-1.4.2.min.js"></script>
</head>
<body>
<div data-role="page" id="index" data-theme="a" >
<div data-role="header">
<h3>
First Page
</h3>
Next
</div>
<div data-role="content">
<input type="button" id="clr-form-btn" value="Clear form"/>
<label for="basic">Text Input:</label>
<input type="text" name="name" id="basic" value="Some value"/>
<label for="flip-1">Flip switch:</label>
<select name="flip-1" id="flip-1" data-role="slider" data-default-value="off">
<option value="off">Off</option>
<option value="on">On</option>
</select>
<fieldset data-role="controlgroup">
<legend>Choose a pet:</legend>
<input type="radio" name="radio-choice" id="radio-choice-1" value="choice-1"/>
<label for="radio-choice-1">Cat</label>
<input type="radio" name="radio-choice" id="radio-choice-2" value="choice-2" checked="checked" data-default-value=""/>
<label for="radio-choice-2">Dog</label>
<input type="radio" name="radio-choice" id="radio-choice-3" value="choice-3" />
<label for="radio-choice-3">Hamster</label>
<input type="radio" name="radio-choice" id="radio-choice-4" value="choice-4" />
<label for="radio-choice-4">Lizard</label>
</fieldset>
<label for="select-choice-0" class="select">Shipping method:</label>
<select name="select-choice-0" id="select-choice-0" data-default-value="standard">
<option value="standard">Standard: 7 day</option>
<option value="rush">Rush: 3 days</option>
<option value="express">Express: next day</option>
<option value="overnight">Overnight</option>
</select>
<textarea>
asd
asd
asd
as
das
d
asdassd
</textarea>
</div>
<div data-role="footer" data-position="fixed">
</div>
</div>
</body>
</html>
Javascript:
$(document).on('pagebeforeshow', '#index', function(){
cleanForm();
});
function cleanForm() {
var page = $.mobile.activePage;
// Reset input elements
page.find('.ui-content *').filter("[type='text'],textarea").each(function(){
$(this).val('');
});
// Reset drop down elements
page.find('.ui-content *').filter(".ui-select").each(function(){
var select = $(this).find('select');
var defaultValue = select.attr('data-default-value');
select.val(defaultValue);
select.selectmenu('refresh', true);
});
// Reset flip switch elements
page.find('.ui-content *').filter('[data-role="slider"]').each(function(){
var flipSwitch = $(this);
var defaultValue = flipSwitch.attr('data-default-value');
flipSwitch.val(defaultValue);
flipSwitch.slider('refresh');
});
// Reset radio elements
page.find('.ui-content *').filter('fieldset:has([type="radio"])').each(function(){
var radio = $(this);
var checkedRadio = radio.find(':checked').prop("checked",false).checkboxradio("refresh");
var defaultRadio = radio.find('[data-default-value]').prop("checked",true).checkboxradio("refresh");
});
}

Using fixed footer with Jquery mobile + phonegap on android

I am building a phonegap app for Android using jquery mobile and having some
trouble with fixed footers.
Please see the HTML code below.
<!DOCTYPE HTML>
<html>
<head>
<title>Test</title>
<script type="text/javascript" charset="utf-8" src="cordova-2.0.0.js">
</script>
<script type="text/javascript" src="js/jquery-1.7.min.js">
</script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/jquery.mobile-1.1.1.min.css" />
<script src="js/jquery.mobile-1.1.1.min.js"> </script>
</head>
<body>
<div data-role="page" id="home">
<div data-role="header" data-position="fixed"
data-tap-toggle="false">
<h1>Test</h1>
</div><!-- /header -->
<div data-role="content">
<form id="searchform" action="" method="post" onsubmit="return false;"
data-ajax="false">
<label for="city" class="select">City</label>
<select name="city" class="city"></select>
<label for="city" class="select">City</label>
<select name="city" class="city"></select>
<label for="city" class="select">City</label>
<select name="city" class="city"></select>
<label for="city" class="select">City</label>
<select name="city" class="city"></select>
<label for="city" class="select">City</label>
<select name="city" class="city"></select>
<label for="city" class="select">City</label>
<select name="city" class="city"></select>
<label for="city" class="select">City</label>
<select name="city" class="city"></select>
<label for="city" class="select">City</label>
<select name="city" class="city"></select>
</form>
<script type="text/javascript">
$('.city').each(function() {
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
$(this).append("<option>Nagpur</option>");
});
</script>
</div><!-- /content -->
<div data-role="footer" data-position="fixed"
data-tap-toggle="false">
<div data-role="navbar" data-iconpos="left">
<ul>
<li><a href="#help" data-icon="info"
data-transition="none">Help</a></li>
<li><a href="#help" data-icon="star"
data-transition="none" >Favorites</a></li>
<li><a href="#help" data-icon="arrow-r"
data-transition="none" >Results</a></li>
</ul>
</div>
</div>
</div><!-- /page -->
<div data-role="page" id="help">
<div data-role="header" data-position="fixed"
data-tap-toggle="false">
<h1>Help</h1>
</div><!-- /header -->
</div>
</div>
</body>
</html>
There is a long form containing several fields including checkboxes, radio buttons, select lists etc. (using repeated select lists here to simulate). There is a fixed footer at the bottom. Things work fine on desktop browsers. But when I test on my phone having Android 2.3 I observe strange behaviour. Assuming the footer is hiding the select list underneath , if I click on any of the tabs on the navbar, the select list pops up whereas I would expect a transition to a new page. This is as if the select list is getting the click event instead of the footer. This is very annoying to the user. I have searched google but haven't seen this problem reported elsewhere.
Updated the solution yet again.
/* HACK: when clicked on navbar the select list underneath pops up
for some reason. So we just hide all content as soon as
we click on navbar and then show it whenever we load new page*/
$(document).bind('pagechange', function(e, data) {
$('[data-role="content"]').show();
});
$(document).bind('tap', function(e) {
if($("body").data("hold-flag") == true) {
$("body").data('hold-flag', false);
return;
}
if($(e.target).closest("[class='ui-btn-inner']").length > 0 ||
$(e.target).closest("[class~='ui-btn-right']").length > 0 ||
$(e.target).closest("[class~='ui-btn-left']").length > 0) {
$('[data-role="content"]').hide();
}
});
$(document).bind('taphold', function(e) {
/* set a flag to mark this as a taphold event */
/* BIG assumption: a 'tap' event is always fired after a
taphold event */
$("body").data('hold-flag', true);
e.preventDefault();
return false;
});
I found a workaround. I added following code. Essentially I am testing whether there has been click in the footer area. If yes then I simply hide the contents of the page. This seems to stop the annoying pop-up select list. Of course the hidden page contents must be restored after page transition is complete. I am not sure how portable and/or robust this code is. Would appreciate comments from experienced developers.
$(document).bind('pagechange', function(e, data) {
$('[data-role="content"]').show();
});
$(document).bind('tap', function(e) {
/* find the footer for this page*/
var footer = $(e.target).
closest('[data-role="page"]').
find('[data-role="footer"]');
var offset = footer.offset();
var scroll = e.pageY - e.clientY;
var pos = offset.top - scroll;
if(e.clientY > pos) {
//click in footer area
$('[data-role="content"]').hide();
}
});
Simplified 'tap' event handler. This also handles clicks in header area now.
$(document).bind('tap', function(e) {
if($(e.target).closest("[data-role='footer']").length > 0 ||
$(e.target).closest("[data-role='header']").length > 0) {
$('[data-role="content"]').hide();
}
});

On-click jquery mobile

I need some sort on onclick function for my jquery mobile/php website. The following on-click wont work...
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
_END;
$int = 0;
foreach (array_slice($list,1) as $value) {
echo <<<_END
<input type="checkbox" name="checkbox-$int" id="checkbox-$int" class="custom" />
<label for="checkbox-$int">$value</label>
_END;
$int = $int+1;
}
echo <<<_END
</fieldset>
<script type="text/javascript" >
$(".checkbox-1").click(function(){
alert('clicked!');
});
</script>
</div>
_END;
Your jQuery is using a class selector, you need to update to it used an ID selector to match the output.
Replace
$(".checkbox-1").click
with
$("#checkbox-1").click

Resources