Storing user highlighted rows using HTML5 localStorage - javascript

I have a javascript function that adds a table row id each time a user highlights a row to an array and then also removes that corresponding id from the array when the user unhighlights that same row.
Each row has a unique id field.
I have been trying to using localStorage to remember what row(s) the user has highlighted in the array over multiple sessions so that if they close the browser and come back later I can read from that array and automatically highlight the previously highlighted rows.
I am getting stuck on how to get the localStorage part of it to remember the array as from my reading
of localStorage, it doesn't supports arrays only strings. All I need to do is store an array of numbers to read from each time I load the page.
var selectedTeams = [];
var teamIndex;
$('#leaderboard').on('click', 'tr', function() {
if($(this).hasClass('highlight')){
$(this).removeClass('highlight')
teamIndex = selectedTeams.indexOf(this.getAttribute('id'))
selectedTeams.splice(teamIndex,1)
}
else {
$(this).addClass('highlight')
selectedTeams.push(this.getAttribute('id'))
}
});
Any suggestions on where to go from here would be appreciated.
Cheers

For a simple example, you'd do something like this (which Dave alluded to).
Assuming you have done all your checks for valid localStorage capability.
var someArray = ['<tr><td>test 3</td></tr>','<tr><td>test</td></tr>','<tr><td>test 3</td></tr>']
window.localStorage.setItem('mySavedArray',JSON.stringify(someArray));
then to get it:
JSON.parse( window.localStorage.getItem('mySavedArray') );

Related

How to access an entered Interactive Grid column value in a Javascript dynamic action on the Change event in order to ensure uniqueness

I am trying to prevent duplicate items from being entered in an Interactive Grid in Oracle Apex 20.2. I do get a unique constraint error when this happens, but this is for a barcode scanning stock control app and the unique constraint error only happens when saving after scanning a room with lots of objects. It is then very difficult to find the duplicate field. You also cannot use sort, since that wants to refresh the page and looses all your scanned items. I cannot presort because I want the last scanned item on top.
I was able to add Javascript on page load that creates an array with all the barcodes. I then check this array when scanning and do not add new Interactive Grid rows when a duplicate barcode is going to be added to the array.
In addition to this I need to add the same for when an Interactive Grid row is manually entered. For this I wanted to add a Javascript dynamic action on the barcode column in the Interactive Grid, in order to once again check the global array for uniqueness. However I have several issues: I cannot figure out how the get the entered barcode value in the change dynamic action Javascript, sometimes it shows the previous changed value (might be this bug although I am in 20.2) and the Change event also seems to fire twice when hitting enter after entering a value (once for the new row (this time my code works unlike when hitting Tab) and once for the next row below). The last one seems bad, since then it will try to check existing values (the next row) and give errors that should not happen; however I do not see a more appropriate event like On Row Submit. Not sure if there is a way to check whether the value changed on the Change event.
The code I currently have I got from here. I am assuming this means Oracle Apex does not have a standard way of getting an Interactive Grid column value in a Javascript dynamic action. Not sure if this has changed in 20.2 or 21. The code I have is:
console.log($(this.triggeringElement));
var grid = apex.region('LINES').widget().interactiveGrid('getViews', 'grid');
var model = grid.model;
var selectedRow = grid.view$.grid('getSelection');
var id = $(selectedRow[0][0]).data('id');
var record = model.getRecord(id);
let bcode = model.getValue(record, 'BARCODE');
console.log(id);
console.log(record);
console.log($(selectedRow[0][0]));
console.log(bcode);
if(barcodes.includes(bcode)) {
apex.message.showErrors([{
type: "error",
location: "page",
message: "The entered barcode is already in the list.",
unsafe: false
}]);
}
When I console.log(record) I can see values that I enter into the barcode column, but I do not know how to walk the object tree in order to retrieve the value out of the record. I do not understand the object it shows me in the console log. It does not seem to correlate with the dot access traversals that others are doing in the above code. I can see the record array at the top, but for that the barcode column shows the previous value; below that it does however show the newly entered value as the third (2) index, but I do not know how to write Javascript to access that.
If I can access the previous and new value from the record object I could check for changes and also compare the new value against the global array. How do I access these values in the record object or is there a better way of achieving my goal? bcode prints the previous value, so I guess I already have that if that is not a bug.

activating checkbox on load with javascript or jQuery

hello I have a small project I'm working on.
the project is calling an API with ajax and getting info about currencies, one of the things I'm stuck on is that I have to write them in cards that include a checkbox that has to stay activated after I refresh the page.
any suggestions?.. please I'm desperate
When you make your call on your API just set the checked value on the correct checkbox, please have in mind that setting checked=false will still give you a checked checkbox.
<input type="checkbox" checked>
One way to preserve information against a page refresh is to use localStorage.
LocalStorage allows you to store key:value variable pairs in the local browser. You can view the localStorage values for any given website in DevTools F12, on the Application tab. The variables are stored by website, and remain as they are until (a) they are deleted, or (b) browser cache is cleared. (For more info on when localStorage is cleared, see this answer).
LocalStorage is dead-simple to use:
let myPet = 'Cat';
localStorage.setItem('animal', myPet);
And to read it:
let myPet = localStorage.getItem('animal');
What you might want to do in your project, perhaps on a timer - or after the ajax call - is loop through your fields and create an object with all the fieldnames/values. Then use JSON.stringify to turn the object into text that you can store in a localStorage variable.
Note that you will need to write something that on page load ( $(document).ready() ) will see if the fields are empty and if there is a RECENT localStorage variable (so, you might want to create second localStorage variable (you can have MANY) that has the last-updated datetime) then you read the JSON string into a javascript object and populate your field values.
I would recommend using a dictionary, putting something unique like an ID of those currencies that are checked at that time.
If the new answer you get has the same currencies as before plus more, you can use that dictionary in memory to check those items again. If you don't get the previous response, you can just add those new items to avoid unchecking the checked currencies.
Exmaple:
var dictionary = {};
// here you should do a forEach in currently checked currencies
...
dictionary[id] = value; // (true, because it is the value of checked)
Hope it helps you.

jQuery DataTables getting hidden column data

I have one table where I have 2 columns that get hidden by the dataTables api. From which when I delete a row from the table I need to pass the data in these columns via ajax so that it gets removed from the database as well..
I have been deleting my rows prior that didn't have data I need in them directly, without any issue. Now I need to change it up for this need and catch those values. Problem is no matter how I have tried to spin it one thing or another breaks.
delete_row = $(this).closest("tr").get(0);
This is what I used to catch the row I want to delete to pass it along when confirmation of deleting the row is made. And that works fine. Now I need to match the logic in creating two new vars that can be read if confirmation is made to pass through my ajax call.
Which I have tried:
var aPos = throttleTable.fnGetPosition($('td:eq(0)', delete_row));
var aData = throttleTable.fnGetData(aPos[0]);
Along with a few different spins to catch the column I want to get the data from. The above breaks the script altogether. The thought came from
var aPos = throttleTable.fnGetPosition(throttle_delete_row);
var aData = throttleTable.fnGetData(aPos[0]);
Which does work but only in returning every column in that row as a string. Which isn't desired. I would run a loop over it but that is problematic as a loop can be expensive, and also there is no distinct method of splitting the data up, as one of the values in one of the hidden columns is a CSV in it of itself. So the loop would be invalid for the need there as well if I split and delimited it by ,
So my ultimate question is, how can I break it down to get column specific?
Well, alright then. Apparently the problem was I was attempting to do to much when all I needed was the fnGetData() bit.
Turns out after playing around with whats actually going on and dumping it all into the console.log() I was able to sort out that all I truly needed to do was throttleTable.fnGetData(throttle_delete_row, 0) for sake of example, to get the hidden column(s) I seek.
$(document).ready(function() {
$('#example tbody td').click( function () {
// Get the position of the current data from the node
var aPos = oTable.fnGetPosition( this );
// Get the data array for this row
var aData = oTable.fnGetData( aPos[0] );
});
返回的都是数组,获取数组对应的下标就可以了!

How to save 4 drop down list selections to a cookie, and set drops if cookie present

So I am using jQuery and have setup the jquery cookie plugin.
I have 4 drop down lists on my page, and I want to save the user's selections in a cookie, so when they come back to the page I automatically pre-select their previous selections.
I added a class to all my drop downs "ddl-cookie", and I was just thinking if I could somehow loop through all the drop down lists using the class, and save the selection and also loop to set the selections when the user returns to the page.
$(".ddl-cookie").each(function() {
});
It seems that given a cookie name, I can save a single key/value in the cookie.
So I'm guessing the only way for me to do this would be to have a comma separated list of drop down list names and values (selection value)?
You are correct. Cookies are intended to store a single piece of data, so the most common way to handle this is to serialize your data into an easy to retrieve format. That format is up to you, but you might use something like:
field_1=value1&field_2=value&...
You might want to also encode this data--remember that cookies are transferred as part of the request header. The pseudo code would go something like this:
// Store the data, using your own defined methods
data = serialize_data(data);
data = encode_data(data);
cookie = data;
// Retrieve the data using your own defined methods
data = cookie;
data = unencode_data(data)
data = deserialize_data(data)

storing and retrieving 100-element array

I am using Greasemonkey/Tampermonkey to visit pages and make a change to a 100-element table based on what's on the current page.
Short term storage and array manipulation works fine, but I want to store the data permanently. I have tried GM_getValue/GM_setValue, GM_SuperValue, localStorage, and indexedDB, but I am clearly missing something fundamental.
Nothing seems to allow me to write the array into the permanent storage and then read it back into a variable where I can access each element, such that variablename[32] is actually the 32nd element in the table (Well, 33rd if you start counting at zero, which I do).
I need access to the entire 100-element table while the script is running, because I need to output some or all of it on the page itself. In the most basic case, I have a for loop which goes from 0 to 99, printing out the value of variablename[i] each time.
I have no predisposition to any method, I just want the frickin' thing to work in a Greasemonkey/Tampermonkey script.
Towards the top of the script I have this:
for (var i = 0; i <= 99; i++) {
currentData[i] = localStorage.getItem(currentData[i]);
}
The purpose of the above section is to read the 100 entries into the currentData array. That doesn't actually work for me now, probably because I'm not storing things properly in the first place.
In the middle, after modifying one of the elements, I want to replace it by doing this:
localStorage.setItem(
currentData[specificElementToChange], differentStuff);
The purpose of the above is to alter one of the 100 lines of data and store it permanently, so the next time the code at the top is read, it will pull out all 100 entries, with a single element changed by the above line.
That's the general principle.
I can't tell if what I'm doing isn't working because of some security issue with Firefox/Chrome or if what I want to do (permanently storing an array where each time I access a given page, one element changes) is impossible.
It's important that I access the array using the variable[element] format, but beyond that, any way I can store this data and retrieve it simply is fine with me.
I think you're going about this wrong. LocalStorage stores strings so the simplest way to store an array in LocalStorage is to stringify it into JSON and store the JSON. Then, when reading it back, you parse the JSON back into an array.
So, to read it in, you do this:
var currentData = JSON.parse(localStorage.getItem("currentData") || "[]");
To save your data, you do this:
localStorage.setItem("currentData", JSON.stringify(currentData));
Working demo: http://jsfiddle.net/jfriend00/6g5s6k1L/
When doing it this way, currentData is a variable that contains a normal array (after you've read in the data from LocalStorage). You can add items to it with .push(), read items with a numeric index such as:
var lastItem = currentData[currentData.length - 1];
Or, change an item in the array with:
currentData[0] = "newValue";
Of course, it's just a normal array, so you can use any array methods on it.

Categories