0

Trying to get a jQuery Mobile button to behave like a toggle but it's not working fully. Trying to toggle between ui-body-a and ui-body-b. When I click the button, the page's colours change to dark. However when I click the button again, the page doesn't change back to light colours and is stuck on dark colours.

Whenever the button is clicked, I want the following to happen:

  1. If the colours are light, change them to ui-body-b (to show the dark colours), then change the button text to 'Light colours'
  2. Else if the colours are dark, change them to ui-body-a (to show the light colours), then change the button text to 'Dark colours'

HTML

<div data-role="header">
    <h1>Hello World</h1>
    <a href="index.html" id="btn-left" class="ui-btn-left" onclick="changeColour()">Dark colours</a>
</div>

JavaScript

function changeColour() {
    if ($("#page").attr("data-theme", "a")) {
        $("#page").attr("data-theme", "a");
        $("#page").removeClass("ui-body-a").addClass("ui-body-b");

        $("#btn-right").text("Light colours");
    } else if ($("#page").attr("data-theme", "b")) {
        $("#page").attr("data-theme", "b");
        $("#page").removeClass("ui-body-b").addClass("ui-body-a");

        $("#btn-right").text("Dark colours");
    }
}
wbk727
  • 8,017
  • 12
  • 61
  • 125
  • Big THX to [Omar](https://stackoverflow.com/users/1771795/omar)! You need to add to Your code the suggested fix in Omar's [answer](https://stackoverflow.com/a/16136992/4845566). – deblocker Feb 09 '18 at 07:54

1 Answers1

2

It depends from your page markup. TBH, I haven't understand if you try to create a whole theme switcher or just need to change the page background. Anyway, JQM has hard-coded overall the default theme "a" but offers a lot of possibilities to customize just only sections of the page, or even more single elements by applying the desired data-theme attribute just to one of them.

Moreover, please think what shall be if you are creating some elemnts dynamically? You should use the -inherit attributes to keep the same page theme, or set it explicitly (for instance, Popups).

Again, what if you navigate to an external page? Shall be styled or not...? So, it really depends from how your markup is, and what look and feel You are trying to achieve.

Here is an example how to change the theme of some page sections, You only need to keep the function toggleTheme():

function toggleTheme() {
  var themes = {"a":"Light","b":"Dark"},
  oldTheme = $(":mobile-page").page("option", "overlayTheme"),
  newTheme = oldTheme == "a" ? "b" : "a";

  $("div[data-role='page']").each(function(index) {
    $(this).removeClass("ui-page-theme-"+oldTheme).addClass("ui-page-theme-"+newTheme);
  });
  $(".ui-bar-"+oldTheme).each(function(index) {
    $(this).removeClass("ui-bar-"+oldTheme).addClass("ui-bar-"+newTheme);
  });
  $(".ui-body-"+oldTheme).each(function(index) {
    $(this).removeClass("ui-body-"+oldTheme).addClass("ui-body-"+newTheme);
  });

  $(":mobile-page").page("option", "overlayTheme", newTheme);
  $(":mobile-page").page("option", "theme", newTheme);
  $(":mobile-page").page("option", "contentTheme", newTheme);
 
  $("#btn-theme").text(themes[oldTheme]);
}

var all = [], current = {};

var listTemplate = [
  '<li class="ui-first-child ui-last-child">',
  '<a href="#page-card" data-id="{id}" class="ui-btn ui-btn-icon-right ui-icon-carat-r">',
  '<h2>{name}</h2>',
  '<p><strong>{address.city}</strong></p>',
  '<p>{email}</p>',
  '<p class="ui-li-aside">id: <strong>{id}</strong></p>',
  '</a>',
  '</li>'
].join("");

var cardTemplate = [
  '<h3 class="ui-bar ui-bar-inherit ui-corner-all">{name}</h3>',
  '<div class="ui-body ui-body-inherit ui-corner-all">',
  '<p>{email}</p>',
  '<p>{website}</p>',
  '<p>{phone}</p>',
  '<p>{address.street}</p>',
  '<p>{address.city}</p>',
  '</div>'
].join("");

function nano(template, data) {
  return template.replace(/\{([\w\.]*)\}/g, function(str, key) {
    var keys = key.split("."), v = data[keys.shift()];
    for (i = 0, l = keys.length; i < l; i++) { v = v[keys[i]]; }
    return (typeof v !== "undefined" && v !== null) ? v : "";
  });
}

$(document).on("vclick", "#page-list li>a", function() {
  var id = $(this).data("id");
  current = $.grep(all, function(item) {
    return item.id == id;
  })[0];
});

$(document).on("pagecreate", "#page-list", function() {
  var $ul = $(this).find("ul");
  $.ajax({
    url: "https://jsonplaceholder.typicode.com/users",
    method: 'GET',
    crossDomain: true,
    dataType: "jsonp",
    complete: function() {
      $ul.listview().listview("refresh");
    },
    success: function(result) {
      all = result;
      $.each(all, function(i, item) {
        $ul.append(nano(listTemplate, item))
      });
    }
  });
});

$(document).on("pagebeforeshow", "#page-card", function() {
  $(this).find("[data-role=content]").empty().append(nano(cardTemplate, current)).trigger("updatelayout");
});

$(document).on("vclick", "#btn-theme", function() {
 toggleTheme();
});
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
  <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css">
  <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
  <script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
</head>

<body>
  <div data-role="page" id="page-list">
    <div data-theme="a" data-role="header" data-position="fixed">
      <a href="#" id="btn-theme" class="ui-btn-left ui-btn ui-btn-inline ui-mini ui-corner-all ui-btn-icon-left ui-icon-eye">Dark</a>
      <h3>Users</h3>
    </div>
    <div data-role="content">
      <ul data-role="listview" data-inset="true" data-filter="true">
      </ul>
    </div>
  </div>
  <div data-role="page" id="page-card">
    <div data-theme="a" data-role="header" data-position="fixed">
      <h3>Details</h3>
      <a href="#" data-rel="back" class="ui-btn-left">Back</a>
    </div>
    <div data-role="content">
    </div>
  </div>
</body>

</html>

UPDATE:

This fix need to be added: https://stackoverflow.com/a/16136992/4845566 for a bug in the page widget (thanks to Omar).

deblocker
  • 7,629
  • 2
  • 24
  • 59