Restore Checkbox State from Dictionary - javascript

I am storing form data in json format. To allow changing values from a previously created json file, the (plain old javascript) function below will load the values into a form from a file. This method will restore the value of drop down lists but not with a checkbox.
I have tried storing the value of the checkbox ('on' or 'off') and the checked state ('true' or 'false') but neither works out of the box.
Also, I tried adding an if statement before the return, like so:
if (newArr[dataItem] === "true") {
document.getElementById(newArr[dataItem]).click();
} else {
return (inputItem.id === dataItem) ? (inputItem.value = newArr[dataItem]) : false;
}
Here is a stripped down version of the function that works to restore values:
function receivedText(e) {
let lines = e.target.result;
var newArr = JSON.parse(lines);
Object.keys(newArr).map(function (dataItem) {
inputs.map(function (inputItem) {
return (inputItem.id === dataItem) ? (inputItem.value = newArr[dataItem]) : false;
});
});
}
The json data would look like this:
{ "foo": "ws", "bar": "ws", "checkbox_value": "on", "other_data": "apple" }
So in short, when loading data from a file and evaluating the json dictionary, the checkbox_value does not seem to select or deselect the checkbox.

You need to update the checked attribute, and it needs to be set to the booleans true and false, not the strings. You should store the checked attribute as a boolean in the JSON. To load the values, consider the following code:
Object.keys(newArr).map(function (dataItem) {
var inputItem = document.getElementById(dataItem);
if (inputItem.type === "checkbox") {
inputItem.checked = newArr[dataItem];
} else {
inputItem.value = newArr[dataItem];
}
});

Related

How to retrieve multiple select values from sessionStorage and put them into the original form field

I want to store values from a form input field that has a tags input functionality using select multiple and automatically retrieve them back after the form was sent. Basically, what I am trying to achieve is to just keep them in the input field after form submission. With them being tags, this adds convenience to the user since you can just add/delete some of the inputs and reload the page.
I have successfully written a piece of code that stores the array in sessionStorage after clicking the submit button, where pmids[]is the id of the select element:
function store() {
var select = document.getElementById('pmids[]');
var pmids = [...select.options]
.filter(option => option.selected)
.map(option => option.value);
sessionStorage.setItem("pmids", JSON.stringify(pmids));
}
I am struggling with getting the values back into the form field though, this attempt does not seem to work:
var storedPmids = JSON.parse(sessionStorage.getItem("pmids"));
if (storedPmids !== null) {
document.getElementById("pmids[]" options).each(function() {
for (var i = 0; i < storedPmids.length; i++) {
if (this.value == storedPmids[i]) {
this.selected = true;
}
}
});
}
Speaking of this line:
document.getElementById("pmids[]" options)
This is not how you access the options of a <select> element. Instead you should call:
document.getElementById("pmids[]").options
Furthermore, each is a jQuery method. The vanilla JS equivalent of each is forEach, which, in fact, only works with arrays and nodelists. Hence you need to convert your options collection into an array first:
var options = Array.from(document.getElementById("pmids[]").options);
Finally, this inside forEach refers to the window object, so you need to use a callback function with a parameter. Full code:
var storedPmids = JSON.parse(sessionStorage.getItem("pmids"));
if (storedPmids !== null) {
var options = Array.from(document.getElementById("pmids[]").options);
options.forEach(function(option) {
for (var i = 0; i < storedPmids.length; i++) {
if (option.value == storedPmids[i]) {
option.selected = true;
}
}
});
}

localStorage returns as undefined but works with console

I wrote a JavaScript file which reads history from localStorage and logs it to the console. The value of the key history is a string array which looks somthing like this:
[
{
"dateCreated": 1624953025609,
"link": "localhost/97a4",
"uri": "google.com"
}
]
and as expected the key/value also shows up in the Application DevTools tab. I can also access the array in the console after JSON.parse()ing it like:
JSON.parse(localStorage.getItem("history"))[0].dateCreated;
// 1624953025609
.
However, another JS file which looks like
function checkLocalStorage() {
if (typeof localStorage !== 'undefined') {
try {
localStorage.setItem('feature_test', 'yes');
if (localStorage.getItem('feature_test') === 'yes') {
localStorage.removeItem('feature_test');
return true;
} else {
return false;
}
} catch (e) {
return false;
}
} else {
return false;
}
}
var isEnabledLocalStorage = checkLocalStorage();
if (!isEnabledLocalStorage) {
$('<p></p>').append("Your browser doesn't support <b>localStorage</b> or it is disabled.<br><b>localStorage</b> is required to view your history.")
} else {
var history = JSON.parse(localStorage.getItem("history"))[0];
document.write(history.dateCreated);
}
writes undefined to the document. How do I get the value of a nested object from the history localStorage key?
It is undefined because in your else statement, you call your variable history, but that already exists: window.history
So instead of saving the parsed JSON, it fails to overwrite and when you retrieve the dateCreated property, it doesn't exist on window.history.
Just rename your variable to something like saved_history.

ComboBox typeAhead works but valueField is null under certain behavioral conditions

Requesting a sanity check here please...
ExtJS 4.2 comboBox Typeahead works but having issues retrieving the valueField under the following conditions:-
1) If a user types a value and then instead of hitting enter or clicking on the select combo list, they click elsewhere then the valueField is empty but the selected value is present.
2) Assuming that the combobox item was selected correctly, If I enter an additional character and then backspace that character, the combo box can no longer find the valueField..its almost like it has reset itself.
Fiddle example
https://fiddle.sencha.com/#fiddle/je1
How to reproduce
If you enter Maggie in the combo box, you will see the valueField ID in the console window, if you append a character and then backspace the character, the ID in the console window is null
(You will need to open the console window to see the output)
forceSelection does not resolve this issue as I have a template and it will not accept an entry in the combobox that is not part of the store, and I need to use sumID for my valueField as I need to retrieve and pass that value to the server.
Thank you everyone, awesome to have such a great community!!
I was able to get around this by using forceSelection and overriding the setValue thus allowing template items not in the store but in the combo to be selected via forceSelection. From playing around with the combobox, IMO, for a good look and feel, forceSelection is the way to go.
Here is my override, refer to statement //start of override
This was a quick fix, I will refine statement when I am back in the office, below I am pasting the solution from memory, you get the idea.
setValue: function(value, doSelect) {
var me = this,
valueNotFoundText = me.valueNotFoundText,
inputEl = me.inputEl,
i, len, record,
dataObj,
matchedRecords = [],
displayTplData = [],
processedValue = [];
if (me.store.loading) {
// Called while the Store is loading. Ensure it is processed by the onLoad method.
me.value = value;
me.setHiddenValue(me.value);
return me;
}
// This method processes multi-values, so ensure value is an array.
value = Ext.Array.from(value);
// Loop through values, matching each from the Store, and collecting matched records
for (i = 0, len = value.length; i < len; i++) {
record = value[i];
if (!record || !record.isModel) {
record = me.findRecordByValue(record);
}
// record found, select it.
if (record) {
matchedRecords.push(record);
displayTplData.push(record.data);
processedValue.push(record.get(me.valueField));
}
// record was not found, this could happen because
// store is not loaded or they set a value not in the store
else {
//start of override
// 'Select All Names' is the template item that was added // to the combo box, it looks like an entry from the store
// but it is not in the store
if (me.forceSelection && me.getDisplayValue() === 'Select All Names'){
processedValue.push(value[i]);
dataObj = {};
dataObj[me.displayField] = value[i];
displayTplData.push(dataObj);
}
//end of override
if (!me.forceSelection) {
processedValue.push(value[i]);
dataObj = {};
dataObj[me.displayField] = value[i];
displayTplData.push(dataObj);
// TODO: Add config to create new records on selection of a value that has no match in the Store
}
// Else, if valueNotFoundText is defined, display it, otherwise display nothing for this value
else if (Ext.isDefined(valueNotFoundText)) {
displayTplData.push(valueNotFoundText);
}
}
}
// Set the value of this field. If we are multiselecting, then that is an array.
me.setHiddenValue(processedValue);
me.value = me.multiSelect ? processedValue : processedValue[0];
if (!Ext.isDefined(me.value)) {
me.value = null;
}
me.displayTplData = displayTplData; //store for getDisplayValue method
me.lastSelection = me.valueModels = matchedRecords;
if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
inputEl.removeCls(me.emptyCls);
}
// Calculate raw value from the collection of Model data
me.setRawValue(me.getDisplayValue());
me.checkChange();
if (doSelect !== false) {
me.syncSelection();
}
me.applyEmptyText();
return me;
},
Look at the sources of Combobox and try override this method as follows
doLocalQuery: function(queryPlan) {
var me = this,
queryString = queryPlan.query;
if (!me.queryFilter) {
me.queryFilter = new Ext.util.Filter({
id: me.id + '-query-filter',
anyMatch: me.anyMatch,
caseSensitive: me.caseSensitive,
root: 'data',
property: me.displayField
});
me.store.addFilter(me.queryFilter, false);
}
if (queryString || !queryPlan.forceAll) {
me.queryFilter.disabled = false;
me.queryFilter.setValue(me.enableRegEx ? new RegExp(queryString) : queryString);
}
else {
me.queryFilter.disabled = true;
}
me.store.filter();
if (me.store.getCount()) {
if (me.rawValue === me.lastSelection[0].get(me.displayField)){
me.setValue(me.lastSelection);
} else {
if(me.store.getCount() === 1){
me.setValue(me.store.first());
}
me.expand();
}
} else {
me.collapse();
}
me.afterQuery(queryPlan);
},

Pass values into session.php

I'm trying to pass some values into session.php.
Below is my code. type_oq is a dropdown menu. I want to save certain values if the dropdown selection is equal to "fruit".
The problem: Not sure what is the problem. No errors shown. The php file path is accurate. Button click works. My guess is that there might be a syntax error in the if condition?
$('#goBtn').click(function(){
alert("done!");
$.post('sessions.php',
{
if ($('#type_oq').val() == "fruit") {
a:$('#a_oq').val(),
b:$('#b_oq').val(),
}
from:$('#from_oq').val(),
to:$('#to_oq').val(),
radioG:$('#radioGroup').val()
} ,
function(response) {
$('#postrequest').html(response);
});
});
I would create the data object outside the $post and then just pass it as a variable:
$('#goBtn').click(function(){
alert("done!");
var data = {
from:$('#from_oq').val(),
to:$('#to_oq').val(),
radioG:$('#radioGroup').val(),
// If a and b are required then create them here with empty values.
a: "",
b: ""
};
if ($('#type_oq').val() == "fruit") {
data.a = $('#a_oq').val();
data.b = $('#b_oq').val();
};
$.post('sessions.php', data, function(response) {
$('#postrequest').html(response);
});
});
Just to be extra clear, it turns out that you can't use conditions inside of the object creation, e.g. this wouldn't work:
var data = {
if (true) {
a:"a",
}
b: "b"
};

Javascript validation. What am I not passing after the .val using values

how is my values not passing for ajax using trim and val. The issue is that when I check it using trim and val the values get check if there was anything typed if there is nothing then it sends to validation false if there is something it will hide the validate. All works bu the values do not make it and I get a new row without values. What am I missing from my function to pass my values. Here is the code:
var validation = "";
var values = {};
if ($.trim($("#name").val()) === "") {
$("#validateName").show();
validation = "false";
} else {
$("#validateName").hide();
}
if ($.trim($("#news").val()) === "") {
$("#validateNews").show();
validation = "false";
} else {
$("#validateNews").hide();
}
if(validation == "false"){
return false;
}
values['addnews'] = '';
$.ajax({
// Rest of the code //
This is how it was previously passed. Here is the code:
$.each($('#add-news-form').serializeArray(), function(i, field) {
if((field.value == 0)){
validation = "false";
}
values[field.name] = field.value;
});
What am I missing from my ajax function to pass the values?
If you want to assign the name input text to the values object, you can do it like so:
values['name'] = $.trim($("#name").val());
Ideally you shouldn't have this trim statement twice, you should store the trimmed value in a variable and use that variable in both your validation and assignment sections.
Then make sure you're passing 'values' in the data param of your ajax call:
$.ajax({
data: values
// rest of your ajax code
});

Categories

Resources