Load single property of a class async - javascript

I'm bulding a dynamic UI and I have a "ul" list that needs to load a single value from the db per "li". A sort of badge that display a count from the db.
Following is a bit of code:
function A {
var count;
function buildItem() {
//some code to build a list "li" item
};
this.setCount = function(number) {
count = number;
};
this.getHtml = function() {
buildItem();
return html;
};
};
function B {
var ul;
var container = [];
function loadCount(ref, i) {
//ajax call that should set count for class A
$.ajax({
//blabla
container[i].setCount(jsonResult);
});
};
this.buildList = function() {
//code that build the list..
};
};
What I need is that loadCount() assign the value retrieved from the db before or at the same time the script is parsed. Using an asynchronous request populate the count after the list is displayed.
How can I populate my A class count with the value taken from the db and after display the entire list ?

Hide your ul until you receive the counts for all your li elements. Display a loader during the time of loading.
var nResponses = 0;
$.ajax( "example.php" )
.done(function(msg) {
addLi(msg); //Add an li element to the ui
if (liCount === nResponses) //Check if all the responses are received. liCount is the number of lis you have
showUl(); //Everything is good. Show the ui
else
nResponses++; //Increase the response count
})

Related

Delete div by /{id} json-server

I've written a Todo task app, using JSON-Server, to manage the REST routing.
I've uploaded my code here:
https://codesandbox.io/s/json-server-i5hv5
Problem I'm having, is that when I click on a todo task, I want to delete only that DIV by {id}, from the database.
However, the delete function only works, if you click on the last div added. And even then, it deletes all {id}'s in the DB and divs on the page, rather than the single div, I've clicked on.
Struggling to make this work.
I want to only delete the div I click on. And I only want that div to be removed in the DB, by it's allocated id={id}.
This is the click function in question:
document.getElementById('id').addEventListener('click', function(event)
{
event.preventDefault();
console.log('clicked');
var divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; i++) {
var id = divs[i].getAttribute('id');
divs[i].parentElement.removeChild(divs[i]);
fetchService.deleteTodoTask(id);
}
});
Any approaches/tips, would be grateful!
I got this working, by changing the way I'm accessing the DOM element on click. And the below code seems to work well.
I'm them passing the grabbed ID on click, into fetchService.deleteTodoTask(id).
Which is where the delete REST route is being handled:
const list = document.querySelector('.js-todo-list');
list.addEventListener('click', event => {
if (event.target.classList.contains('js-delete-todo')) {
const itemKey = event.target.parentElement.dataset.key;
const id = itemKey;
var elem = document.getElementById(id);
elem.parentNode.removeChild(elem);
fetchService.deleteTodoTask(id);
}
});
function deleteTodoTask(id) {
const options = {
method: 'DELETE'
};
return fetch(`${url}/${id}`, options);
}

Cordova navigator.app.backHistory button on html different approach

I'm building hybrid app with Intel XDK and I need help with back button and it's function. I have only one index.html file. All "pages" are 's and each one have different id.
I navigate through them using activate_subpage("#uib_page_10");
$(document).on("click", ".firs_div_button", function(evt){
//#uib_page_10 is div with it's content
activate_subpage("#uib_page_10");
var thisPage = 1;
goBackFunction (thisPage); //call function and pass it page number
});
$(document).on("click", ".second_div_button", function(evt){
//#uib_page_20 is div with it's content
activate_subpage("#uib_page_20");
var thisPage = 2;
goBackFunction (thisPage); //call function and pass it page number
});
I have set this EventListener hardware on back button.
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
alert("hello");
navigator.app.backHistory();
}
This is functional but it does not work as it should, in my case and for my app.
When I navigate from one page to another (5 pages / divs) and hit back button, sometimes it does not go back to the first page. It just go "back" to history too deep and close the app, without changing the actual page (view) before closing.
Now, I have an idea, but I need help with this.
I will not use history back, I will use counter and dynamic array for up to 5 elements.
function goBackFunction (getActivePage) {
var active_page = getActivePage;
var counter = 0; // init the counter (max is 5)
var history_list = [counter][active_page]; // empty array
counter = counter + 1;
:
:
:
}
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
//read the array and it's positions then activate:
activate_subpage("#PAGE_FROM_ARRAY");
counter = counter - 1;
if (counter == 0) {
//trigger the app exit when counter get's to 0.
navigator.app.exitApp();
}
}
This is only idea, not tested. I would like to store list of opened pages in Array and when back button is pressed, to activate the pages taken from the Array list, backwards.
I do not know how to do this, I'm not a expert :( There is may be batter way to do this. If someone have any suggestion, I will accept it :D
I save an array in localStorage with all pages navigated and I go back using a pop() on the array. At the moment, it's the best way I got to go back.
This is my code:
// First, create the table "pages"
function init_pages_table()
{
var pages = new localStorageDB("pages", localStorage);
if (!pages.isNew())
{
pages.drop();
pages.commit();
}
var pages = new localStorageDB("pages", localStorage);
pages.createTable("Pages", ["nome"]);
// commit the database to localStorage
// all create/drop/insert/update/delete operations should be committed
pages.commit();
}
// Add a page into the array:
function push_pagename(pagename)
{
var pages = new localStorageDB("pages", localStorage);
if (!pages.tableExists("Pages"))
{
init_pages_table();
pages = new localStorageDB("pages", localStorage);
}
pages.insert("Pages", {nome: pagename});
pages.commit();
}
// Pop a page form the array:
function pop_pagename()
{
var output = '';
var id_page = ''
var pages = new localStorageDB("pages", localStorage);
var last_page = pages.queryAll("Pages", { limit: 1,
sort: [["ID", "DESC"]]
});
$.each(last_page, function(index,value){
output = value.nome;
id_page = value.ID;
return false;
});
var rowdeleted = pages.deleteRows("Pages", {ID: id_page});
pages.commit();
return output;
}
You can also define functions for set, get, read:
function set_backpage(pageurl)
{
push_pagename(pageurl);
}
function get_backpage()
{
return pop_pagename();
}
function read_backpage()
{
var output = '';
var id_page = ''
var pages = new localStorageDB("pages", localStorage);
var last_page = pages.queryAll("Pages", { limit: 1,
sort: [["ID", "DESC"]]
});
$.each(last_page, function(index,value){
output = value.nome;
id_page = value.ID;
return false;
});
return output;
}

Print values associated with checkboxes in HTML on button click event of JavaScript

Planning to get the specific ID values from the selection on the HTML page (selection here means checked boxes). Here is my code for a button click event(button will fetch the row numbers or ids):
$("a", button).click(function () {
$('#groups').find('tr').each(function () {
var row = $(this);
if (row.find('input[type="checkbox"]').is(':checked')) {
console.log($(this));
}
});
});
This returns addtional information on rows + tr tag, however, I just want the ID part of it. Here is sample output I am getting out of above code:
[tr#row-12150.row.oddSelected, context: tr#row-12150.row.oddSelected]
[tr#row-12151.row.evenSelected, context: tr#row-12151.row.evenSelected]
This means I have selected 12150 and 12151 out of the #groups table. How do I just pull the row numbers 12150 and 12151 and not the entire detailed output and I want this to store in an array/(JS array) for multiple row numbers.
You have the row as per the .find('tr'), your should just be able to go:
console.log($(this).attr('id')); //this should show the id in your console.
so your code becomes:
$("a", button).click(function () {
$('#groups').find('tr').each(function () {
var row = $(this);
if (row.find('input[type="checkbox"]').is(':checked')) {
console.log($(this).attr('id'));
}
});
});
Then to just get the number you can use:
var number = $(this).attr(id).split('-')[1] //assuming it's always row-<<some number>>
putting it all together:
$("a", button).click(function () {
$('#groups').find('tr').each(function () {
var row = $(this);
if (row.find('input[type="checkbox"]').is(':checked')) {
var number = $(this).attr('id').split('-')[1] //assuming it's always row-<<some number>>;
console.log(number);
}
});
});
To store it in an array:
$("a", button).click(function () {
var checkedRows = []; //define empty array.
var count = 0; //keep a counter to use for the array.
$('#groups').find('tr').each(function () {
var row = $(this);
if (row.find('input[type="checkbox"]').is(':checked')) {
var number = $(this).attr('id').split('-')[1];
checkedRows[count] = number; //add the number to our array.
count++; //increase the count
}
});
});
Make sure your form and your button have id's first then try this instead:
$('#buttonId').click(function(){
$('#formId input:checked').each(i, e){
console.log($(e).attr('id'));
}
});

How to save the checkbox state even after the page refresh?

I have multiple checkboxes on my UI which when checked doing some operation. But the moment I refresh the page all the check boxes are unchecked again. How can I use AJS.Cookie (Atlassian Javascript framework) to save the state. Source Code which I have written but it gives the cookie value as undefined.
'#generate-canvas-button' is the id of the button which passes all the checked checkboxes.
// Wait until the page is completely loaded.
AJS.$(document).ready(function() {
// Iterating over all checkboxes on page.
$('input:checkbox').each(function() {
// Getting checkbox name.
var name = $(this).attr('name');
// Checking saved cookie.
if (AJS.Cookie.read(name)) {
// Updating checkbox state.
$(this).prop('checked', true);
}
});
// Clicking the OK button should run submit(), pop up displays all checked boxes
$('#generate-canvas-button').click(submit);
});
function submit() {
var checked = [];
var targetGroupActors = [];
var bigPictureActors = [];
var bigPictureImpacts = [];
var productDetailsActors = [];
var productDetailsDeliverable = [];
// Iterating over all checkboxes on page.
$('input:checkbox').each(function() {
// Getting checkbox name.
var name = $(this).attr('name');
// Checking checkbox state.
if ($(this).is(":checked")) {
// Saving checkbox name to cookie.
AJS.Cookie.save(name, true);
} else {
// Remove checkbox state from cookie.
AJS.Cookie.erase(name);
}
if ($(this).is(":checked")) {
impactMapValues = $( this ).prop('id');
impactMapActor = $( this ).prop('name');
var value = document.getElementById(impactMapValues).value;
if (impactMapActor == "actor-checkbox") {
targetGroupActors.push(value);
}
if (impactMapActor == "impact-checkbox") {
var result = value.split(",");
actor_value = result[0];
impact_value = result[1];
bigPictureActors.push(actor_value);
bigPictureImpacts.push(impact_value);
}
if (impactMapActor == "deliverable-checkbox") {
var result = value.split(",");
actor_value = result[0];
deliverable_value = result[1];
productDetailsActors.push(actor_value);
productDetailsDeliverable.push(deliverable_value);
}
checked.push(value);
}
});
addTotargetGroup(targetGroupActors);
addToBigPicture(bigPictureActors,bigPictureImpacts);
addReleaseTarget(productDetailsActors,productDetailsDeliverable);
}
Try this approach:
// Wait until the page is completely loaded.
$(document).ready(function() {
// Iterating over all checkboxes on page.
$('input:checkbox').each(function() {
// Getting checkbox name.
var name = $(this).attr('name');
// Checking saved cookie.
if (AJS.Cookie.read(name)) {
// Updating checkbox state.
$(this).prop('checked', true);
}
// Attaching onchange handler.
$(this).change(function() {
// Checking checkbox state.
if ($(this).is(":checked")) {
// Saving checkbox name to cookie.
AJS.Cookie.save(name, true);
} else {
// Remove checkbox state from cookie.
AJS.Cookie.erase(name);
}
});
});
});
Use viewstate concept intead of using other cookies logic
Wrap all your logic in
AJS.toInit(function ($) {
// You can use $ instead of AJS.$ here
...
});
This is Atlassian's equivalent of $(document).ready(...) which allows all the Atlassian code to load before you call yours.

How to loop through ids with same prefix

I have this section of code that saves a list item on click to localStorage based on the list item's id number. On a different page I am then able to load whatever list items were saved.
var save1075 = $('#store-1075').get(0);
$('#store-1075').on('click', function () {
var storeStorageKey1075 = $(this).attr('id');
localStorage.setItem('storeStorageKey1075', $(this).attr('id'));
localStorage.setItem('storeStorageKey1075', this.innerHTML);
});
if ( localStorage.getItem('storeStorageKey1075') ) {
save1075.innerHTML = localStorage.getItem('storeStorageKey1075');
}
var storeStorageKey1075 = $(this).attr('id');
if ( localStorage.getItem('storeStorageKey1075') ) {
storeStorageKey1075 = localStorage.getItem('storeStorageKey1075');
}
Right now I have to repeat that chunk of code for every individual id number and I'm trying to instead make the id number a variable that loops through all possible id numbers when clicked but only saves the id of that specific one. Maybe something along the lines of this:
var id = //some sort of loop or array of possible ids.
var save = $('#store-'+id).get(0);
$('#store-'+id).on('click', function () {
var storeStorageKey = $(this).attr('id');
localStorage.setItem('storeStorageKey', $(this).attr('id'));
localStorage.setItem('storeStorageKey', this.innerHTML);
});
if ( localStorage.getItem('storeStorageKey') ) {
save.innerHTML = localStorage.getItem('storeStorageKey');
}
var storeStorageKey = $(this).attr('id');
if ( localStorage.getItem('storeStorageKey') ) {
storeStorageKey = localStorage.getItem('storeStorageKey');
}
Each of the list items has the same prefix of "store-" and the numbers are in no specific order but randomly generated each time a new store location is created.
The obvious thing to do is to add a class but you could also:
var elems = $( "[id^='store']")
elems.on( "click", function() {//Save html on click
localStorage.setItem( this.id, this.innerHTML );
});
//Retrieve html
elems.each( function() {
var html = localStorage.getItem( this.id );
if( html ) {
$(this).html( html );
}
});
This loops over all keys that begin with storeStorageKey:
for (var i=0; i<localStorage.length; i++) {
var key = localStorage.key(i);
if (/^storeStorageKey/.test(key)) {
var item = localStorage.getItem(key);
// do something with item
}
}
Instead of using a prefix in the id I'd suggest adding a class to indicate that an item is storable:
<div class="storable" id="store-1234">...</div>
then you can use the class to select all the storable things in one go:
$('.storable').on('click', function () {
var storeStorageKey = $(this).attr('id');
...
});

Categories

Resources