I have managed to find out how to pull data from a excel file into HTML.
I am now trying to look how to search for values within a set of cells. Does anyone know how to achieve this?
Thanks in advance!
jQuery is likely going to help you with that. when building the HTML i would also add data-[somethingHelpfulWhenSearching] or add class values that could help.
then you can search for the item by class
$('.[searchableClassName]')
or by data attribute:
$('[data-[somethingHelpfulWhenSearching]') //only looking that the tag exists
$('[data-[somethingHelpfulWhenSearching]="something im looking for"') //only looking that the tag and checking the value
hope this helps
From the way you worded the question, it sounds like you have a table in your HTML, and you just want to loop over all of the cells to check which cells contain a given value, and return those DOM nodes that contain the provided search string within their text content. If that's an accurate interpretation, here is a Vanilla JS solution:
function findCells(str) {
var allCells = document.querySelectorAll("td");
var matchingCells = [];
for (var i = 0; i < allCells.length; i++) {
if (allCells[i].textContent.indexOf(str) !== -1) {
matchingCells.push(allCells[i]);
}
}
return matchingCells;
}
<html>
<script>
function mytest1() {
var Excel, Book; // Declare the variables
Excel = new ActiveXObject("Excel.Application"); // Create the Excel application object.
Excel.Visible = false; // Make Excel invisible.
Book = Excel.Workbooks.Add() // Create a new work book.
Book.ActiveSheet.Cells(2, 2).Value = document.all.my_textarea1.value;
Book.SaveAs("C:/temp/TEST.xls");
Excel.Quit(); // Close Excel with the Quit method on the Application object.
}
function mytest2() {
var Excel;
Excel = new ActiveXObject("Excel.Application");
Excel.Visible = false;
form1.my_textarea2.value = Excel.Workbooks.Open("C:/temp/TEST.xls").ActiveSheet.Cells(1, 1).Value;
Excel.Quit();
}
</script>
<body>
<form name="form1">
<input type=button onClick="mytest1();" value="Send Excel Data">
<input type=text name="my_textarea1" size=70 value="enter ur data here">
<br><br>
<input type=button onClick="mytest2();" value="Get Excel Data">
<input type=text name="my_textarea2" size=70 value="no data collected yet">
</form>
</body>
</html>
Since you're already using jQuery, try DataTables, which is a jQuery plugin and does a lot more than filtering for you. It allows for both client side and server side filtering, so it's not a problem if your table is large.
Related
I am pretty new to using localStorage, so excuse my ignorance and the potential repetition of this question. I couldn't get any answer yet.
I have a form with a lot of input tags. I am storing their values in a var called data var data = document.querySelectorAll( "input" ).value;
when I do window.localStorage.setItem('data', JSON.stringify(data.value))
it stores data in the storage with a value of undefined.
I get that my var data isn't really catching all the user input values, but I couldn't figure out how to do it.
My intention is to make var data an object that stores other objects that have the values of the input fields. then push this data to the localStorage. WITH PURE JS
Try this code, it writes to localStorage and reads from it to console (stackoverflow insert code tool doesn't allow to work with localStorage, that is why the code is in different JS sandbox): https://plnkr.co/edit/0e1R1aDTneQ1RA0Dvasj?p=preview
code:
<!DOCTYPE html>
<html>
<body>
<form action="/action_page.php">
First name:<br>
<input type="text" name="firstname" value="Mickey">
<br>
Last name:<br>
<input type="text" name="lastname" value="Mouse">
<br><br>
<input type="submit" value="Submit">
</form>
<script>
let data = document.querySelectorAll("input");
let formData=[];
console.log('data', data);
for(let i=0; i<data.length; i++){
formData.push({ name: data[i].name, value: data[i].value })
}
console.log("formData for localStorage", formData)
localStorage.setItem('formData', JSON.stringify(formData));
let output = localStorage.getItem('formData');
console.log('output', JSON.parse(output));
</script>
</body>
</html>
As noted in the comments, you need to loop over your inputs to get the values and then store them in localStorage. For example:
const inputs = document.querySelectorAll('input');
const data = [];
for (const input of inputs) {
data.push(input.value);
}
window.localStorage.setItem('data', data);
Also, if you are really trying to store the data as JSON (perhaps why you were trying to use JSON.stringify()), then you could do something like the following (although it would be better if your input elements had unique id or name values you could use as keys rather than just the index of the selected input as in the example below).
const inputs = document.querySelectorAll('input');
const data = {};
inputs.forEach((input, i) => {
data[i] = input.value;
});
window.localStorage.setItem('data', JSON.stringify(data));
I've been tasked with a demo for a query API our company has. For that, my boss wanted me to create a simple HTML site containing a search feature to use said API. So far, I've managed to create almost everything she wanted, but am now stuck on a rather... Peculiar problem.
I've managed to create a flexible filtering feature, allowing the user to add/remove filters as they see fit. I've done it like this:
window.onload = function init()
{
var filterSet = document.getElementsByTagName("fieldset")[0];
var filterSection = filterSet.getElementsByTagName("section");
var set = filterSection[1];
var elements = set.getElementsByTagName("*");
set.getElementsByTagName("*")[5].addEventListener("click", cloneSection);
if (filterSection.length > 2)
{
elements[6].hidden = false;
elements[6].addEventListener("click", deleteSection);
}
else
{
elements[6].hidden = true;
}
}
function cloneSection(e)
{
var filterSet = document.getElementsByTagName("fieldset")[0];
var filterSection = filterSet.getElementsByTagName("section");
var newId = parseInt(filterSection[filterSection.length - 1].id) + 1;
var set = filterSection[1];
var newSet = set.cloneNode(true);
var elements = newSet.getElementsByTagName("*");
newSet.id = "" + newId;
elements[5].addEventListener("click", cloneSection);
elements[6].hidden = false;
elements[6].addEventListener("click", deleteSection);
filterSet.appendChild(newSet);
}
function deleteSection(e)
{
var target = e.target;
var filterSet = document.getElementsByTagName("fieldset")[1];
var filterSection = target.parentElement;
filterSection.remove();
}
<fieldset>
<section>
<input type="checkbox" id="filter_query" name="feature" value="search" />
</section>
<section id="0">
<input type="text" name="filter_name">
<select id="comperason_type">
<option value="=">Equal to</option>
<option value="!=">Different then</option>
</select>
<input type="text" name="filter_value">
<input type="submit" value="+" id="AddButton">
<input type="submit" value="-" id="RemoveButton" hidden="true">
</section>
</fieldset>
It's rather basic (I'm kinda new to networking and Javascript as a whole, I'll admit), but for the most part it works just fine. Except for one single issue.
I want, when the user adds a new filter, to allow them to remove the default one created by the original markup. The button is there, I just need to set it to hidden = false and that's it. Except... When I try to do that, for some reason, the code doesn't recognize the extra section created into it. For example, if there are 3 sections in the fieldset, one created by my own code, the length count will only return 2.
Does anyone know why? Or what can I do to get it to count properly? I'm sorry if this is a newb question, but like I said, I'm a bit out of my depth here.
EDIT: Made a snippet that works this time. Sorry for making it confusing, but it should be good now.
I am attempting to get all the form values into a normal array[]. I had it working for tags but then I added some tags and can't seem to get it.
With just tags it worked with this
var content = document.querySelectorAll("#form input[name='content[]']");
I am currently trying something like this
var content = document.elements["content[]"].value;
This form can change from user input down the road as each section of the form is a module that they choose to add. It is also important to get the values in order, if that isn't possible then I would need to make it a JSON array. Pure javascript or jquery is fine either way.
Thank you for any help.
EDIT
I used this to solve my problem
var contents=[]
var content = $('#form').serializeArray()
for (var i = 0; i < content.length; i++) {
contents[contents.length]=content[i].value
};
Try
html
<form id="form">
<input type="text" name="content[]" value="abc" />
<textarea name="textarea" value="">123</textarea>
</form>
js
$(function() {
var form = $("#form");
// escape `[]`
var content = form.find("input[name=content\\[\\]]");
// array `literal declaration`
var _arr = [content.prop("value")];
// map all form values to single array
var arr = $.map(form.serializeArray(), function(v, k) {
return [v.value]
});
// array literal with `textarea` `value`
var t = [$("textarea").prop("value")];
console.log(_arr, arr, t);
// _arr: `["abc"]` , arr:`["abc", "123"]` t:`["123"]`
})
Demo.
See Arrays
I've got a table with a load of auto complete boxes in it which look like so...
<richui:autoComplete style="width:500px" name="objSelect[${newRow-1}].id" value= "" action="${createLinkTo('dir': 'object/searchAJAX')}" forceSelection = "true" maxResultsDisplayed="20" minQueryLength ="3" onItemSelect="updateHiddenInput(id,${newRow-1})" />
I've got it to call a function called updateHiddenInput when a user selects a value passing in the id selected as well as the row the autocomplete is on (this function then updates a hidden field in the same row, using the values passed in, with the ID). The function looks like so: -
function updateHiddenInput(id, num){
var objID = "objectID[" + num + "].id";
$(document.getElementById(objID)).val(id);
}
Everything works until I add a new row within my table, this pushes everything down one row and stops the autocomplete from updating the right rows hidden field (as its still referencing the old row).
Currently I have another piece of code that goes through and renames all the fields when a new row is inserted, but I have no idea how to update the autocomplete so that it passes through the right row number, anyone know how I can alter this?
The only other alternative I could think of would be to just pass through the object itself as well as the ID I can then locate the hidden based off the object, but I can't work out how to do this, any suggestions gratefully received! :S
I've tried changing
onItemSelect="updateHiddenInput(id,${newRow-1})"
to
onItemSelect="updateHiddenInput(id,this)"
Theoretically so I can just pass through the autocomplete object and from there just traverse the page to find the hidden field I want to update. However when I then attempt to use that object in my function, for example with something like: -
var mynumber = $(myobject).closest('td').find('input').val();
I always get an "undefined" returned when I try to alert back the value...
If I just put in an alert(myobject) in the function it returns AutoComplete instance0 autoLook[0].id but if I've inserted new lines the id value doesn't change (i.e the objects id is now autoLook[3].id but it still shows [0], which I think could be part of the problem but I've got now idea how I can update this value...
I notice when looking in firebug at the html there is a /script linked to the autocomplete which could be the problem as this doesn't get updated when new lines are added and I can see multiple references to the old/original id value (see below) so maybe the passing through of this isn't passing the current objects values through...?
<script type="text/javascript">
var autoCompleteDataSource = new YAHOO.util.XHRDataSource("/Framework/object/searchAJAX");
autoCompleteDataSource.responseType = YAHOO.util.XHRDataSource.TYPE_XML;
autoCompleteDataSource.responseSchema = {
resultNode : "result",
fields : [
{ key: "name" },
{ key: "id" }
]
};
;
autoComplete = new YAHOO.widget.AutoComplete('autoLook[0].id','ad186a42e45d14d5cde8281514f877e42', autoCompleteDataSource);
autoComplete.queryDelay = 0;
autoComplete.prehighlightClassName = 'yui-ac-prehighlight';
autoComplete.useShadow = false;
autoComplete.minQueryLength = 3;
autoComplete.typeAhead = false;
autoComplete.forceSelection = true;
autoComplete.maxResultsDisplayed = 20;
autoComplete.shadow = false;
var itemSelectHandler = function(sType, args) {
var autoCompleteInstance = args[0];
var selectedItem = args[1];
var data = args[2];
var id = data[1];
updateHiddenInput(id,this) };
autoComplete.itemSelectEvent.subscribe(itemSelectHandler);
</script>
My thanks so far to user1690588 for all his help thus far! :)
On further digging I'm convinced that my issues is down to the line autoComplete = new YAHOO.widget.AutoComplete('autoLook[0].id','a5b57b386a2d1c283068b796834050186', autoCompleteDataSource); specifically the part where its inputting autoLook[].id and if I could change this I'd then be ok, but this line is auto generated and I've got no idea how to update it, anyone have any similar experience?
I have not much idea about your gsp page but I tried it on my side:
My gsp:
<!DOCTYPE html>
<html>
<head>
<resource:autoComplete skin="default"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript">
var counter = ${list.size()};
function asd() {
jQuery.ajax({
url: " ${createLink(controller: 'oauthCallBack', action: 'testAuto')}",
data: "idx=" + counter++,
success: function (data) {
jQuery("#tableId").append("<tr><td>" + data + "</td></tr>");
}
});
}
function updateHiddenInput(id, tg) {
jQuery(tg).val(id);
}
</script>
</head>
<body>
<g:form>
<table id="tableId">
<g:each in="${list}" var="vr" status="idx">
<tr>
<td>
<richui:autoComplete name="name" id="uniqueId${idx}" action="${createLinkTo('dir': 'oauthCallBack/test')}" onItemSelect="updateHiddenInput(id, someId${idx})"/>
<g:hiddenField name="someName" id="someId${idx}" value=""/>
</td>
</tr>
</g:each>
</table>
</g:form>
<button onclick="asd()">Add</button>
</body>
</html>
My action:
def testAuto() {
render template: 'addNew', model: [idx: params.idx]
}
My template(addNew):
<richui:autoComplete name="name" id="uniqueId${idx}" action="${createLinkTo('dir': 'oauthCallBack/test')}"
onItemSelect="updateHiddenInput(id, someId${idx})"/>
<g:hiddenField name="someName" id="someId${idx}" value=""/>
Try this..,.
EDIT.....................................................................................
I supposed that you have successfully updated all the input field names. Then you can edit hidden field like:
View:
<tr class="dummyClass">
<td>
<richui:autoComplete name="name[${idx}]" id="uniqueId[${idx}]" action="${createLinkTo('dir': 'oauthCallBack/test')}" onItemSelect="updateHiddenInput(id, this)"/>
<g:hiddenField name="someName[${idx}]" id="someId[${idx}]" value=""/>
</td>
</tr>
jQuery:
function updateHiddenInput(id, tg) {
jQuery(tg._elTextbox).closest("tr.dummyClass").find("input[type=hidden]").val(id);
}
EDIT.....................................................................................
Why you need to change the 'id'? Changing name is sufficient to send values in order. And you can update the hidden field without id as above edit.
If you still need to change the id then you can change it by cloning the tr and then use regex. See this answer for full working example.
I am trying to put together what I thought would be an easy solution for a friend.
He has a list of fan emails that he collects at gigs and off his website.
He sticks them in a single column file and saves them.
He needs to have them in comma delimited format containing 150 each, one single line.
He wants a "simple" local HTML form he can paste the list into and have the results displayed.
So, I started working on it but, it has proven past my ability.
So far I have some basics but, I really need help.
As you can see, I am really a beginner.
<html><head>
<script type="text/javascript">
function makeit(){
var enteredEmails = document.getElementById("emails").value;
var cnt = document.getElementById("breakcnt").value;
var mails = enteredEmails.toString();
var textareacnt = '1';
// Now I think I need to loop or create arrays of emails up to cnt //
csvmails = mails.splice(0,cnt)
// Then dynamically generate some textareas or boxes populated with a single comma delimited line of cnt" emails //
document.write("<textarea id=\"textareacnt\">" + csvmails + "</textarea>")
textareacnt++;
}
</script>
</head><body>
<form onsubmit="makeit();">
<textarea name="emails" id="emails" rows="10" cols="75"></textarea><br />
<input type="text" name="breakcnt" id="breakcnt"><br />
<input type="submit" name="submit" value="submit">
</form>
<textarea id="results"></textarea>
</body></html>
The textarera will have emails pasted into it like:
amail1#sometld.com
bmail1#sometld.com
cmail1#sometld.com
amail4#sometld.com
zmail10#sometld.com
... up to 6000 fan emails he has collected over the years
He needs the results to be:
amail1#sometld.com,bmail1#sometld.com,cmail1#sometld.com,amail4#sometld.com,zmail10#sometld.com
up to 150 emails long as I am sure the last chunk or array will not contain 150.
I cant get anything to work and I spent 6 hours on this so far.
Can someone please help? I feel like a complete idiot.
All you have to do is split the text into an array and then splice the array in a loop and join the slices you take out like this:
var emails= document.getElementById('emails').value.split(/\s+/), list="";
while(emails.length) {
list+=emails.splice(0,150).join(',')+"\n";
}
//list now has the result you are looking for
I have made an example of how to this here: http://jsfiddle.net/PfB42/2/
All you have to do is paste the emails into the text area and it will automatically change the format to the one you are looking for, and insert it to the <pre> area below the textarea
This should achieve what you want.
Don't be so hard on yourself mate :)
<html><head>
<script type="text/javascript">
function makeit(){
var enteredEmails = document.getElementById("emails").value;
var results = document.getElementById("results");
var index = 0;
var index2 = enteredEmails.indexOf("\n");
while(true) {
results.value += enteredEmails.substring(index, index2);
index = index2+1;
var index2 = enteredEmails.indexOf("\n", index+1);
//EOF
if(index2 == -1) {
results.value += ",";
results.value += enteredEmails.substring(index, enteredEmails.length);
break;
} else {
results.value += ",";
}
}
}
</script>
</head><body>
<form onsubmit="makeit();">
<textarea name="emails" id="emails" rows="10" cols="75"></textarea><br />
<input type="button" value="submit" onclick="makeit()">
</form>
<textarea id="results"></textarea>
</body></html>
Ouch, don't use that complicated scripts. Strings have functions exactly for that purpose:
var input = document.getElementById("emails").value;
input = input.replace(/\r\n/g, "\n"); // I hate this
var emails = input.split("\n"); // make an Array
var output = emails.join(","); // should we use ", " instead?
Of course you could put everyhing in one line ;-)