JavaScript, get dynamically created label's id - javascript

The label that is beings created holds a guid that I need later. I need to grab that information after the list of labels are created. Here's my code:
<button onclick="getAllListings()">Get All Listings Information</button>
<br />
<div id="divDataInsert" name="divDataInsert">
#foreach (MVCTest1.Models.Listing foundListings in Model._listings)
{
string pk_listing_id = "listingsid_" + foundListings.PK_Listings_ID;
string addressPK = "address_" + foundListings.PK_Listings_ID;
string address = foundListings.Address.ToString();
string cityPK = "city_" + foundListings.PK_Listings_ID;
string city = foundListings.City.ToString();
string statePK = "state_" + foundListings.PK_Listings_ID;
string state = foundListings.State.ToString();
string zipcodePK = "zipcode_" + foundListings.PK_Listings_ID;
string zipcode = foundListings.ZipCode.ToString();
string fullAddress = address + ", " + city + " " + state;
if (foundListings.PK_Listings_ID != null)
{
<input type="text" id="lblListing_#pk_listing_id" value="#pk_listing_id" />
}
}
</div>
function getAllListings(){
//var listingArray = [document.getElementById("lblListing_")];
for (var i = 0; i < [document.getElementById("lblListing_")].length; i++) {
var listingString = document.getElementById("lblListing_").value;
var guid = listingString.split("_");
alert(guid[1]);
i++;
}
}
My code behind
public ActionResult Index()
{
string sql = "SELECT TOP 10 [PK_Listings_ID], [Address], [City], [State], [ZipCode] FROM dbo.Listings";
ListingCollection ListOfListings = new ListingCollection();
ListOfListings._listings = new List<Listing>();
using (SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["MVCInsertData"].ToString()))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = conn;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = sql;
using(SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
Listing listing = new Listing();
listing.PK_Listings_ID = Convert.ToInt32(reader["PK_Listings_ID"]);
listing.Address = reader["Address"].ToString();
listing.City = reader["City"].ToString();
listing.State = reader["State"].ToString();
listing.ZipCode = reader["ZipCode"].ToString();
ListOfListings._listings.Add(listing);
}
}
}
}
conn.Close();
}
return View(ListOfListings);
}
one of the answers involved adding a JS array in the code behind. How do you do that?
*****Update*****
I have changed my input to this:
<input type="text" class="lblListing_" value="#pk_listing_id" />
And I have adjusted my JS to this:
function getAllListings(){
var listingsArray = document.getElementsByClassName("lblListing_");
for (var i = 0; i < listingsArray.length; i++) {
var listingString = listingsArray.value;
var guid = listingString.split("_");
alert(guid[1]);
}
}
Keep in mind, my JS is NOT inside a document.ready(). Should it be?

One way would be to have your code behind emit a JavaScript array of all labels. A different--and this is the approach I would take--would be to use a class name as a "tag". Emit:
<input type="text" class="lblListing_" ...>
Then in your fixed (not dynamic) JavaScript, you can do:
function getAllListings(){
var listings = document.getElementsByClassName("lblListing_");
for (var i = 0; i < listings.length; i++) {
var listingString = listings[i].value;
var guid = listingString.split("_");
alert(guid[1]);
}
}
Update for the follow-on question:
The JavaScript can be placed anywhere but will not run on load. When and how to run the function depends on what you need it to do. (I assume the alert is just to test the logic.)

You can easily achieve that with jQuery
$('someSelector').each(function() {
// do something
});
$("input[id^='lblListing_']").each(function() {
console.log($(this).val().split("_")[1]);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="lblListing_g-u-i-d-1" value="value1_g-u-i-d-1" />
<input type="text" id="lblListing_g-u-i-d-2" value="value2_g-u-i-d-2" />

Related

Parsing text area line that comma separated using Jquery or Js

I have a textarea with data like this (UserId,Name,Gender), and I want to parsing that data
<textarea class="form-control" id="data" rows="5" cols="10" placeholder="ID's Phones Number:" name="msg">097544,markd amm,male
731490,Hossam Hassan,male
130578,Kamal Eldin,male
87078148,Muhammad Ahmad Atia,male
932484,Alia AlHorria,female
093779,Yaser Hadidi,male
39393,Soka Dą,female
</textarea>
i want all IDs only , Names only And i want to get Names&Gender from text area above ,
i tried to separated this data but if failed .
This my JS code :
var data = $('#data').val();
console.log(fbdata[0]);
Split your trimmed string by newlines to create an array of strings.
Then, depending on the desired output use Array.prototype.map() or Array.prototype.reduce()
const elData = document.querySelector("#data");
const str = elData.value.trim();
const lines = str.split(/\n/);
// Example 1: create array or data objects
const list = lines.map(str => {
const [id, name, gender] = str.split(",");
return {id, name, gender};
});
// console.log(list); // get 'em all
console.log(list[1]); // get by index
// Log only names
list.forEach((user) => {
console.log(user.name);
});
// example 2: create Object of items - by ID
const listById = lines.reduce((acc, str) => {
const [id, name, gender] = str.split(",");
acc[id]= {id, name, gender};
return acc;
}, {});
// console.log(listById); // get 'em all
console.log(listById[731490]) // Get specific by ID
<textarea class="form-control" id="data" name="msg">097544,markd amm,male
731490,Hossam Hassan,male
130578,Kamal Eldin,male
87078148,Muhammad Ahmad Atia,male
932484,Alia AlHorria,female
093779,Yaser Hadidi,male
39393,Soka Dą,female
</textarea>
You could also do it like this.
var results = [];
var data = $('#data').val().trim();
if(data) {
// Create an array by splitting the textarea.value by newline
data = data.split(/\r?\n/);
// Loop through indivdual rows, and split by comma / ,
for(var i = 0; i < data.length; i++) {
var temp = data[i].trim();
if(temp) {
// Create an array from the values in the current line
temp = temp.split(",");
// Separate the first and last names
var pairs = temp[1].split(/ (.*)/s);
// if there's no last name, pairs[1]
// will be undefined, so we set it to
// and empty string, to avid errors
if(typeof pairs[1] === 'undefined') {
pairs[1] = '';
}
var personsObj = {};
personsObj.id = temp[0];
personsObj.firstName = pairs[0].trim();
personsObj.lastName = pairs[1].trim();
personsObj.gender = temp[2].trim();
results.push(personsObj);
}
}
}
console.log(results);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea class="form-control" id="data" rows="5" cols="10" placeholder="ID's Phones Number:" name="msg">097544,markd amm,male
731490,Hossam Hassan,male
130578,Kamal Eldin,male
87078148,Muhammad Ahmad Atia,male
932484,Alia AlHorria,female
093779,Yaser Hadidi,male
39393,Soka Dą,female
</textarea>
EDIT
If you want to replace the contents of the textarea with specific values from the processed array of objects (results, in my example), you could do that like this.
Please note that you do not need extra textareas, like in the following example. I am using them to show you what you would get for different combinations. In reality, you would replace the contents of the #data element with the new content.
var results = [];
var data = $('#data').val().trim();
if(data) {
// Create an array by splitting the textarea.value by newline
data = data.split(/\r?\n/);
// Loop through indivdual rows, and split by comma / ,
for(var i = 0; i < data.length; i++) {
var temp = data[i].trim();
if(temp) {
// Create an array from the values in the current line
temp = temp.split(",");
// Separate the first and last names
var pairs = temp[1].split(/ (.*)/s);
// if there's no last name, pairs[1]
// will be undefined, so we set it to
// and empty string, to avid errors
if(typeof pairs[1] === 'undefined') {
pairs[1] = '';
}
var personsObj = {};
personsObj.id = temp[0];
personsObj.firstName = pairs[0].trim();
personsObj.lastName = pairs[1].trim();
personsObj.gender = temp[2].trim();
results.push(personsObj);
}
}
}
// This doesn't have to be here, you can use the logic in the loop above
// which would a better, more efficient way of doing it
// I'm doing this separately, so you can better understand how it works
// That's why there are 6 additional textareas - in reality, you would
// change the contents of your original textarea
var tmpNames = "", tmpIdsNames = "",
tmpGenders = "", tmpIdsGenders = "",
tmpNamesGenders = "", tmpIdsNamesGenders = "";
for(var i = 0; i < results.length; i++) {
tmpNames += results[i].firstName+ "\r\n";
tmpIdsNames += results[i].id + "," + results[i].firstName + "\r\n";
tmpGenders += results[i].gender + "\r\n";
tmpIdsGenders += results[i].id + "," + results[i].gender + "\r\n";
tmpNamesGenders += results[i].firstName + "," + results[i].gender + "\r\n";
tmpIdsNamesGenders += results[i].id + "," + results[i].firstName + "," + results[i].gender + "\r\n";
}
$("#justNames").val(tmpNames);
$("#idsNames").val(tmpIdsNames);
$("#justGenders").val(tmpGenders);
$("#idsGenders").val(tmpIdsGenders);
$("#namesGenders").val(tmpNamesGenders);
$("#idsNamesGenders").val(tmpIdsNamesGenders);
textarea {
width: 100%;
}
.results {
display: inline-block;
width: 30%;
margin-right: 15px;
}
.results textarea {
min-height: 75px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label style="display:block; width:100%">Original data
<textarea class="form-control" id="data" rows="5" cols="10" placeholder="ID's Phones Number:" name="msg">097544,markd amm,male
731490,Hossam Hassan,male
130578,Kamal Eldin,male
87078148,Muhammad Ahmad Atia,male
932484,Alia AlHorria,female
093779,Yaser Hadidi,male
39393,Soka Dą,female
</textarea>
</label>
<label class="results">Just names
<textarea style="display:block" id="justNames" name="justNames"></textarea>
</label>
<label class="results">IDs and names
<textarea style="display:block" id="idsNames" name="idsNames"></textarea>
</label>
<label class="results">Just genders
<textarea style="display:block" id="justGenders" name="justGenders"></textarea>
</label>
<label class="results">IDs and genders
<textarea style="display:block" id="idsGenders" name="idsGenders"></textarea>
</label>
<label class="results">Names and genders
<textarea style="display:block" id="namesGenders" name="namesGenders"></textarea>
</label>
<label class="results">IDs, names and genders
<textarea style="display:block" id="idsNamesGenders" name="idsNamesGenders"></textarea>
</label>
You can also experiment with this fiddle.
See String.prototype.split() and Array.prototype.map().
var data = $('#data').val().split("\n").map(line => line.split(",")[0]);
// ['097544', '731490', '130578', '87078148', '932484', '093779', '39393']

JavaScript , AJAX, PHP : trying to get values from $_POST

I am trying to build a way for a user to be able to create an article, if they want, with a button they can add an input for a text, a file input etc.
I want to send this form with JavaScript vanilla (training)
so what I do in my js is that I loop into my different added input then I append them to formData
and send this formData to my controller to treat it and add it to my database.
Problem is that by iterating my input when I append my input into formData I have to add the index
so when I send it and print_r my post
I get like:
text01
text02
text03 etc.
it would be fine if it was only these input that I wanted to send but in my post I have other inputs which are sent the same way so I get like
title01
paragraphe01
title02
paragprahe02
the problem will be when I want to query to add the data to my database I would have to bind all of these to my query, but of course I can't make 50 lines of
bind('text01', $text01)
I don't think it would be a nice way to do it
so I am looking for a way to be able to query all of these data I thought of maybe a way getting only the paragraphs indexes and putting them in an array containing only paragraphs then forEach() everything.
another array for another input etc. but I can't find a way to do it, is it even possible
so here is my code
<?php
include '../flash/Flash.php';
$pageTitle = "création d'article";
$css = "create_article";
include './assets/include/_header.php';
?>
<body>
<?php
include '../view/assets/include/_nav.php';
flash('createB');
?>
<main>
<form action="../controller/Crud_controller.php" method="post" class="form_container" enctype="multipart/form-data">
<input type="hidden" name="type" value="createB" id="type">
<h3 id="status"></h3>
<h5>titre du post</h5>
<input type="text" name="title" id="title">
<h5>Paragraphe</h5>
<textarea name="paragraphe" id="product_desc" cols="30" rows="10"></textarea>
<input type="file" id="img_livre" name="name" accept="image/png, image/jpeg">
<h5>Note 1</h5>
<input type="text" name="note" id="note">
<button type="button" data-prototype="" class="btn btn_primary btn-js">Ajouter un paragraphe ou une image ?</button>
<button type="button" class="btn btn_primary btn-js-ajax">envoyer</button>
</form>
</main>
</body>
<script>
const btnSubmit = document.querySelector('.btn-js-ajax');
btnSubmit.addEventListener('click', uploadFiles);
function uploadFiles() {
let formData = new FormData();
let images = document.getElementsByName('name');
let type = document.getElementById('type').value;
let paragraphe = document.getElementsByName('paragraphe');
let note = document.getElementsByName('note');
let title = document.getElementById('title').value;
for(i = 0; i <= images.length; i++) {
let uFiles = images[i];
if (uFiles) {
formData.append("name" + i, uFiles.files[0]);
}
}
for(let i = 0; i < paragraphe.length; i++) {
let paragraphes = paragraphe[i].value;
if (paragraphes) {
formData.append("paragraphe"+i,paragraphes);
}
}
for(let i = 0; i < note.length; i++) {
let notes = note[i].value;
if (notes) {
formData.append("note" + i, notes);
}
}
formData.append('title', title);
formData.append('type',type );
const ajax = new XMLHttpRequest();
fetch("../controller/Crud_controller.php", {method: "POST", body: formData}).then(res => res.text()).then(data => {console.log(data);})
ajax.upload.addEventListener("load", completeHandler, false);
}
var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map((key) => [Number(key)]);
console.log(result);
const form = document.querySelector('.form_container');
const addBtn = document.querySelector('.btn-js');
function addInput() {
const paragraphe = document.createElement('textarea');
paragraphe.name = 'paragraphe';
paragraphe.style = "margin-top:100px";
paragraphe.cols = "30";
paragraphe.rows = "10";
const file = document.createElement('input');
file.type = 'file';
file.style = "border: none";
file.name = 'name';
file.accept = "image/png, image/jpeg";
const note = document.createElement('input');
note.type = 'text';
note.name = 'note';
const btnRemove = document.createElement('a');
btnRemove.className = 'btn_primary btn';
btnRemove.innerHTML = 'supprimer';
form.insertBefore(btnRemove, addBtn);
form.insertBefore(note, btnRemove);
form.insertBefore(file, note);
form.insertBefore(paragraphe, file);
}
addBtn.addEventListener('click', addInput);
</script>
</html>
here the controller getting the post ajax element
<?php
include '../model/CrudModel.php';
include '../model/Blog.php';
require_once '../flash/Flash.php';
class Products
{
private $crudModel;
private $crudBlog;
public function __construct()
{
$this->crudModel = new Product;
$this->crudBlog = new Blog;
}
public function blog()
{
$data = $_POST;
echo "<pre>";
print_r($data);
echo "</pre>";
print_r($_FILES);
if (empty($data['title']) || empty($data['paragraphe'])) {
flash('createB', 'remplir au moins le titre et le paragraphe et ajouter une image');
// header('Location: ../view/crud_blog.php');
} else {
forEach($data as $k => $v)
{if ($this->crudBlog->setBlogPost($data)) {
foreach ($_FILES as $file) {
if ($this->crudBlog->setBlogImages($file)) {
flash('createB', "c'est bon");
// header('Location: ../view/create_blog_page.php ');
}
}
}}
}
}
}
$init = new Products;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
switch ($_POST['type']) {
case 'crud':
$init->produit();
break;
case 'createB':
$init->blog();
break;
default:
echo "je peux pas";
break;
}
}
here is my Model where I have all my queries
<?php
require_once '../dbb/Database.php';
class Blog {
private $con;
private $table_name = "blog_post";
public function __construct()
{
$this->con = new Database;
}
public function setBlogPost($array) {
$query = "INSERT INTO " . $this->table_name . " SET title = :title , paragraphe=:p1 , note = :note1";
$this->con->prepare($query);
$this->con->bind('title' , $array['title']);
$this->con->bind('p1' , $array['paragrape']);
$this->con->bind('note1' , $array['note']);
if($this->con->execute()){
return true;
}return false;
}
public function setBlogImages($file){
$table_name = "blog_image";
$query = "INSERT INTO " . $table_name . " SET name = :img , id = LAST_INSERT_ID()";
$this->con->prepare($query);
$this->con->bind('img',$file['name']);
move_uploaded_file($file['tmp_name'], "../view/assets/uploads/".$file['name']);
if ($this->con->execute()){
return true;
}return false;
}
and this is the response I get in my console.log maybe it will be more clear
thank you
Little edit so i managed to make an array for each of my input
array paragraphe for paragraphes
note for notes etc...
i changed this
for(i = 0; i <= images.length; i++) {
let uFiles = images[i];
if (uFiles) {
formData.append("name" + i, uFiles.files[0]);
}
}
for(let i = 0; i < paragraphe.length; i++) {
let paragraphes = paragraphe[i].value;
if (paragraphes) {
formData.append("paragraphe"+i,paragraphes);
}
}
for(let i = 0; i < note.length; i++) {
let notes = note[i].value;
if (notes) {
formData.append("note" + i, notes);
}
}
by this
for(i = 0; i <= images.length; i++) {
let uFiles = images[i];
if (uFiles) {
formData.append("name[]" + i, uFiles.files[0]);
}
}
for(let i = 0; i < paragraphe.length; i++) {
let paragraphes = paragraphe[i].value;
if (paragraphes) {
formData.append("paragraphe[]"+i,paragraphes);
}
}
for(let i = 0; i < note.length; i++) {
let notes = note[i].value;
if (notes) {
formData.append("note[]" + i, notes);
}
}
but here's the problem
i can't find a way to foreach multiple array in php to add them to my database
this is the response result i get in my console now
reponse2

How to populate multiple HTML DOM elements with local storage values

I want to display contents in the last <div> element when a click event occurs but now it only shows 1st 2 elements. Is there something I am not doing right somewhere?
Here is my code so far:
JS
const iname = document.getElementById("name");
const iemail = document.getElementById("email");
const iphone = document.getElementById("phone");
const submit = document.getElementById("submit");
const storage = document.getElementById("storage");
submit.onclick = function () {
const name = iname.value;
const email = iemail.value;
const phoneno = iphone.value;
if (name && email && phoneno) {
localStorage.setItem(name, "");
localStorage.setItem(email, "");
localStorage.setItem(phoneno, "");
location.reload();
}
};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
storage.innerHTML += `Name : ${key}<br />Email : ${value}`;
}
localStorage.clear()
HTML
<p>Name</p>
<input id="name" autocomplete="off">
<p>Email</p>
<input id="email" autocomplete="off">
<p>Phone no</p>
<input id="phone" autocomplete="off">
<button id="submit">Let's go</button>
<div id="storage" class="box">
<h1>Is this correct?</h1></div>
I think you are setting the values in localstorage the wrong way.
The syntax for storing stuff in there is localstorage.setItem(keyName, keyValue).
And your code is setting the keyName argument to the value you are getting from the form and keyValue argument to an empty string; not what you need.
Make the following changes and you should be good to go (see comments):
submit.onclick = function () {
const name = iname.value;
const email = iemail.value;
const phoneno = iphone.value;
if (name && email && phoneno) {
// set local storage values
localStorage.setItem("name", name); // modified
localStorage.setItem("email", email); // modified
localStorage.setItem("phoneno", phoneno); // modified
location.reload();
}
console.log(localStorage); // new (maybe unnecessary)
};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
storage.innerHTML += `${upFirst(key)}: ${value}<br>`; // modified
}
localStorage.clear();
/**
* new: making the first letter an upper case (for labels in the output div).
* See usage in 'for loop' above.
*/
function upFirst(stringValue) {
return stringValue.slice(0, 1).toUpperCase() + stringValue.slice(1);
}

JavaScript arrays adding last element instead of recently added input

Good evening. I am new to JavaScript and I need help with my mini-project and I have only one issue here and it is in the this.Add = function ().
It works properly when I enter a duplicate value from my list therefore it displays an alert that no dupes are allowed. But... when I enter a unique value, it only adds up the last element present (Wash the dishes) from myTasks list. instead of the one I recently entered and the list goes on adding the same ones. Did I just misplace something?
This is my final activity yet and I want to finish it to move to the next function. Thank you in advance.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Tasks CRUD</title>
<style>
#tasks{
display: none;
}
</style>
</head>
<body>
<center>
<form action="javascript:void(0);" method="POST" onsubmit="app.Add()">
<input type="text" id="add-task" placeholder="Add another card">
<input type="submit" value="Add">
</form>
<div id="tasks" role="aria-hidden">
<form action="javascript:void(0);" method="POST" id="saveEdit">
<input type="text" id="edit-task">
<input type="submit" value="Edit" /> <a onclick="CloseInput()" aria-label="Close">✖</a>
</form>
</div>
<p id="counter"></p>
<table>
<tr>
<th>Name</th>
</tr>
<tbody id="myTasks">
</tbody>
</table>
</center>
<script>
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
if (task ) {
for(task of this.myTasks)
{
var ctr = 0;
if(document.getElementById("add-task").value == task){
ctr = 1;
break;
}
}
if(ctr == 1)
{
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task.trim());
// Reset input value
el.value = '';
// Dislay the new list
this.FetchAll();
}
}
};
this.Edit = function (item) {
var el = document.getElementById('edit-task');
// Display value in the field
el.value = this.myTasks[item];
// Display fields
document.getElementById('tasks').style.display = 'block';
self = this;
document.getElementById('saveEdit').onsubmit = function() {
// Get value
var task = el.value;
if (task) {
// Edit value
self.myTasks.splice(item, 1, task.trim());
// Display the new list
self.FetchAll();
// Hide fields
CloseInput();
}
}
};
this.Delete = function (item) {
// Delete the current row
this.myTasks.splice(item, 1);
// Display the new list
this.FetchAll();
};
}
app.FetchAll();
function CloseInput() {
document.getElementById('tasks').style.display = 'none';
}
</script>
</body>
</html>
In your for loop:
for (task of this.myTask) {
}
You are not declaring a new task variable, but instead assigning to the outer task variable, hence the repeated addition of tasks already in your list.
You can declare a new variable in the for scope like so:
for (const task of this.myTask) {
}
Your HTML as it is.
And your Javascript goes like below. You have a bug while checking if the task already exists in the array. As you're comparing string value either use simple for loop with triple equals or do as i have attached below.
var app = new function() {
this.el = document.getElementById('myTasks');
this.myTasks = ['Clean the bathroom', 'Wash the dishes'];
this.Count = function(data) {
var el = document.getElementById('counter');
var name = 'task';
if (data) {
if (data > 1) {
name = 'Things To DO';
}
el.innerHTML = data + ' ' + name ;
} else {
el.innerHTML = 'No ' + name;
}
};
this.FetchAll = function() {
var data = '';
if (this.myTasks.length > 0) {
for (i = 0; i < this.myTasks.length; i++) {
data += '<tr>';
data += '<td>' + this.myTasks[i] + '</td>';
data += '<td><button onclick="app.Edit(' + i + ')">Edit</button></td>';
data += '<td><button onclick="app.Delete(' + i + ')">Delete</button></td>';
data += '</tr>';
}
}
this.Count(this.myTasks.length);
console.log(this.myTasks.length);
return this.el.innerHTML = data;
};
this.Add = function () {
el = document.getElementById('add-task');
// Get the value
var task = el.value;
console.log(task);
if (task ){
var arrayContainsTask = (this.myTasks.indexOf(task) > -1);
if(arrayContainsTask == true){
window.alert("Duplicates not allowed.");
}else{
// Add the new value
this.myTasks.push(task);
// Reset input value
el.value = '';
}
// Dislay the new list
this.FetchAll();
}
}
}

HTML error in Google Apps Script for EVE Online

I am currently working on a little recreational Google Apps Script (GAS) for EVE Online and I have hit a brick wall when I am getting my server side functions talking to my client side ones.
HTML:
<form id="frm1" name = "mat_add">
<input width="1000" type="text" name="mat" value="Enter Item Here"><br />
<input type="button" value="Submit" name="mat_sub" onclick= "google.script.run.withSuccessHandler(onSuccess).shortlist(this.parentNode,document.getElementById('spn1').innerHTML)">
</form>
<span id="spn1"><table><tr><td>Type Name</td><td>Type ID</td></tr></table></span>
<script>
function onSuccess(output) {
document.getElementById(output[0]).innerHTML = output[1];
};
</script>
GAS:
function doGet() {
return HtmlService.createTemplateFromFile('Index').evaluate().setTitle('UMX Web App');
};
function include(filename) {
return HtmlService.createHtmlOutputFromFile(filename).getContent();
};
function shortlist(form,table) {
var arr = transpose(htmlToArray(table));
var item = form.mat;
if ( isNaN(item) ) {
var url = 'https://www.fuzzwork.co.uk/api/typeid2.php?format=xml&typename=' + item.toString();
} else {
var url = 'https://api.eveonline.com/eve/TypeName.xml.aspx?ids=' + item.toString();
};
var xml = UrlFetchApp.fetch(url).getContentText();
var document = XmlService.parse(xml);
var name = document.getRootElement().getChild('result').getChild('rowset').getChild('row').getAttribute('typeName').getValue();
if ( arr[0].indexOf(name) == -1 && name != 'Unknown Type' && name != 'bad item' ) {
arr[0].push(name);
arr[1].push(document.getRootElement().getChild('result').getChild('rowset').getChild('row').getAttribute('typeID').getValue());
};
var str = arrayToHTML(transpose(arr));
return ['spn1',str]
};
function arrayToHTML(arr) {
var i = 0;
var j = 0;
var str = '<table>';
while ( i < arr.length ) {
str = str + '<tr>';
while ( j < arr[i].length ) {
str = str + '<td>' + arr[i][j] + '</td>';
j += 1
};
str = str + '</tr>';
j = 0;
i += 1
};
str = str + '</table>';
return str
};
function htmlToArray(str) {
var arr1 = str.replace(/<tr>/g,'</tr>').split('</tr>');
var arr2 = [];
var i = 1;
var j = 1;
var x = [];
while ( i < arr1.length ) {
arr2.push([]);
x = arr1[i].replace(/<td>/g,'</td>').split('</td>');
while ( j < x.length ) {
arr2[arr2.length - 1].push(x[j]);
j += 2
};
j = 1;
i += 2
};
return arr2
};
function transpose(input) {
var output = [];
var i = 0;
var j = 0;
while ( i < input[0].length ) {
output.push([]);
while ( j < input.length ) {
output[i].push(input[j][i]);
j += 1
};
j = 0;
i += 1
};
return output
};
function direct(input) {
return input
}
The problem seems to be on the submit button because everything else is working fine. I have been looking for a workaround but that submit button is the only point of entry I can get and it will not accept more than one variable.
The problem seems to be on the submit button because everything else is working fine. I have been looking for a workaround but that submit button is the only point of entry I can get and it will not accept more than one variable.
Let's focus on this, and ignore all the irrelevant code. Basic question: how to get multiple inputs from a form to a server-side GAS function?
This example will demonstrate communication of the form object to the server, by throwing an error that contains all the received parameters. An errorHandler on the client side will alert with the received error message.
Index.html
<form id="frm1" name = "mat_add">
<input width="1000" type="text" name="mat" placeholder="Enter Item Here" /><br />
<input width="1000" type="text" name="mat2" placeholder="Enter Quantity Here" /><br />
<input type="button" value="Submit" name="mat_sub" onclick="google.script.run
.withSuccessHandler(onSuccess)
.withFailureHandler(onFailure)
.shortlist(this.parentNode)" />
</form>
<script>
function onSuccess(output) {
document.getElementById(output[0]).innerHTML = output[1];
};
function onFailure(error) {
alert( error.message );
}
</script>
Code.gs
function doGet() {
return HtmlService.createTemplateFromFile('Index').evaluate().setTitle('UMX Web App');
};
function shortlist(input) {
reportErr(JSON.stringify(input,null,2))
}
function reportErr(msg) {
throw new Error( msg );
}
Run this webapp, and here's your result:
The two named input elements, mat and mat2 were communicated to the server function shortlist() via the this.parent parameter. Since the button invoking this.parent in its clickHandler is contained in the frm1 form, all input elements of that form were included, and may be referenced on the server side as named properties of the input parameter of shortlist(). (NOT as array elements.)
The upshot of this is that your shortlist() function can be modified thusly:
function shortlist(input) {
var item = input.mat;
if ( isNaN(item) ) {
var url = 'https://www.fuzzwork.co.uk/api/typeid2.php?format=xml&typename=' + item;
} else {
var url = 'https://api.eveonline.com/eve/TypeName.xml.aspx?ids=' + item.toString();
};
...

Categories

Resources