Get values by class - javascript

I tried for hours but could not find any solution.
Simplified my code looks like following.
PHP :
foreach($db->query("SELECT id FROM news ORDER BY position ASC") as $row)
{
...
<input type="text" class="_title" >
Search: <input type="file" class="_file" >
<input type='button' class="_submit" value='Save' >
...
}
?>
JS :
$(document).ready(function(){
$("._submit").click(function(){
?? var _title = document.getElementById('_title'),
?? _file = document.getElementById('_file');
var data = new FormData();
data.append('SelectedFile', _file.files[0]);
data.append('title', _title.value);
...
</script>
I don't know how to get the data by class. By ID it is working, but i can't use IDs, because there would be several same IDs because of the foreach loop.
Tried this as well without success:
var _file = document.getElementsByClassName('_file');
I hope somebody can help me.
Misch

You can wrap your elements in container div like
<?php
foreach($db->query("SELECT id FROM news ORDER BY position ASC") as $row)
{
...
<div class='container'>
<input type="text" class="_title" >
Search: <input type="file" class="_file" >
<input type='button' class="_submit" value='Save' >
</div>
}
?>
Then use .closest() to traverse up the container. After wards you simply use find to get the desired elements.
<script>
$(document).ready(function(){
$("._submit").click(function(){
var container = $(this).closest('.container');
var _title = container.find('._title'),
var _file = container.find('._file')[0];
var data = new FormData();
data.append('SelectedFile', _file.files[0]);
data.append('title', _title.value);
//Rest of your code
});
});
</script>

Since you're using jquery you could use .each() function and class selector . to loop through all the element with same class :
$('.class').each(function(){
var input_value = $(this).val();
})
Since you have more than one field with class _title and _file you should pass them as array to Formdata() using array signs [] :
var data = new FormData();
$('._file').each(function(){
var _file = $(this).val();
data.append('SelectedFile[]', _file.files[0]);
})
$('._title').each(function(){
var _title = $(this).val();
data.append('title[]', _title);
})
Hope this helps.

One more thing you can do a bit same as #satpal
Wrap your code in a div element.
PHP:
foreach($db->query("SELECT id FROM news ORDER BY position ASC") as $row)
{
...
<div> <!-- wrapper -->
<input type="text" class="_title" >
Search: <input type="file" class="_file" >
<input type='button' class="_submit" value='Save' >
</div>
}
?>
Then try following code.
JS:
$("._submit").click(function(){
var title = $(this).siblings('._title').val();
var file = $(this).siblings('._file')[0].files[0];
var data = new FormData();
data.append('SelectedFile',file);
data.append('title', title);
});
The above code makes use of .siblings() function

Related

How do I get cell values on click event from webpage tabs after the first one?

I have tried javascript and JQuery. I know how to write the code to get the cell values from my first tab but the same function does not work on the other tabs on my webpage. It seems as if the table in my other tabs is just a view. I am new to javascript and JQuery so think I might be missing something easy. I have used ".on" in my click function and that doesn't help. Here is the Javascript code and JQuery code, both work by grabbing the cell value I click but only for the first tab:
JavaScript
init();
function init(){
addRowHandlers('customerTable');
}
function addRowHandlers(tableId) {
if(document.getElementById(tableId)!=null){
var table = document.getElementById(tableId);
var rows = table.getElementsByTagName('tr');
var cid = '';
var name = '';
for ( var i = 1; i < rows.length; i++) {
rows[i].i = i;
rows[i].onclick = function() {
cid = table.rows[this.i].cells[0].innerHTML;
name = table.rows[this.i].cells[1].innerHTML;
alert('cid: '+cid+' name: '+name);
};
}
}
}
JQuery
$('#customerTable').find('tr').click(function() {
var $id = $(this).closest("tr")
.find(".custId")
.text();
var $name = $(this).closest("tr")
.find(".custName")
.text();
alert($name);
$('.defaultTextBox.text_custId:text').val($id);
$('.defaultTextBox.text_custName:text').val($name);
});
In the end my goal is to get the elements clicked and set the text in my text boxes to those values, which you can see I did in the JQuery, but it only works on my first page. I need the click in my table to work on all tabs. Thanks in advance!
Edit
<div id="removeCustomer" class="tabcontent">
<h3>Pick a customer to remove!</h3>
<div class="container">
<br />
<h2 align="center">Search here to find the customer you want to remove</h2><br />
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">Search</span>
<input type="text" name="search_text" id="search_text" placeholder="Search by name, phone number, email, or state" class="form-control" />
</div>
</div>
<br />
<div class="result"></div>
</div>
</div>
The "removeCustomer" id is one of the tabs. So I have multiple tabs using the same, "result", which I think is the problem I just do not know how to solve it. If I Left out "result" it would not generate a table.
Here is the JQuery which uses a php file to connect to my database and get my data. And this is what generates result.
JQuery
$(document).ready(function(){
load_data();
function load_data(query)
{
$.ajax({
url:"fetchCustomers.php",
method:"POST",
data:{query:query},
success:function(data)
{
$('div.result').html(data);
}
});
}
$('input.form-control').keyup(function(){
var search = $(this).val();
if(search != '')
{
load_data(search);
}
else
{
load_data();
}
});
});
Thanks again.

Read txt file to array + increment variable on click to access next array element: PHP or Javascript?

I am reading a short text file on server into a PHP variable ($data), and first accessing the first 2 items in the array to display them.
Then when the user clicks one of the items (which also sends form data) I want to increment the PHP variable that specifies the array item ($counter).
Reading from the file seems to be easiest to do with PHP, but incrementing at click seems easier with Javascript - and I can't figure out a good way to forge the two. What is the best way to solve this? I am fairly new to both languages.
The php/html code for reading from file (working):
<?php
function getData($subtest_nr) {
$data = file("subtests/$subtest_nr.txt");
return $data;
}
$subtest_nr = "7";
$counter = 0;
$data = getData($subtest_nr); ?>
<form id="myform" method="post">
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
</form>
A quick attempt at incrementing variable in jQuery:
jQuery(function($) {
var counter = 0;
$("img").click(function(){
counter++;
$("p").text(counter);
});
});
So my question is if I should aim for either only PHP or Javascript/jQuery for both functionalities or if there is a way for me to merge the two?
Further to the comments, here's an approach that combines the font-end and the back-end into a single file.
The file makes use of the $_SERVER['PHP_SELF'] variable to find the name of the file that's executing. We use this to write the correct name of the backend php file to request into the javascript - this has the effect of allowing us to name the single-file solution anything we want and not worry about updating a hard-coded url somewhere in the source. (got a sore head yet? :p )
index.php
<?php
if ( isset($_GET['firstItem']) && isset($_GET['numItems']) )
{
$firstItem = $_GET['firstItem'];
$numItems = $_GET['numItems'];
// should do error checking here
$subtestNumber = 7;
$filename = sprintf("subtests/%d.txt", $subtestNumber);
// dummy, used for testing
$filename = 'sampleInput.txt';
$fileHandle = fopen($filename, "rt");
for ($numLinesToSkip=0; $numLinesToSkip<$firstItem; $numLinesToSkip++)
fgets($fileHandle);
$results = array();
for ($itemCount=0; $itemCount<$numItems; $itemCount++)
{
$curLine = fgets($fileHandle);
//
// you may wish to remove the trailing new-line character here
//
array_push($results, $curLine);
}
fclose($fileHandle);
echo json_encode($results);
die; // stop execution now - dont output the html below
}
?><!doctype html>
<html>
<head>
<script>
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
// useful for HtmlCollection, NodeList, String types
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){if (this.readyState==4 && this.status==200) onLoad(this);}
ajax.onerror = function() {error.log("ajax request failed to: "+url);onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('goBtn').addEventListener('click', onGoBtnClicked);
}
function onGoBtnClicked(evt)
{
var firstIndex = byId('firstRecordInput').value;
var numItems = byId('numRecordsInput').value;
// we want to request data from this same file, so get php to print it into the javascript source
var filename = '<?php echo $_SERVER['PHP_SELF'];?>';
// construct the url from the filename and the (GET) parameters we'd like to pass to the php
var url = filename + '?firstItem=' + firstIndex + '&numItems=' + numItems;
// ask for it, fire the onDataReceived function with the XMLHttpRequest object as the only input
ajaxGet(url, onDataReceived, function(){alert('ajax failed! :(');} )
}
/*
------------------------------------------------------------
format of html the onDataReceived function needs to create
- .four_images div just once for the whole response
- .flex-item once for each item returned
------------------------------------------------------------
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
*/
function onDataReceived(ajax)
{
// get the raw data - it'll be a string something like `["file1.txt\n","file2.swf\n"]`
var rawData = ajax.response;
// parse it and turn it from a string into some javascript objects.
// this has same the effect as typing the following into your source-code
//
// var parsedData = [ "file1.txt\n", "file2.swf\n" ];
//
// except, you can do it with unknown data. BUT: we must know the *format*
// of the data so we know what to do with it. We happen to know that
// the data will be an array
var parsedData = JSON.parse(rawData);
// make the outer wrapper - refer above for the structure of the created HTML
// this wrapper needs to exist so the makeItem function can append content
// to it in the forEach call
var div = newEl('div');
div.className = 'four_images';
// for each of the items in the parsedData array, call the makeItem function - once this forEach call is done,
// we have the contents of the form all sitting in the [div] element - the makeItem function is inside this onDataReceived function
// so that it can 'see' the [div] variable in order to append each item to it.
forEach(parsedData, makeItem);
// show the results
byId('myForm').innerHTML = '';
byId('myForm').appendChild(div);
// this function has now finished executing. the makeItem function exists here (unfortunately) so that
// the [div] element remains in scope.
// called with the current element in the collection as dataItem, it's index in the collection as index and the collection itself as arrayOfItems
// we're making use of the item's index to correctly set the id of the radio-button and then to make the label refer to it (which it doesn't actually
// need to do in this case, since the label element contains the input)
// another use of index is to place a comma between items i.e "1,2,3,4,5,6" - there are two approaches. The naive one is to place a comma after each
// item except the last one. To do this - we need to know how many items there are in total - sometimes this is very expensive to compute.
// the other approach, is to put a comma _before_ all items except the first one.
function makeItem(dataItem, index, arrayOfItems)
{
var itemDiv = newEl('div');
itemDiv.className = 'flex-item';
var input = newEl('input');
input.type = 'radio';
input.name = 'image';
input.value = 'putSomethingUsefulHere'; // **** the example had 7.11 and 7.12 here - I've no idea how they were determined ***
input.id = "alt" + (index+1);
input.className = 'hidden';
var label = newEl('label');
label.for = 'alt' + (index+1);
var img = newEl('img');
img.src = 'images/' + dataItem;
label.appendChild(img);
itemDiv.appendChild(input);
itemDiv.appendChild(label);
div.appendChild(itemDiv);
}
}
</script>
<style>
.panel
{
border: solid 1px black;
border-radius: 8px;
padding: 8px;
background-color: #eef;
display:inline-block;
}
</style>
</head>
<body>
<div class='panel'>
<label>Index of first record: <input type='number' id='firstRecordInput' value='0'/></label><br>
<label>Number of records: <input type='number' id='numRecordsInput' value='2'/></label>
<hr>
<div style='text-align: center'><button id='goBtn'>Retrieve records</button></div>
<hr>
<form id='myForm'>
</form>
</div>
</body>
</html>
Here's a rough example, sans error checking. I don't jQuery, so you'll need to convert this to make use of jQuery's ajax method. Can't tell what you're trying to achieve with each image click either, so you can edit that back in.
My primary aim, was to show a means by which the front-end can maintain state information and can use this to request to desired info from a (dumb) backend.
sampleInput.txt
file1.txt
file2.swf
file1.pdf
file1.exe
file1.asm
getItems.php
<?php
$firstItem = $_GET['firstItem'];
$numItems = $_GET['numItems'];
// should do error checking here
$subtestNumber = 7;
$filename = sprintf("subtests/%d.txt", $subtestNumber);
// dummy, used for testing
$filename = 'sampleInput.txt';
$fileHandle = fopen($filename, "rt");
for ($numLinesToSkip=0; $numLinesToSkip<$firstItem; $numLinesToSkip++)
fgets($fileHandle);
$results = array();
for ($itemCount=0; $itemCount<$numItems; $itemCount++)
{
$curLine = fgets($fileHandle);
//
// you may wish to remove the trailing new-line character here
//
array_push($results, $curLine);
}
fclose($fileHandle);
echo json_encode($results);
?>
getStuff.html
<!doctype html>
<html>
<head>
<script>
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
// useful for HtmlCollection, NodeList, String types
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){if (this.readyState==4 && this.status==200) onLoad(this);}
ajax.onerror = function() {error.log("ajax request failed to: "+url);onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
/////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('goBtn').addEventListener('click', onGoBtnClicked);
}
function onGoBtnClicked(evt)
{
var firstIndex = byId('firstRecordInput').value;
var numItems = byId('numRecordsInput').value;
var url = 'getItems.php?firstItem=' + firstIndex + '&numItems=' + numItems;
ajaxGet(url, onDataReceived, function(){alert('ajax failed! :(');} )
}
/*
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
*/
function onDataReceived(ajax)
{
var rawData = ajax.response;
var parsedData = JSON.parse(rawData);
var div = newEl('div');
div.className = 'four_images';
forEach(parsedData, makeItem);
byId('myForm').innerHTML = '';
byId('myForm').appendChild(div);
function makeItem(dataItem, index, arrayOfItems)
{
var itemDiv = newEl('div');
itemDiv.className = 'flex-item';
var input = newEl('input');
input.type = 'radio';
input.name = 'image';
input.value = 'putSomethingUsefulHere';
input.id = "alt" + (index+1);
input.className = 'hidden';
var label = newEl('label');
label.for = 'alt' + (index+1);
var img = newEl('img');
img.src = 'images/' + dataItem;
label.appendChild(img);
itemDiv.appendChild(input);
itemDiv.appendChild(label);
div.appendChild(itemDiv);
}
}
</script>
<style>
.panel
{
border: solid 1px black;
border-radius: 8px;
padding: 8px;
background-color: #eef;
display:inline-block;
}
</style>
</head>
<body>
<div class='panel'>
<label>Index of first record: <input type='number' id='firstRecordInput' value='0'/></label><br>
<label>Number of records: <input type='number' id='numRecordsInput' value='2'/></label>
<hr>
<div style='text-align: center'><button id='goBtn'>Submit</button></div>
<hr>
<form id='myForm'>
</form>
</div>
</body>
</html>
I guess the data you got is ajax data. So need to be $(document).on(...
var counter = 0;
$(document).on('click','img', function(){
counter++;
$("p").text(counter);
});

Jquery | Add value to name which is attribute of input

I want to add $(this) value when the button is clicked.
uhm. let me show you my code below first.
$("#filenameList button").click(function(){
$(this).parent().remove();
});
$("#file").change(function(){
$("#filenameList div.notyet").remove();
for(var i = 0, len = this.files.length; i < len; i++){
var file = this.files[i];
var fr = new FileReader();
fr.onload = (function (file) {
return function(e) {
var div = document.createElement("div");
$(div).addClass("notyet").css({
margin : "30px"
,position : "relative"
});
//var html = ['<input type="hidden" name="screenshots_filename[]" value="' + file.name + '">'
var html = ['<img src="" width="100%">'
,'<input type="hidden" name="">'
,'<button type="button" class="close img-close" aria-label="Close"><span aria-hidden="true">×</span></button>'
].join("");
$(div).append(html);
$(div).find("button").click(function(){
$(this).parent().remove();
});
$(div).find("img").attr("src", e.target.result);
$("#filenameList").append(div);
}
})(file);
fr.readAsDataURL(file);
}
});
All i want to do is verify which element is removed by clicking the button so that i add the value to name attribute that is hidden above html variable.
How can i do this?
<div class="col-xs-4 vcenter from-group">
<h1>test</h1>
<input id="file" type="file" name="inputScreenshots[]" accept="image/*" multiple>
<div id="filenameList" style="width : 400px">
<?
$str = $screenshot_urls;
$arr = explode("+", $str);
foreach ($arr as $filename) {
?>
<div style="margin : 30px; position :relative;">
<input type="hidden" name="screenshots_filename[]" value="<?=$filename?>">
<img src="<?="http://cspmedia.net:3001/gp_images/ames/".$filename?>" width="100%">
<button type="button" class="close img-close" aria-label="Close"><span aria-hidden="true">×</span></button>
<input type="hidden" name=""> // TODO HERE ##
</div>
<? } ?>
</div>
okay here is the html code. and i really sorry. i was so confused.
I move the todo to bottom code.
I want to know the list of element which is clicked by the button.
I figured out like this. Im new in php so i totally confused about client and server because they are all in just one page.
Anyway this is the code what i wanted. sorry guys.
$("#filenameList button").click(function(){
var targetDom = document.getElementById( "filenameList" );
var targetInput = document.createElement("input");
targetInput.setAttribute("name", "del_img[]" );
targetInput.setAttribute("type","hidden");
targetDom.appendChild(targetInput);
//alert(targetInput.getAttribute("name"));
var filename = $(this).parent().find("input[name='screenshots_filename[]']").val();
alert(filename);
targetInput.setAttribute("value", filename);
$(this).parent().remove();
});
Why i wrote this code is submitting the value and deleting the file in the server.
if (isset($_POST["del_img"])) {
echo "<br/>del_img[] isset";
$tmp = $_POST["del_img"];
// TODO : delete images in server
foreach ($tmp as $value) {
echo "<br/> Unlnk image ::: ".$value;
unlink("http://cspmedia.net:3001/gp_images/games/".$value);
}
}
$('Selector( 'whose value you want to set' )').attr('value',$(this).val());
For example like given below
$('input[type="hidden"]').attr('value',$(this).val());
$(div).find("button").click(function(){
$(this).parent().remove();
// TODO : I want add $(this).val() to input name attribute
});
But note that here you will set the value of button which will gonna clicked.
because in you code $(this) will refer to button as it is picking the that by
.find("button")
Not certain if requirement is to set name at <input type="hidden" name=""> to current file , or previously user selected file , before current change event ?
Solution below attempts to set name at <input type="hidden" name=""> within html array to current file.name
$("#filenameList button").click(function(){
$(this).parent().remove();
});
$("#file").change(function(){
$("#filenameList div.notyet").remove();
for(var i = 0, len = this.files.length; i < len; i++){
var file = this.files[i];
var fr = new FileReader();
fr.onload = (function (file) {
return function(e) {
var div = document.createElement("div");
$(div).addClass("notyet").css({
margin : "30px"
,position : "relative"
});
//var html = ['<input type="hidden" name="screenshots_filename[]" value="' + file.name + '">'
var html = ['<img src="" width="100%">'
,'<input type="hidden" name="'+file.name+'">'
,'<button type="button" class="close img-close" aria-label="Close"><span aria-hidden="true">×</span></button>'
].join("");
$(div).append(html);
$(div).find("button").click(function(){
$(this).parent().remove();
});
$(div).find("img").attr("src", e.target.result);
$("#filenameList").append(div);
}
})(file);
fr.readAsDataURL(file);
}
});

jQuery - set .html() to element by it's data-for attribute

please, is there any way to put content into element with not know id or class, but by it's attribute? I have somewhere on the page more of this twins:
<input id="someSpecialId" class="autocomplete"/>
<ul data-for="someSpecialId"></ul>
List can be anywhere on page, not next to input.
In jQuery I have this:
$(document).on('keyup', '.autocomplete', function() {
var sectionName = 'autocomplete';
var min_length = 2;
var inputID = $(this).attr('id');
var keyword = $(this).val();
var $output = // HERE I NEED TO PUT FOUND ELEMENT BY IT'S data-for = inputID
if (keyword.length >= min_length) {
$.ajax({
url: 'php/readDB.php',
type: 'POST',
data: {section: sectionName, keyword:keyword},
success:function(data){
$output.show();
$output.html(data);
}
});
} else {
$output.hide();
}
});
Do you have any ideas, please? Thank you very much for answer.
var $output = $('[data-for="'+inputID+'"]');
The attribute equals selector.
You can use selector attributes for this. In general they look like this: [attribute="value"]
In your case, you would use something like this:
$('ul[data-for="'+inputID+'"]');
These work both in CSS and jQuery. Here's a code snippet with an example for both:
$('[data-for="second_input"]').html("<li>Item</li>");
[data-for="second_input"] {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input type="text" id="first_input" />
<ul data-for="first_input"></ul>
<input type="text" id="second_input" />
</div>
<ul data-for="second_input"></ul>

javascript array empty using .push .text

I am having an issue with the code that I was given as an example from a previous SO question - it is working about 95% but the order array is appearing empty why?
HTML:
<input class="order" value="<?php echo $order; ?>" type="text" />
JS:
$('body').on("click", "#brands_by_category_submit_btn", function (e) {
e.preventDefault();
var self = $(this);
var order = [];
var id = $("#manID").data("id");
var brand_name = $("#brand_name").data("id");
var data = grabData(true);
$(".order").each(function(){
order.push($(this).text());
})
if(data.length)
{
var data_array = {
id : id,
brand_name : brand_name,
cat_id : data,
order : order,
state : 1
};
.text() returns the text content of a node, like <p>this text here</p>. An <input /> element doesn't have text content, so $('input').text() will just return an empty string. Your order array should be an array of empty strings then. Maybe you want to extract the values?
$(".order").each(function(){
order.push($(this).val());
});
How about:
order.push($(this).val());

Categories

Resources