Jquery mobile: update theme for all forms immediately - jquery-mobile

Is it possible to change theme of all pages on the fly?
Example (code below and here) contains:
Single page template is used (each form is called via Ajax ).
Each form has back button
After applying chosen theme - all forms have to be updated to new theme. Only current form is updated in my example.
I`ve researched thoroughly before asking the question here but could not find an answer about theme rolling immediately for all forms, i.e.
Theme can be applied to all pages during "mobileinit" event
Theme can by applited to element
and so on
Thanks in advance
Html code:
<div data-role="page" data-theme="a" id="mainpage">
<div data-role="header" data-position="inline">
<h1>Name</h1>
Settings
</div>
<div data-role="content">
<ul data-role="listview" data-inset="true">
<li>
Requirements
</li>
</ul>
<input type="button" value="Button" />
</div>
</div>
<div data-role="page" data-theme="a" id="date-requirements" data-add-back-btn="true">
<div data-role="header" data-position="inline">
<h1>Requirements</h1>
</div>
</div>
<div data-role="page" data-theme="a" id="settings-page" data-add-back-btn="true">
<div data-role="header" data-position="inline">
<h1>Settings</h1>
</div>
<div data-role="content">
<div data-role="collapsible" id="skin-settings">
<h4>Skin</h4>
<ul data-role="listview">
<li>Dark</li>
<li>Blue</li>
<li>Grey</li>
<li>White</li>
<li>Yellow</li>
</ul>
</div>
</div>
</div>
JS code:
$(document).ready(function(){
// configure transition effect
$.mobile.changePage.defaults.allowSamePageTransition = true;
$.mobile.changePage.defaults.transition="slide";
// configure back button
$.mobile.page.prototype.options.addBackBtn = true;
$.mobile.page.prototype.options.backBtnText = "Back";
// set skin
$('#skin-settings').find('ul').children('li').bind('touchstart mousedown', function(e) {
var currentTextSkin= $.trim($(this).text());
var newTheme;
switch (currentTextSkin)
{
case "Dark":
newTheme="a";
break;
case "Blue":
newTheme="b";
break;
case "Grey":
newTheme="c";
break;
case "White":
newTheme="d";
break;
case "Yellow":
newTheme="e";
break;
default:
newTheme="a";
}
var rmbtnClasses = '';
var rmhfClasses = '';
var rmbdClassess = '';
var arr = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" ];
$.each(arr,function(index, value){
rmbtnClasses = rmbtnClasses + " ui-btn-up-"+value + " ui-btn-hover-"+value;
rmhfClasses = rmhfClasses + " ui-bar-"+value;
rmbdClassess = rmbdClassess + " ui-body-"+value;
});
// reset all the buttons widgets
$.mobile.activePage.find('.ui-btn').not('.ui-li-divider').removeClass(rmbtnClasses).addClass('ui-btn-up-' + newTheme).attr('data-theme', newTheme);
// reset the header/footer widgets
$.mobile.activePage.find('.ui-header, .ui-footer').removeClass(rmhfClasses).addClass('ui-bar-' + newTheme).attr('data-theme', newTheme);
// reset the page widget
$.mobile.activePage.removeClass(rmbdClassess).addClass('ui-body-' + newTheme).attr('data-theme', newTheme);
// target the list divider elements, then iterate through them and
// change its theme (this is the jQuery Mobile default for
// list-dividers)
$.mobile.activePage.find('.ui-li-divider').each(function(index, obj) {
$(this).removeClass(rmhfClasses).addClass('ui-bar-' + newTheme).attr('data-theme',newTheme);
});
});
});

Solution given by #Omar is mostly correct but new created objects (on demand) inherit default theme, so code below change default style both already created and oncoming objects
$(document).ready(function(){
// configure transition effect
$.mobile.changePage.defaults.allowSamePageTransition = true;
$.mobile.changePage.defaults.transition="slide";
// configure back button
$.mobile.page.prototype.options.addBackBtn = true;
$.mobile.page.prototype.options.backBtnText = "Back";
// set skin
$('#skin-settings').find('ul').children('li').bind('touchstart mousedown', function(e) {
var currentTextSkin= $.trim($(this).text());
var newTheme;
switch (currentTextSkin)
{
case "Dark":
newTheme="a";
break;
case "Blue":
newTheme="b";
break;
case "Grey":
newTheme="c";
break;
case "White":
newTheme="d";
break;
case "Yellow":
newTheme="e";
break;
default:
newTheme="a";
}
var rmbtnClasses = '';
var rmhfClasses = '';
var rmbdClassess = '';
var arr = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" ];
$.each(arr,function(index, value){
rmbtnClasses = rmbtnClasses + " ui-btn-up-"+value + " ui-btn-hover-"+value;
rmhfClasses = rmhfClasses + " ui-bar-"+value;
rmbdClassess = rmbdClassess + " ui-body-"+value;
});
// reset all the buttons widgets
$.mobile.activePage.find('.ui-btn').not('.ui-li-divider').removeClass(rmbtnClasses).addClass('ui-btn-up-' + newTheme).attr('data-theme', newTheme);
// reset the header/footer widgets
$.mobile.activePage.find('.ui-header, .ui-footer').removeClass(rmhfClasses).addClass('ui-bar-' + newTheme).attr('data-theme', newTheme);
// reset the page widget
$.mobile.activePage.removeClass(rmbdClassess).addClass('ui-body-' + newTheme).attr('data-theme', newTheme);
// target the list divider elements, then iterate through them and
// change its theme (this is the jQuery Mobile default for
// list-dividers)
$.mobile.activePage.find('.ui-li-divider').each(function(index, obj) {
$(this).removeClass(rmhfClasses).addClass('ui-bar-' + newTheme).attr('data-theme',newTheme);
});
// change default theme
// Page
$.mobile.page.prototype.options.headerTheme = newTheme; // Page header only
$.mobile.page.prototype.options.contentTheme = newTheme;
$.mobile.page.prototype.options.footerTheme = newTheme;
// Navigation
$.mobile.page.prototype.options.backBtnTheme = newTheme;
// Listviews
$.mobile.listview.prototype.options.headerTheme = newTheme; // Header for nested lists
$.mobile.listview.prototype.options.theme = newTheme; // List items / content
$.mobile.listview.prototype.options.dividerTheme = newTheme; // List divider
$.mobile.listview.prototype.options.splitTheme = newTheme;
$.mobile.listview.prototype.options.countTheme = newTheme;
$.mobile.listview.prototype.options.filterTheme = newTheme;
// dateboxes
$.mobile.datebox.prototype.options.theme=newTheme;
$.mobile.datebox.prototype.options.themeHeader=newTheme;
// timemode
$.mobile.datebox.prototype.options.themeButton=newTheme;
$.mobile.datebox.prototype.options.themeInput=newTheme;
// calendar mode
$.mobile.datebox.prototype.options.themeDateToday=newTheme;
$.mobile.datebox.prototype.options.themeDayHigh=newTheme;
$.mobile.datebox.prototype.options.themeDatePick=newTheme;
$.mobile.datebox.prototype.options.themeDateHighAlt=newTheme;
$.mobile.datebox.prototype.options.themeDate=newTheme;
});
});

Related

Is it possible to transclude the tab content?

Is it possible to create a tab with either HTML content or move the element directly to the content?
Here is what I am trying to do, ultimately, i want to just move existing element(s) inside the tab content:
HTML
<body ng-controller="MainCtrl">
<div class="container">
<tabset ui-sortable="sortableOptions" ng-model="tabs">
<tab class="tab" ng-repeat="tab in tabs" sortable-tab heading="{{tab.title}}">{{tab.content}}</tab>
</tabset>
<button type="button" ng-click="addSimple()">Add simple</button>
<button type="button" ng-click="addHtml()">Add html</button>
<button type="button" ng-click="addElement()">Add element</button>
<button type="button" ng-click="removeTab()">Remove tab</button>
</div>
</body>
JS
var app = angular.module('plunker', ['ui.bootstrap', 'ui.sortable']);
app.controller('MainCtrl', function($scope) {
var count = 0;
$scope.sortableOptions = {
distance: 10,
axis: 'x',
update: function(event, ui) {
// $scope.activeTab = ui.item.sortable.dropindex;
}
};
$scope.tabs = [
{title:'Test', content:'hello world'},
];
$scope.addSimple = function() {
count++;
var newTab = {title: 'New tab ' + count, content: 'Works'};
$scope.tabs.push(newTab);
}
$scope.addHtml = function() {
count++;
var newTab = {title: 'New tab ' + count, content: '<div>Broken</div>'};
$scope.tabs.push(newTab);
}
$scope.addElement = function() {
count++;
var newTab = {title: 'New tab ' + count, content: angular.element('<div>Broken</div>')};
$scope.tabs.push(newTab);
}
$scope.removeTab = function() {
$scope.tabs.pop();
}
});
Plunkr
It's already transcluded, but if you want to inject HTML, you'll have to use ngBindHtml (requires ngSanitize as a dependency).
Updated Plunker
Add angular-sanitize.js make sure ngSanitize is added as a dependency:
var app = angular.module('plunker', ['ui.bootstrap', 'ui.sortable', 'ngSanitize']);
Change your markup to add ng-bind-html:
<tab class="tab" ng-repeat="tab in tabs" sortable-tab heading="{{tab.title}}">
<div ng-bind-html="tab.content"></div>
</tab>
Then you can pass html directly:
{title: 'New tab ' + count, content: '<strong>Works with <span class="red">ngBindHtml</span></strong>'}
Or, using the angular.element html() method to grab the element object's html:
{title: 'New tab ' + count, content: angular.element('<div>Broken</div>').html()}

JQuery UI Autocomplete and hidden field

I have implemented the JQuery UI Autocomplete widgets in my form so when the user selects an item from the autocomplete, a hidden field is populated with the id and the textbox with the user friendly text.
I have also implemented a remote validation so if the user after selecting an item from the list (hidden field already set) decides to delete or change the text it will fail and force the user to select an item again.
I do want to allow the user to delete the field so if all content of the textbox is deleted I want to reset the hidden field, but I don't know how to do this...
Thanks in advance.
Typically, you can catch certain events on the input field that is the Autocomplete widget. The main ones would be blur where the input field loses focus and or keyup where someone has hit enter inside the input field (maybe trying to submit the form).
The following example shows how a "hidden" field could be updated in these two scenarios:
$(function() {
var availableTags = [
"ActionScript",
"AppleScript",
"Asp",
"BASIC",
"C",
"C++",
"Clojure",
"COBOL",
"ColdFusion",
"Erlang",
"Fortran",
"Groovy",
"Haskell",
"Java",
"JavaScript",
"Lisp",
"Perl",
"PHP",
"Python",
"Ruby",
"Scala",
"Scheme"
];
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$( "#tags" )
// don't navigate away from the field on tab when selecting an item
.bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
})
.autocomplete({
minLength: 0,
source: function( request, response ) {
// delegate back to autocomplete, but extract the last term
response( $.ui.autocomplete.filter(
availableTags, extractLast( request.term ) ) );
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
terms.push( "" );
this.value = terms.join( ", " );
$("#hiddenField").val(terms.join( ", "));
return false;
}
});
});
$("#tags").blur(function() {
$("#hiddenField").val(this.value);
});
$("#tags").keyup(function (e) {
if (e.keyCode == 13) {
$("#hiddenField").val(this.value);
}
});
.hiddenFields {
margin-bottom: 30px;
}
.hiddenF {
color: gray;
}
.hiddenI {
color: gray;
border: 1px dotted gray;
opacity: 50%;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<div class="hiddenFields">
<label for="hiddenField" class="hiddenF">Hidden Field: </label>
<input id="hiddenField" class="hiddenI" size="50" readonly/>
</div>
<div class="ui-widget">
<label for="tags">Tag programming languages: </label>
<input id="tags" size="50">
</div>

how to use infowindow (google map API) to get back the ID of the selected location

I am displaying a list of locations (that i get through ViewBag for now) on a map and ask the user to choose one of them.
I have populated my infowindows with HTML code by looping through the list of locations.
now when the user clicks on one of the buttons in the infowindow ("Choose this one"), I want to update the view model (Venue) to include Venue.Id = the choosen location and submit back to the controller so update the database. how can I do such a thing ?
thanks a lot for your help.
here is my script code:
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<section class="scripts">
<script type="text/javascript">
$(document).ready(function () {
Initialize();
});
function Initialize() {
google.maps.visualRefresh = true;
var rabat = new google.maps.LatLng(34.019657, -6.831833);
var mapOptions = {
zoom: 11,
center: rabat,
mapTypeId: google.maps.MapTypeId.G_NORMAL_MAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var list =
#Html.Raw(Json.Encode(((IEnumerable<KayenChiMVC.Models.Venue>)ViewBag.TheVenue).Select(v => new
{
venueId = v.VenueID,
venueName = v.Name,
venueDistrict = v.District,
venueType = v.SurfaceType,
venueLat = v.Latitude,
venueLon = v.Longitude
})
));
var infowindow = new google.maps.InfoWindow();
for(var i=0; i<list.length;i++){
var pos = new google.maps.LatLng(list[i].venueLat, list[i].venueLon);
var html = "<table>" +
"<tr><td>Nom:</td>" + "<td> " + list[i].venueName +" </td> </tr>" +
"<tr><td>Quartier:</td>" + "<td> " + list[i].venueDistrict +" </td> </tr>" +
"<tr><td>Type de surface:</td>" + "<td> " + list[i].venueType +" </td> </tr>" +
"<tr><td></td><td><input type='button' value='Choisir ce terrain' onclick=''/></td></tr>";
createMarker(pos, list[i].venueName, html);
function createMarker(pos,title, html){
var marker = new google.maps.Marker({
'position': pos,
'map': map,
'title': list[i].venueName
});
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/red-dot.png');
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(html);
infowindow.open(map, marker);
});
}
}
}
</script>
</section>
Add a data-id attribute to your input to hold the venue id.
<input id="myButton" type="button" data-id="123" value="Choose this one" />
and get the data-id attribute in javascript
document.getElementById('myButton').onclick = function() {
console.log(this.getAttribute('data-id')); // will log '123'
};

Break a string and merge string in c# with show and hide options

My Requirement:
My string should be break after some words and at place we need to place "+more" option. when user click the "+more" need to show entire text. after end of the text need to show "-hide". when user click the "-hide" then it should be show previous. means some text with "+more" option. can any one help this.
my code:
var fullString= "string with above 150 charecters here";
var compressedString = TotalNews.fullString(150);
<div class="Temphide">
#compressedString
</div>
<a class="show" id="#newsItem.ApplicationNewsId">+More</a>
var Continues = fullString.Substring(150, TotalNews.Length - 150);
<div style="display:none;" >
#fullString <a class="hide">-Hide</a>
</div>
script:
<script type="text/javascript">
$(document).ready(function () {
$('.show').click(function () {
$(this).next('div').slideToggle();
});
$('.hide').click(function () {
$(this).parent().slideUp();
});
});
</script>
My problem:
Here when i click "+more" option i am showing "+more" with "-hide". requirement is when click "+more" need to show fullstring with "-hide" option. but i am doing showing "+more" and "-hide". please can any one help this.
Script:
$.fn.truncate = function(options) {
$(this).append('<span class="truncate_lh" style="display:none;"> </span>')
var defaults = {
maxlines: 2,
moreText: 'More',
lessText: 'Less',
ellipsis: '...'
};
$.extend(options, {
lineheight: ($('.truncate_lh').css('height').replace('px', ''))
});
$.extend(options, {
maxheight: (options.maxlines * options.lineheight)
});
options = $.extend(defaults, options);
return this.each(function() {
var text = $(this);
if (text.height() > options.maxheight) {
text.css({
'overflow': 'hidden',
'height': options.maxheight + 'px'
});
var link = $('' + options.moreText + '');
var wrapDiv = $('<div class="truncate_wrap" />');
text.wrap(wrapDiv);
text.after(link);
link.click(function() {
if (link.text() == options.moreText) {
link.text(options.lessText);
text.css('height', 'auto');
} else {
link.text(options.moreText);
text.css('height', options.maxheight + 'px');
}
return false;
});
}
});
};
$().ready(function() {
$('.truncate').truncate( {
maxlines: 4
});
});
View
<p class="truncate">//Here text...</p>
I have done this with help of
http://jsfiddle.net/Pjgzq/1/
visit this link

Allowing user to add option to the drop down list in asp.net MVC

In my MVC application have included a button called form Field. whenever user clicks on that button dropdownlist gets displayed in modal box that contains text, checkbox etc as option.
function Select_type(box) {
var tp = document.getElementById('Type').value;
switch (tp) {
case "Text":
{
var editor = CKEDITOR.instances.message;
editor.insertHtml('<input type="text" id="tx" />');
}
break;
case "Checkbox":
{
var editor = CKEDITOR.instances.message;
editor.insertHtml(' <input type="checkbox" id="chk" name="chk" />');
}
break;
case "Radio":
{
var editor = CKEDITOR.instances.message;
editor.insertHtml('<input type="radio" id="rd" name="rd" />');
}
break;
case "DropDown":
{
var ediotr = CKEDITOR.instances.message;
ediotr.insertHtml('<select id="options"></select>');
dhtmlx.modalbox({
title: "Form Field Properties",
text: "<div id='form_in_box'><div ><label>Field Options:<input id='txt'></label><br></div><div><span class='dhtmlx_button'><input type='submit' value='Add' style='width: 86px' onclick='Add_type(this)'></span><span class='dhtmlx_button'><input type='button' value='Cancel' onclick='close_file(this)' style='width:80px;'></span></label></div></div>",
width: "300px"
});
}
break;
case "Listbox": alert("Listbox");
break;
}
dhtmlx.modalbox.hide(box);
}
When user selects drop down option a modal box appears that allows the user to add option to the drop down list
function Add_type(box) {
var txt = $('#txt').val();
if (txt.length > 0) {
$("#options").append("<option value='" + (txt.length - 1) + "'>" + txt + "</option>")
}
}
Textarea and button appears in modal box but it doesn't add the options that user has entered in textarea
function Add_type() {
var txt = $('#txt').val();
if (txt.length > 0) {
var lBox = $('select[id$=options]');
$(lBox ).append("<option value=' " + (txt.length - 1) + " '>" + txt + "</option>")
}
}
I tried like this, it was working

Resources