Subjective Effect
Subjective Effect

Reputation: 1465

Getting values (settings) out of and back into a jQuery Mobile 1.4 form. How to do?

So this is the question I know I should have asked initially, here: How do I get these jQM 1.4 values out of a form with jQuery?

My issue is this - I have a settings panel that allows the user to choose age, gender and metric or imperial units. I store the settings in localStorage and whenever the user re-opens the application I want to pull them out of localStorage in order to implement them in the application.

This is the form

<form style="margin:0;padding:0;width:">                   
  <b>Age</b><br>        
  <input type="range" data-mini="true" data-highlight="true" name="ageview" id="ageview" min="0" max="99" value="30" >
  <p>                                                      
    <b>Gender</b><br>        
    <input type="checkbox" data-role="flipswitch" name="genderview" id="genderview" checked="" data-on-text="f" data-off-text="m" data-wrapper-class="custom-label-flipswitch" data-mini="true">                   
  <p>
    <b>Units</b><br>            
  <fieldset data-role="controlgroup" data-mini="true">        
    <input type="radio" name="unitsview" id="metric_units" value="metric" checked="">
    <label for="metric_units">cm &amp; kg</label>
    <input type="radio" name="unitsview" id="imp_units" value="imp">
    <label for="imp_units">inches &amp; lbs</label>          
  </fieldset>
</form>

When the user clicks the save button, with id="newsettings" this script runs

$("#newsettings").click(function(){
    age_set = $("#ageview").val();
    gender_set = $("#genderview:checked").length > 0 ? 'f' : 'm';
    units_set = $("input[name=unitsview]:checked").val();
    settingsObject = { "ageset" : age_set, "genderset" : gender_set, "unitset" : units_set} //put settings in an object
    localStorage.setItem('settings', JSON.stringify(settingsObject)); //store string in localSettings}
);

Thanks to Jack in the other thread for that.

The problem is I don't know how to put these changes BACK into the form. The only one I can get working is the Age, like this

$("#ageview").val(age_set);

I've tried both

$("input[name=unitsview]").val(units_set);

and

$("input[name=unitsview]:checked").val(units_set);

and neither does anything.

And I don't know where to start with the Gender.

I'm not asking for just the solution using my form set up. The slider input clearly works for the Age though. My question is twofold:

  1. Is there a way to easily insert the saved values? and
  2. If not, is there some other way I can capture these settings in the form? Are there other controls that are easier to manipulate?

Upvotes: 0

Views: 1371

Answers (3)

Subjective Effect
Subjective Effect

Reputation: 1465

Thanks for the feedback guys. I've been trying to reference my option in the select I'm using, like this.

$("#ageview").val(age);
if(gender == "f"){
    $("#genderview option[value='f_gender']").prop("selected", true).flipswitch( "refresh");
    $("#genderview option[value='m_gender']").flipswitch( "refresh");
} else{             
    $("#genderview option[value='m_gender']").prop("selected", true).flipswitch( "refresh");
    $("#genderview option[value='f_gender']").flipswitch( "refresh");
}   
if (units == "metric"){
    $("#metric_units").prop("checked", true).checkboxradio( "refresh" );
    $("#imp_units").checkboxradio( "refresh" );
} else {            
    $("#imp_units").prop("checked", true).checkboxradio( "refresh" );
    $("#metric_units").checkboxradio( "refresh" );
}

I just don't know how to reference these things in jQuery Mobile and the official docs confuse me :(

EDIT: And for an edit, here it is. This was so frustratingly easy.

$("#genderview").val(gender).flipswitch("refresh"); 

That's it.

2 days of struggle. :(

But I couldn't have done it without you guys. Thanks so much.

Upvotes: 0

Omar
Omar

Reputation: 31732

@ezanker's answer is correct in case values are stored in variables. However, when you use localStorage to save data and retrieve them later on, you cant use that method.

You need to save all data into an array, convert array into JSON string using JSON.stringfy(array) to be able to store it in localStorage.

To retrieve store data, JSON string should be parsed as JSON array in order to read values stored, using JSON.parse(localStorage).

  1. Step one:

    Loop through form elements, retrieve their type, value and id. Push each property into an array. Identifying type is a crucial step, based on it, element's value is retrieved. Moreover, type will be used in switch statement to update the form.

    var elements = []; /* array of data */
    
    $("#form_ID input").each(function () {
    
        /* type is either [type] or [data-role] */
        var elm_type = !! $(this).jqmData("role") ? $(this).jqmData("role") : $(this).prop("type");
    
        /* value is "string" or "boolean" */
        var elm_val = $(this).prop("type") === "checkbox" || $(this).prop("type") === "radio" ? $(this).prop("checked") : $(this).val();
    
        /* value will updated based on element's ID */
        var elm_id = "#" + $(this).prop("id");
    
        /* push data into elements array */
        elements.push({
            "type": elm_type,
                "value": elm_val,
                "id": elm_id
        });
    });
    /* array to string and save it */
    localStorage["info"] = JSON.stringify(elements);
    
  2. Step two:

    To read data stored in localStorage, it needs to be parsed first. Then loop through values and update form using switch statement.

    Why switch statement? Each widget in jQuery Mobile has it's own enhancement/update method. i.e. updating a value of a checkbox/radio button, .checkboxradio("refresh") should be used to re-apply styles on that element.

    Note that I have used .ui-page-active selector to target elements by their id in active page. This is a preventive measure as not to target elements in any other page. You can use same id but on two conditions; 1) don't use them on the same page. 2) use page's id selector to target them.

    /* string to array */
    var load_info = JSON.parse(localStorage["info"]);
    
    $.each(load_info, function (i, data) {
        switch (data.type) {
          case "number": /* slider */
              $(".ui-page-active").find(data.id).val(data.value).slider("refresh");
              break;
          case "flipswitch": /* flipswitch */
              $(".ui-page-active").find(data.id).prop("checked", data.value).flipswitch("refresh");
              break;
          case "radio": /* radio button */
              $(".ui-page-active").find(data.id).prop("checked", data.value).checkboxradio("refresh");
              break;
        }
    });
    

Demo (1)

(1) Do changes on form -> Save -> Next Page -> Load -> Voilà!

Upvotes: 1

ezanker
ezanker

Reputation: 24738

Here is a DEMO

$("#setVals").on("click", function(){
    var age = 32,
        gender = 'male',
        units = 'imp_units';

    $("#ageview").val(age);
    $("#genderview").prop("checked", gender == 'female').flipswitch( "refresh" );
    if (units == 'metric_units'){
        $("#unit_choice1").prop("checked", true).checkboxradio( "refresh" );
        $("#unit_choice2").checkboxradio( "refresh" );
    } else {            
        $("#unit_choice2").prop("checked", true).checkboxradio( "refresh" );
        $("#unit_choice1").checkboxradio( "refresh" );
    }
});

On the flipswitch you set the checked property to true or false and then call refresh on the widget. For the radio buttons, you set the checked property for the appropriate one and then call the widget refresh on both.

Upvotes: 1

Related Questions