I have a a table that has four columns ID,NAME,SURNAME and RECIPIENT
Each button has a different value that is equal to the number of the ID that is in the same line as the button. For example the value of the first button is 2, second button 3 last button 123 all the buttons have id=contact. Each time i press a button i store the value of that button in a variable with the name input. My source code for that is:
var input; //prepare var to save contact name/ PLACE outside document ready
$(function() {
// contact form animations
$('button[id="contact"]').click(function() {
input = $(this).val(); //set var contactName to value of the pressed button
$('#contactForm').fadeToggle();
})
$(document).mouseup(function (e) {
var container = $("#contactForm");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.fadeOut();
}
});
});
Then i want to user this variable to fetch some files that are corresponded with the current varibale from firebase database. In my firebase database i have a folder with the name files that has three supfolders that coresponds to the values of the three buttons that i have
In general lines I click one of the three buttons (let's say the button in the first column), I store the value of the button(so now the input value will be equal to 2). Then i drug all the information that is stored in firebase database from files/2/. I have implemented the source code for that but I am not getting any results and when i run inspect console i am not getting any errors. The source code is the following :
var databaseRef = firebase.database().ref().child(`files/${input}/`);
var tblUsers = document.getElementById('tbl_users_list');
var rowIndex = 1;
databaseRef.once('value',function(snapshot){
snapshot.forEach(function(childsnapshot) {
var childKey = childsnapshot.key;
var childData = childsnapshot.val();
//var urls = childData.url;
var row = tblUsers.insertRow(rowIndex);
var cellId = row.insertCell(0);
var cellName = row.insertCell(1);
var button = row.insertCell(2);
var itd = document.createElement('input');
itd.setAttribute("type","button");
itd.setAttribute("value","View");
itd.onclick=function () {
window.open(childData.url);
};
cellId.appendChild(document.createTextNode(childData.filename));
cellName.appendChild(document.createTextNode(childData.created));
button.appendChild(itd);
rowIndex = rowIndex+1;
//document.write(username);
})
});
If in the above source code change the line var databaseRef = firebase.database().ref().child(`files/${input}/`); replacing the variable i stored the value of the button in the first function with 2 , 3 or 123 i am getting results so it seems the the problem is there but i dont know what else to do.
Can someone please help me ?
Thanks in Regards
This appears to be a perfect use case for the .dataset or data- attribute. MDN has a great page showing how to use this. Basically, store the uid as <data-uid = "ach782bckhbc23whatever"> in your HTML on the <tr> or the <button> element an on click, use evt.target.dataset.uid or evt.target.parentElement.dataset.uid to get the row's uid to make your .get() firebase call.
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe</div>
let el = document.querySelector('#user');
// el.id == 'user'
// el.dataset.id === '1234567890'
// el.dataset.user === 'johndoe'
// el.dataset.dateOfBirth === ''
el.dataset.dateOfBirth = '1960-10-03'; // set the DOB.
// 'someDataAttr' in el.dataset === false
el.dataset.someDataAttr = 'mydata';
// 'someDataAttr' in el.dataset === true
Related
I created a table in javascript that uses for loop adding 7 empty rows to the HTML table. But, it seems like these rows (or columns) have default sizes. Tried every possible way to resize them, but no luck. I have div element and inside has two tables for reference. Using also "display: inline- block". Here is my javascript code:
document.addEventListener("DOMContentLoaded", function(){
// Get the current page's URL
const currentUrl = window.location.href;
// Check if the current page's URL is the URL of the exam page
if (currentUrl.includes("exam.html")) {
// Get the table element from the HTML document
const lowBoundAndGradeTable = document.querySelector(".low_boundAndGrade");
// create an empty array to store the exam data
let gradeData = [];
// Check if there is data stored in localStorage
if (localStorage.getItem("gradeData")) {
// Retrieve the data from localStorage and parse it as JSON
gradeData = JSON.parse(localStorage.getItem("gradeData"));
}
// Loop through the examData to insert the rows
gradeData.forEach((data, index) => {
// create a new table row
const row = lowBoundAndGradeTable.insertRow();
// insert the cells into the row
const lowBoundCell = row.insertCell();
lowBoundCell.innerHTML = `<input type="text" name="low bound." value="${data.lowBound}">`;
const gradeCell = row.insertCell();
gradeCell.innerHTML = `<input type="text" name="grade" value="${data.grade}">`;
// add a change event listener to each input field
lowBoundCell.querySelector("input").addEventListener("change", function(){
gradeData[index].lowBound = this.value;
localStorage.setItem("gradeData", JSON.stringify(gradeData));
})
gradeCell.querySelector("input").addEventListener("change", function(){
gradeData[index].grade = this.value;
localStorage.setItem("gradeData", JSON.stringify(gradeData));
});
});
// Loop to insert 7 rows if studentData array is empty
if(gradeData.length == 0){
for (let i = 0; i < 7; i++) {
// create a new table row
const row = lowBoundAndGradeTable.insertRow();
// insert the cells into the row
const lowBoundCell = row.insertCell();
lowBoundCell.innerHTML = `<input type="text" name="low bound${i}">`;
const gradeCell = row.insertCell();
gradeCell.innerHTML = `<input type="text" name="grade${i}">`;
// add the data to the examData array
gradeData.push({ lowBound: "", grade: "" });
}
// set the examData in localStorage
localStorage.setItem("gradeData", JSON.stringify(gradeData));
}
}
});
I want to resize the rows so that I can enter numbers in it. But, these cells are kinda big that does not look like user friendly.
I've created a website using google app script. In my website, I have a table but the values came from my spreadsheet.
Now, I have an editable table unfortunately, once I change the values in the row and the auto refresh triggered it will come back to normal and get the original values from the spreadsheet. Is there a way that once I've made some changes it will also change in the spreadsheet so when autorefresh triggered it will just be the same? Is it even possible?
<script>
document.addEventListener("DOMContentLoaded",function(){
google.script.run.withSuccessHandler(generateTable).getOnline();
google.script.run.withSuccessHandler(generateTable1).getStatus();
setInterval(() => {
document.getElementById("tablebody").innerHTML = "";
document.getElementById("tablebody1").innerHTML = "";
google.script.run.withSuccessHandler(generateTable).getOnline();
google.script.run.withSuccessHandler(generateTable1).getStatus();
google.script.run.withSuccessHandler(getOnline).generateTable();
google.script.run.withSuccessHandler(getStatus).generateTable1();
}, 20000); // run the function every 5 seconds
});
function generateTable(dataArray){
var tbody = document.getElementById("tablebody");
var tbody1 = document.getElementById("tablebody").innerHTML;
dataArray.forEach(function(r){
var row = document.createElement("tr");
var col1 = document.createElement("td");
col1.textContent = r[0];
var col2 = document.createElement("td");
col2.textContent = r[1];
var col3 = document.createElement("td");
col3.textContent = r[2];
row.appendChild(col1);
row.appendChild(col2);
row.appendChild(col3);
tbody.appendChild(row);
$(function(){
$("td").click(function(event){
if($(this).children("input").length > 0)
return false;
var tdObj = $(this);
var preText = tdObj.html();
var inputObj = $("<input type='text' />");
tdObj.html("");
inputObj.width(tdObj.width())
.height(tdObj.height())
.css({border:"0px",fontSize:"17px"})
.val(preText)
.appendTo(tdObj)
.trigger("focus")
.trigger("select");
inputObj.keyup(function(event){
if(13 == event.which) { // press ENTER-key
var text = $(this).val();
tdObj.html(text);
}
else if(27 == event.which) { // press ESC-key
tdObj.html(preText);
}
});
inputObj.click(function(){
return false;
});
});
});
});
}
</script>
<table>
<tr>
<th>Timestamp & Current TimeZone</th>
<th>Name</th>
<th>EID</th>
</tr>
<tbody id="tablebody">
</table>
Here's my code on .gs
function getOnline(){
var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("UserLogins");
var data = ws.getRange(3, 1, ws.getLastRow()-1,3).getValues();
Logger.log(data);
return data;
}
I’m not sure of your use case, but it’s possible to embed an editable spreadsheet (see how here).
If you really want to do this with HTML + JavaScript for yourself, my approach would be:
Keep a version of what you know is in the backend. And another of the local changes, in different data structures.
Use functional paradigms to generate the table. Specially reactive frameworks (React, Vue.js, etc) will simplify your job a lot.
When “applying” changes, do not manually modify the backend data representation.
It should be kept as the data that the server sends you. Simply send the request and it will be updated automatically.
When the server sends a change that you had locally, remove it from the local changes. This consolidates the changes.
Also, you need to decide what happens when a cell gets updated while you are editing it.
Here is an example with vanilla JS on a single text input which can give you an idea (a lot of this could be handled by a reactive framework):
const elements = {
input: null,
stateView: null
}
const backend = {
input: 'value'
}
const local = {
}
function update() {
// Update backend with the backend information. Usually means a fetch
/* backend = ... */
if (local.input === backend.input) {
delete local.input
}
render()
}
function save() {
// Send a request updating the backend
// simulation
backend.input = local.input
update()
}
function localChange() {
local.input = elements.input.value
if (local.input === backend.input) {
delete local.input
}
render()
}
function render() {
input.value = 'input' in local ? local.input : backend.input
let state = ''
if ('input' in local) {
state += `Local: "${local.input}"<br/>`
}
state += `Backend: "${backend.input}"<br/>`
elements.stateView.innerHTML = state
}
// Setup events
document.addEventListener('DOMContentLoaded', function() {
elements.input = document.getElementById('input')
elements.input.addEventListener('keyup', localChange)
elements.input.addEventListener('change', save)
elements.stateView = document.getElementById('stateView')
update()
})
<input id="input" type="text" placeholder="Add you data here">
<p id="stateView"></p>
Notice that in this case if the user is editing and it’s the same I just ignore the local state. Also, because I’m not really making requests, everything is instantaneous.
I have coded some simple function which allow me to add order. I have also dynamically created the button which when called will remove the current html element which is a table row. Now, I am stuck with finding the current element index which I needed so I can use splice to remove it from the array.
const order = [];
const customer = {
name: '',
totalCups: 0
}
$('#btnAdd').click(function() {
debugger
var itemName = $('#customerName');
var itemTotalCups = $('#customerTotalCups');
customer.name = itemName.val();
customer.totalCups = itemTotalCups.val();
// Data structure Queue
order.push(Object.assign({}, customer));
// UI - HTML rendering - start
if (order.length === 1) {
// Create table column name
$('#AllOrders').append('<table id="tbl" class="table table-bordered"><tr><td>Customer</td><td>Cups</td><td></td></tr></table>');
}
var itemElement = `<tr><td>${itemName.val()}</td><td>${itemTotalCups.val()}</td><td><a class='del' href='#'>Cancel order</a></td></tr>`;
$('#tbl').append(itemElement);
// UI - HTML rendering - end
$('.del').click(function(e) {
e.stopImmediatePropagation();
// Delete order object
debugger
//var elm = $(this).parent().text().substr(0, $(this).parent().text().length-1);
console.log(elm);
console.log(order.indexOf(elm));
//order.splice(order.indexOf(elm),1);
//order.splice(2,1);
// Delete HTML element
$(this).parent().parent().remove();
})
// Reset textbox
itemName.val("");
itemTotalCups.val("");
// Optional Design
$('#ViewAllOrders').click();
debugger;
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="customerName" type="text" />
<input id="customerTotalCups" type="number" />
<button id="btnAdd">Add</button>
<div id="AllOrders"></div>
I search for the solution but can't figure out the commented code below to find the element
//var elm = $(this).parent().text().substr(0, $(this).parent().text().length-1);
I am stuck inside $('.del').click event handler.
You can find the element in the order array by getting the index of the row where the clicked cancel button is.
To do so, you have to first get the current row. You can use the closest method:
var $row = $(this).closest('tr');
Now, you can get the index of the current row through the index method. You have to take into account that you have the tr for the header, you we need to substract one:
var index = $row.index() - 1;
Your final code should look like:
$('.del').click(function(e) {
e.stopImmediatePropagation();
var $row = $(this).closest('tr');
var index = $row.index() - 1;
order.splice(index, 1);
// Delete HTML element
$row.remove();
});
You can find the parent tr element and use that element to find the customer name and delete that node from DOM.
Couple of methods you want to try out:
.closest(): find the first match in the parent DOM hierarchy
https://api.jquery.com/closest
.filter(): filter an array based on some condition
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
So, basically you can find the closest tr node using closest and then find the customer name from within this tr's first td element.
Then, use filter on order to remove its instance from the order array.
Below is the changed code from the snippet:
$('.del').click(function(e) {
e.stopImmediatePropagation();
// Delete order object
var elm = $(this).closest('tr');
var nameToDelete = elm.find('td:first').text();
// filter out order
order = order.filter(item => item.name !== nameToDelete);
console.log('order now is = ', order);
// Delete HTML element
elm.remove();
});
More appropriately, learn about using HTML data-* Attributes along with id and class that could really ease up DOM manipulation. There are many samples online. Give that a try.
Cheers!
var order = [];
const customer = {
name: '',
totalCups: 0
};
$('#btnAdd').click(function() {
var itemName = $('#customerName');
var itemTotalCups = $('#customerTotalCups');
customer.name = itemName.val();
customer.totalCups = itemTotalCups.val();
// Data structure Queue
order.push(Object.assign({}, customer));
// UI - HTML rendering - start
if (order.length === 1) {
// Create table column name
$('#AllOrders').append('<table id="tbl" class="table table-bordered"><tr><td>Customer</td><td>Cups</td><td></td></tr></table>');
}
var itemElement = `<tr><td>${itemName.val()}</td><td>${itemTotalCups.val()}</td><td><a class='del' href='#'>Cancel order</a></td></tr>`;
$('#tbl').append(itemElement);
// UI - HTML rendering - end
$('.del').click(function(e) {
e.stopImmediatePropagation();
// Delete order object
var elm = $(this).closest('tr');
var nameToDelete = elm.find('td:first').text();
// filter out order
order = order.filter(item => item.name !== nameToDelete);
console.log('order now is = ', order);
// Delete HTML element
elm.remove();
});
// Reset textbox
itemName.val("");
itemTotalCups.val("");
// Optional Design
$('#ViewAllOrders').click();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="customerName" type="text" />
<input id="customerTotalCups" type="number" />
<button id="btnAdd">Add</button>
<div id="AllOrders"></div>
I am trying to make a form where you have a list with the names of your friends to invite them every name with a checkbox i already get the data and insert the data in a collection as an array but now i added a filter to the friends list and when i check the checkbox --> change the filter --> other name appears --> change the filter so the first name comes again but it isnt checked anymore so the data is lost
Thats the point why i created a event where the last names of this filter input is stored and when you change the filter and select some friends i want to combine the first and the second array to insert it in the collection.
This is it so far:
Template.NeuesEvent.events({
"click .RadioButtonOnClick": function(event){
var Zwischensumme = [];
$.each($('.FreundeCheckbox:checked'), function(){
Zwischensumme.push($(this).val());
});
console.log(Zwischensumme);
Session.set("Zwischensumme", Zwischensumme);
}
});
and here is the other event with the insert and the array I want all of the data go is "eingeladene":
Template.NeuesEvent.events({
"submit .add-event": function(event){
var Name = event.target.name.value;
var Beschreibung = event.target.beschreibung.value;
var Datum = event.target.Datum.value;
var Autor = Meteor.userId();
var Einladender = Meteor.user().username;
var eingeladene = [-----Here the Data have to go-------- ];
if (Name == "")
{
confirm("Das Event braucht einen Namen ;)")
}
else
{
Meteor.call('addEvent', Name, Beschreibung, Datum, eingeladene, Autor, Einladender)
event.target.name.value = "";
event.target.beschreibung.value = "";
FlowRouter.go('/meineEvents');
return false;
}
}
});
Hello friends I have a <input type="text" id="tempID" /> element in my form
I also have an <input type="button" onclick="doSomething()" /> element in my form.
I want to add the text box value to textbox history when user clicks on the button.
I am processing the request using Jquery ajax. So I have to do it with javascript or Jquery.
Is this possible to add values to the history of particular <input type="text" /> element using javascript/Jquery..??
Here is how you can do it using HTML5 LocalStorage
$( "#tempID" ).autocomplete({
source: function( req, resp ) {
var temp = localStorage.getItem('custom_history');
var data = JSON.parse(temp);
resp( data );
}
});
$('#tempID').on('blur', function() {
var temp = localStorage.getItem('custom_history');
var data = JSON.parse(temp);
if($.trim(this.value).length > 0)
data.push(this.value);
localStorage.setItem('custom_history', JSON.stringify(data));
});
What I am doing is Setting the value into HTML5 Local storage when users moves away from the input field, clicks somewhere else.
Then retrieving that and setting that as source for jQuery UI auto complete.
Here is a working fiddle http://jsfiddle.net/joycse06/EBduF/173/
Enter some value. Click somewhere else. Click back again and add other values. The refresh the fiddle and start typing one of those and auto complete will show up.
UPDATE
Based on his comments and later chat the final code he need is this, I am pasting in if it might someone else later
// if we dont set this line then ff will return null, and null.length will throw an error
if(!localStorage.getItem('custom_history'))
localStorage.setItem('custom_history','');
$( "#test" ).autocomplete({
source: function( req, resp ) {
var term = req.term;
var temp = localStorage.getItem('custom_history');
var data = [];
if(temp.length > 0)
data = JSON.parse(temp);
var intRegex = /^\d+$/;
data = $.map(data,function(val){
if(intRegex.test(val)){
if(val.indexOf(term) != -1)
return val;
else
return null;
}
else
return null;
});
resp( data );
}
});
$('#save').on('click', function() {
var temp = localStorage.getItem('custom_history');
var data = [];
if(temp.length > 0)
data = JSON.parse(temp);
var value = $.trim($('#test').val());
if(value.length > 0){
if($.inArray(value,data) != -1){
//alert('Duplicate');
return;
}
}
data.push(value);
localStorage.setItem('custom_history', JSON.stringify(data)); // set item to localStorage
});
You can use localStorage like following:
var arr = [];
$('input#tempID').on('click', function() {
arr.push(this.value);
localStorage.setItem('history', JSON.stringify(arr)); // set item to localStorage
});
To retrieve that value try,
var temp = localStorage.getItem('history');
if(retarr) { // checking that data it stored in localStorage or not, if not exists temp = null
var allHistories = JSON.parse(temp); // now you have history
console.log(allHistories);
}
I think you need something like autocomplete