-1

I can't safe checkbox data with chrome.storage.sync for my options page in my new chrome plug-in. I have tried many ways to get this able to work; this is my most current one. I'm totally lost. Thanks in advance:

$(document).ready(function () {

  var storage = chrome.storage.sync;

  function load_options() {
    //Retrieve existing settings
    $("input[type=checkbox]").each(function() {
      $(this).prop('checked', function() {
        var name = $(this).parent().next().html();
        storage.get(name, function(items){
          element.checked = items[name];
        });
      });
    });
  }

  function saveSettings() {
    var checkboxes = $("input[type=checkbox]");
    var items = {};
    checkboxes.each(function (){
      var name = $(this).parent().next().html();
      items[name] = this.checked;
    });
    storage.set(items, function() {
      console.log("saved");
     });
} 

  //Factory settings pages class, load dynamic html
  function SettingsPageFactory(menuitem) {
    this.settingsFactoryItems = {
      Posts: 'settings/posts.html',
      Sidebar: 'settings/sidebar.html',
      General: 'settings/general.html',
      Privacy: 'settings/privacy.html'
    };

    this.keys = [];
    for (var key in this.settingsFactoryItems) {
      this.keys.push(key);
    }


    this.createSettingsPage = function () {
      var key = menuitem.find("a").html();
      currentPage = key;
      if ($.inArray(this.keys, key)) {
        $("#page-content-wrapper").html("");
        var url = chrome.runtime.getURL(this.settingsFactoryItems[key]);
        return url;
      }
    }

  }

  $("#wrapper").on("click", "a#safeman.btn.btn-info", function () {
    saveSettings();
  });

  $(".menuitem").on("click", function () {

    var settingsPageFactory = new SettingsPageFactory($(this));

    var url = settingsPageFactory.createSettingsPage();
    $("#page-content-wrapper").load(url + " .container-fluid");
    load_options();

    return false;

  });

The desired behaviour is just an options page with different pages which are loaded asynchronously. These contain checkboxes which kind of look like switches. When a switch is turned on or off this must be saved using the above API. Dynamical pages are all included in this main page:

<html lang="en">

<head>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, shrink-to-fit=no, initial-scale=1">
  <meta name="description" content="">
  <meta name="author" content="">

  <title>Faceblock - Settings Page</title>

  <!-- Bootstrap Core CSS -->
  <link href="css/bootstrap.min.css" rel="stylesheet">

  <!-- Switch checkbox -->
  <link href="css/switchbox.css" rel="stylesheet" />


  <!-- Custom CSS -->
  <link href="css/simple-sidebar.css" rel="stylesheet">
  <link href="css/options.css" rel="stylesheet">


</head>

<body>

  <div id="wrapper">

    <!-- Sidebar -->
    <div id="sidebar-wrapper">
      <ul class="sidebar-nav">
        <li class="sidebar-brand">

          <a href="options.html" style="text-align:center;margin-left:-30px;">
                        Settings
                    </a>
        </li>
        <li class="menuitem">
          <span class="glyphicon glyphicon-download-alt"></span><a href="posts">Posts</a>
        </li>
        <li class="menuitem">
          <span class="glyphicon glyphicon-indent-right"></span>

          <a href="sidebar">Sidebar</a>
        </li>
        <li class="menuitem"><span class="glyphicon glyphicon-eye-close"></span>

          <a href="privacy">Privacy</a>
        </li>
        <li class="menuitem">
          <span class="glyphicon glyphicon-check"></span>

          <a href="general">General</a>
        </li>
        <li class="menuitem">
          <span class="glyphicon glyphicon-eur"></span>
          <a href="donate">Donate</a>
        </li>
        <li class="menuitem">
          <span class="glyphicon glyphicon-cog"></span>
          <a href="settings">Settings</a>
        </li>
      </ul>
    </div>
    <!-- /#sidebar-wrapper -->

    <!-- Page Content -->
    <div id="page-content-wrapper">
      <div class="container-fluid">
        <div class="row content">
          <div class="col-lg-12">
            <a href="#menu-toggle" class="btn btn-black" id="menu-toggle">Toggle Menu</a>
            <h2>Faceblock Settings Page</h2>
            <p>Faceblock is a Chrome extension which filters all annoying adds on Facebook. It also gives you control over which content you would like to show or hide, and makes sure your privacy is kept secret to big companies.</p>
            <p>If you like our Chrome plugin, feel free to donate a small fee in order to keep future changes and features coming. <code>Choose a category from the right sidebar and start configuring Facebook according to your needs!</code></p>

          </div>
        </div>
      </div>
    </div>
    <!-- /#page-content-wrapper -->

  </div>
  <div id="dependencies" />

  <script src="js/jquery.min.js"></script>

  <!-- Bootstrap Core JavaScript -->
  <script src="js/bootstrap.min.js"></script>

  <script src="js/background.js"></script>

  <script src="js/options.js"></script>
  </div>
  <!-- /#wrapper -->



</body>

</html>

An example of a dynamically loaded page is found here:

<div class="container-fluid">
  <div class="row content">
    <div class="col-lg-12">
      <a href="#menu-toggle" class="btn btn-black" id="menu-toggle">Toggle Menu</a>

      <div class="container">
        <div class="col-lg-1 col-centered">


        </div>
        <h2>privacy</h2>
      </div>

      <p>Facebook stores unwanted data in the form of cookies and other ways to show you unwanted data you might like.<code>At this page you can tell Facebook to not store your private information and to not sell it to its third-party apps.</code></p>
      <div class="container">
        <div class="col-lg-1 col-centered">
          <label class="switch ">
  <input type="checkbox" checked>
  <div class="slider round"></div>

</label>
          <div class="lable">Disable cookies Facebook</div>
        </div>
      </div>


    </div>
  </div>
</div>

My manifest.json looks like this:

    {

      "name": "FaceBlock",
      "description": "This extention gets rid of unwanted content on Facebook like sponsored posts, adds or annoying suggestions. The content you wish to see is enlarged for a better and richer social experience.",
      "version": "0.0.1",
      "manifest_version": 2,
      "content_scripts": [
        {
          "matches": [
        "http://*.facebook.com/*", "https://*.facebook.com/*", "<all_urls>"],
          "css": ["css/popup.css"],
          "js": ["js/jquery.min.js", "js/content.js",
          "js/options.js",
          "js/background.js"],
          "run_at": "document_end",
          "all_frames": true
    }],
      "options_page": "options.html",
      "browser_action": {
        "default_icon": "icon.png",
        "default_popup": "popup.html",
        "default_title": "Faceblock"
      },
      "permissions": [
    "activeTab",
    "tabs",
    "https://www.facebook.com/*",
    "https://ajax.googleapis.com/",
    "storage",
    "<all_urls>"
  ],
      "background": {
        "scripts": ["js/background.js", "js/options.js"],
        "persistent": true
      },
      "options_ui": {
        // Required.
        "page": "options.html",
        // Recommended.
        "chrome_style": true
          // Not recommended; only provided for backwards compatibility,
          // and will be unsupported in a future version of Chrome (TBD).
          //"open_in_tab": true
      },
      "web_accessible_resources": [

    "images/faceblock.jpg",
    "images/seigaiha.png",
    "js/popup.js",
    "icon.png",
    "js/options.js",
    "css/popup.css",
    "popup.html",
    "options.html",
    "background.html",
    "js/background.js"
  ]
    }

As pointed out below, something might go wrong in my load_options()

Niels Vermeiren
  • 238
  • 3
  • 10
  • What *exactly* is shown in the [various appropriate consoles for your extension](http://stackoverflow.com/a/38920982/3773011) when you load and execute your extension? – Makyen Jan 19 '17 at 03:53
  • Please [edit] the question to be on-topic: include a **complete** [mcve] that *duplicates the problem*. Including a *manifest.json*, some of the background/content/popup scripts/HTML. Questions seeking debugging help ("**why isn't this code working?**") must include: ►the desired behavior, ►a specific problem or error *and* ►the shortest code necessary to reproduce it **in the question itself**. Questions without a clear problem statement are not useful to other readers. See: "**How to create a [mcve]**", [What topics can I ask about here?](http://stackoverflow.com/help/on-topic), and [ask]. – Makyen Jan 19 '17 at 03:54
  • @Mayek, currently no errors. Only saved is outputted, the problem is that my checkboxes are not in the saved state I left them in when I get back to them. An other problem is that he does not go further then the $("input[type=checkbox]").each(function() { in the load_options function. Also the savesettings function has mistakes, I can't retrieve the html without jQuery: var $name = $(this); $name.parent().next().html(); – Niels Vermeiren Jan 19 '17 at 06:47
  • I improved my changesettings to this: `function saveSettings() { var checkboxes = $("input[type=checkbox]"); var items = {}; checkboxes.each(function (){ var name = $(this).parent().next().html(); items[name] = this.checked; }); storage.set(items, function() { console.log("saved"); }); } ` – Niels Vermeiren Jan 19 '17 at 07:00
  • Maybe because it is called after the asynchronous load? – Niels Vermeiren Jan 19 '17 at 07:09

1 Answers1

0

The problem lied in the saving and retrieving of the persisted data. The solution is the following:

SaveSettings

  function saveSettings() {
    var checkboxes = $("input[type=checkbox]");
    var items = {};
    checkboxes.each(function (){
      var name = $(this).parent().next().html();
      items[name] = this.checked;
      storage.set(items, function() {
        console.log("saved a checkbox");
      });
    });
}

I converted some code to jQuery and made sure a checkbox was added per name to the items object and then persisted.

The second fault was a bit more complicated for me. Since I loaded my content asynchronously before loading the checkboxes on which I could load my persisted content, it was important for me to load the content first via a callback.

$("#page-content-wrapper").load(url + " .container-fluid", load_options);

The rest was simple, I changed javascript from the internet example into jQuery and made sure I retrieved the name of each checkbox which I then compared to the items being stored. The solution below could use some error handling though.

function load_options() {
    //Retrieve existing settings
    console.log($("input[type=checkbox]").length);
    $("input[type=checkbox]").each(function() {

        var checkbox = $(this);
        var name = checkbox.parent().next().html();

        storage.get(name, function(items){
            console.log(items);
            checkbox.prop('checked', items[name]);
        });
      });

  }
Niels Vermeiren
  • 238
  • 3
  • 10