I have trouble with this code..
I'm making a "zoo system", where using button click (its value=type of animal) it adds me new item (<select> of animals) of that type. The problem I have, is that I am not able to determine (because I'm using button, not submit and its $_POSTS), which of the 10 types of animals (10 buttons with different captions (e.g. "Add birds", "Add mammals", etc.) and different values of button) was "chosen" with the click.
And when I "Add birds", I'd like to create not only the <select> with particular birds, but I also want to create next element (e.g. next <select> with the color of its feathers). For each type, I'd like to have different element that I'd like to add to that stable <select>.
In my code, there's newdiv.innerHTML = \"$animals[1]\";, because it is working well if I manually put the value inside (it generates me select of animals with id_type=1).
$anim = array();
$res = mysqli_query($db,"SELECT * FROM animals ORDER BY name");
while ($arr = mysqli_fetch_assoc($res)) {
$anim[$arr['id_type']][] = "<option value='".$arr['id_animal']."'>".$arr['name']."</option>";
$animals[$arr['id_type']]= '<select name=id_anim[]>' . implode(' ', array_values($anim[$arr['id_type']])) . '</select>';
}
$anim_type = "";
$types = mysqli_query($db, "SELECT id_type, name_type FROM type_animals ORDER BY id_type");
while ($t = mysqli_fetch_assoc($types)) {
$anim_type .= "<button type='button' name='atype' value='".$t['id_type']."' onclick=\"zoo('dynamicInput', '".$t['id_type']."');\">Add ".$t['name_type']." </button>";
}
echo"
<script type=\"text/javascript\">
function zoo(divName, atype){
var newdiv = document.createElement('div');
newdiv.innerHTML = \"$animals[1]\";
document.getElementById(divName).appendChild(newdiv);
}
</script> ";
Do you think, it's somehow possible to differentiate which of the button was pressed so I can i.e. in JS have switch where for each number (value of pressed button, value of id_type), I can specify what content should be generated?
Or is it possible to generate content with PHP instead of JavaScript (so I can use something like $_POST - although it's just a button, not a submit)?
How can I use that passed value in JavaScript code, to generate more content due to that value? I see the foolish way, to manually insert 10 values, and for everyone set it's full content. But I'd like to see the smart way (i.e. the stable core, and the switch which generates its own content for each value)..
edit for #tttpapi: the generated code is:
stable: 4x <button type='button' name='atype' value='1-4' onclick=\"zoo('dynamicInput', '1-4');\">Add birds/mammals/beasts/herbivores </button>
generated after "birds" clicked:
<select name=id_anim[]><option value='1'>Parrot</option> <option value='2'>Pelican</option> <option value='3'>Hummingbird</option></select>
And this all is, in latter code coated in:
<form method='POST'><fieldset>
<div name='dynamicInput'></div>
</fieldset></form>
Thanks a lot ;)
You can get the value of the button click with
$button = $_POST["nameOfButton"];
Here replace "nameOfButton" with "atype".
Note: You need to put the same button name tag on the different buttons.
Related
I'm having a problem in a simply js function. I have a web page where I show records in a table, and when I click on an icon (which stands for 'change this record'), that cell of table should be replaced with a dropdown menu in which the user can select the new value for that record based on the available ones.
I tried in a lot of ways:
function clickOnModifyProfessor(id, professors) {
let select = document.createElement("select");
select.setAttribute("id", id);
for (let i = 0; i < professors.length; i++) {
let el = document.createElement("option");
el.textContent = professors[i]['name'] + " " + professors[i]['surname'];
el.value = professors[i]['professorID'];
select.appendChild(el);
}
//I set id=2 simply to test with one specific record, if it works I'll just set another parameter to generalize the change.
const node = document.getElementById("2");
node.textContent = '';
node.appendChild(select);
}
With this code I just get the empty table cell after clicking on the modify button, but the strange thing is that if I try to create another element (textarea, password etc) it works perfectly, so I can't understand why it does this only with the select element. I also tried by creating the whole select with option elements and taking it to the table cell by the innerHTML, but it doesn't works (as before, it works with others elements that aren't 'select').
If it can help, here is the code fragment where I call this function:
echo "<tr><td>" . $row['subjectName'] . "</td>
<td id='" . $rowsCount . "'>
<p>" . $row['profName'] . " " . $row['profSurname'] . "
<i class='material-icons' onclick='clickOnModifyProfessor(" . json_encode($row['subjectName'], JSON_HEX_APOS) . "," . json_encode($professors, JSON_HEX_APOS) . ")'>create</i>
</p>
</td>
</tr>";
PS: I also tried to print in console document.getElementById(id).innerText after I append the new 'select' element to the document and it prints correctly the options I added.
Am I making an error? I hope it's sufficiently clear.
I answer my own question with the solution I found, maybe it can be helpful for someone.
The problem is that the materialize css' select can't render on browser without starting js before, so it's necessary to add class='browser-default' when we create the select element or, if we want materialize css select style, we need to use $('select').formSelect(); after the select element has been created with its options.
I have a PHP sql query that returns a table.
while($row = $result->fetch_assoc()) {
echo "<tr><td id=\"cst\"><button type=\"submit\" id=\"click\" onClick=sendData(this)>".$row["Name"]</button></td></tr>";
The table is output correctly. My next step is using vanilla Javascript to pull the HTML text value associated with $row["Name"] from the button in the output table (when the button is clicked). I call the function onClick=sendData(this)
Now, in Javascript I'm attempting to access the text value like so:
function sendData(name) {
var text = name.innerText;
}
However, this isn't working. Can anyone explain why?
There are multiple problem with how you are using both PHP and JavaScript here to solve this problem.
Let me break them down, and how best we can solve them.
Your ID's are the same : When you're iterating through the rows in your table, you're not setting a unique id for them. This means if you try to reference them later on in any capacity via JavaScript you won't be able to. Instead, you can change this to something like, <td id=\"cst_$row['row_id']\".
Your PHP is prone to SQL Injection : The method you're using to query your database is most likely prone to SQL Injection based on how I see you are returning your values. You'd be best to read up on Prepared Statements and PDO.
You don't have quotation marks around your onclick : because you haven't wrapped your function in quotation marks, it actually won't even be sending correctly. However, there is a better solution anyway. Remove the on-click from your button, and add an event listener.
Your button type is of submit : because you've set your button type to submit, the default behavior is to refresh the page. If you want to keep this, you'd have to specify not to use the default behavior, or simply change the button type, to button.
To solve all of these issues (except SQL Injection because this would require more information than was provided), your code could be changed to the following :
PHP :
while($row = $result->fetch_assoc()) {
echo "<tr><td id=\"cst_$row['row_id']\"><button class=\"test_buttons\"type=\"button\" id=\"btn_$row['row_id']\"".$row["Name"]</button></td></tr>";
In the above example, "row_id" is your unique identifier in your database table. Change this to "id" or whatever you have called it in your table.
JavaScript :
window.onload = function() {
let buttons = document.getElementsByClassName("test_buttons"); // Get all buttons you want to search for
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", function(event) { // On click of these buttons
event.preventDefault(); // This is required only if you want to keep the button type of submit
let text = this.textContent;
alert(text);
});
}
}
<td><button type="button" class="test_buttons">Test 1</button></td>
<td><button type="button" class="test_buttons">Test 2</button></td>
The yet another variant is to improve formatting of your HTML output by taking advantage of HEREDOC syntax that suits well for complex formatting
while($row = $result->fetch_assoc()) {
echo <<<HTML
<tr>
<td class="cst"> <!-- class instead `id` -->
<button
type="button" <!-- `button` type instead of `submit` -->
class="btn-click" <!-- class instead `id` -->
data-name="{$row["Name"]}">
{$row["Name"]}
</button>
</td>
</tr>
HTML;
And using vanilla JS it is possible to make smth. similar to the result snippet below.
document.addEventListener('click', function(event) {
var target = event.target;
// If the clicked element doesn't have the right selector, bail
if (!target.matches('.btn-click')) {
return;
}
var name = target.getAttribute('data-name');
alert('Button `data-name` is "' + name + '"');
// sendData logic goes further ...
}, false);
<tr>
<td class="cst">
<button type="submit" class="btn-click" data-name="Coockaracha">Reveal my name</button>
</td>
</tr>
The approach of using global click listener is called event delegation and has some advantages. You can read about it here.
Also keep in mind that id should be unique across the page, so it is not correct to iterate using id. class attribute suits nicely and allows multiples.
Three days and I cannot find an answer to this or a solution. I am far from being a jQuery guy.
User arrives at a php page that shows a form to choose the language code and submit. Form gets submitted and the jQuery response builds a table in a div container in the original page. So far so good. The resulting table contains hundreds of rows where the language variables can be edited. On clicking the edit button, I get nothing, no errors in console, nothing. If I use on click, I can fire an alert. On submit, bind, and many others do not work.
I am attempting to load the table, perform basic editing, submit the edits to the db, and refresh the div.table.row with the edited results. I have not gotten to the part where I refresh the rows with the edited data, still stuck trying to submit the dynamic form in each row.
One interesting thing that happens when I use on click, it works with just the first button I click on, it somehow disables all the other rows. I need to be able to submit a row for changes, have that row refresh and move on to the next row all without redirecting. Is this too much to ask? Or should I just move them from page to page?
The ajax php page returns the table using the following code:
if(!empty($_POST['edit_language']) && $_POST['edit_language'] == 1){
edit_language($_POST['lang']); //call function to edit language
} else {
echo "You got here but no variables<br>"; //testing
print_r($_POST); //testing
}
function edit_language($lang){
//query table to get language vars list
$sql = "SELECT lang_site.lid, lang_codes.iso_code, lang_codes.`language`, lang_varnames.varid, lang_varnames.varname, lang_site.varval FROM lang_codes LEFT JOIN lang_site ON lang_site.langid = lang_codes.langid LEFT JOIN lang_varnames ON lang_site.varid = lang_varnames.varid where lang_codes.iso_code = '" . $lang . "'";
$result = db_query($sql);
//generate report table
echo "<table cellspacing='0' border='1'><tr><th>Count</th><th>Language</th><th>Variable Id</th><th>Variable Name</th><th>Variable Value</th><th>Edit</th></tr>";
$a=1; //count the rows to number the rows for easy viewing
while($data = db_fetch_assoc($result)){
//create form in each tr
echo "<form name='edit_" . $data['lid'] . "' id='edit_" . $data['lid'] . "' action=''><tr><td>" . $a++ . "</td><td>" . $data['language'] . "</td><td>" . $data['varid'] . "</td><td>" . $data['varname'] . "</td><td><textarea class='form-control' name='varval' id='varval' cols='100' wrap='virtual'>" . $data['varval'] . "</textarea></td><td id='editresponse'><button type='submit' class='button' type='submit' id='but_" . $data['lid'] . "'>Edit</button></td></tr></form>";
?>
//jquery to post edits
<script language="javascript">
$(document).ready(function()
{ //using $.ajax() function
//alert("document ready"); //this alerts each row
//this function will not work, no errors, simply nothing
$(document).on("submit", "#edit_<?php echo $data["lid"]; ?>", function(e)
{
//alert("button clicked"); //this does not work
var data = $("#edit_<?php echo $data["lid"]; ?>").serialize();
$.ajax({
type : "POST",
url : "/lang/ajax_langs.php",
data : data,
success : function(response)
{
{
$("#editresponse").html(response);
};
}
});
e.preventDefault();
});
});
</script>
<?php
}
echo "</table>";
}
?>
How do I get the jQuery to submit the individual form in each row to effect an edit and then refresh each row individually as languages are edited? I need to add another form to each row to delete an entry then remove the row dynamically, but I am stuck here without being able to submit any of these forms.
I should add that this generated form shows well in the website, but is not shown in view source. Using chrome browser. I'm open to any suggestions. Thanks in advance for reading. I seriously hope I can find a solution here. Otherwise, I'm back to the 90's on this software.
It's not working because you are only submitting one id. You need to make each of your forms be of the same class. Therefore, any form clicked will be processed. Like
<form class="myForm" .....
Then, the Jquery would look like this
$(".myForm").submit(function(e){
var inputToChange = this.varval; // saw input varVal, but use whatev
var dataToChange = inputToChange.value;
// then send the data to php for processing using ajax or post
Then, use inputToChange.value = whatever new value you want to put into the form input or other div/td etc. you want to change. If you want to change data that isn't in an input, just make that td a text input and disable it from being edited by the client
<input type="text" name="lname" disabled>
then on callback send new data to this.lname.value = (many other ways to do this as well)
Don't forget, if you send through ajax you want to stop the form itself from submitting so use e.preventDefault()
I need a little guidance. I have an HTML form comprised of a very long list of items pulled from an array generated by a database query (it's a list of university courses). Users need to be able to select as many or as few courses as are relevant to their research: because the list can have hundreds or items I have a "select all" and a "select none" function and have added a jQuery shift-select batch selector to make this as easy as possible.
However, I also want them to be able to enter some text in an input box and click APPLY to select all checkboxes where the label text pattern matches using a LIKE operator (i.e., if they want all MATH courses, or all courses of level 2xx). The project is using PHP and JavaScript/jQuery/AJAX.
I know how to pull from the database based on LIKE queries, but I'm just a bit stumped as to how best loop through the generated form and target the items that are in my form. (My PHP is pretty strong, my jQuery is a bit shaky).
The list of checkboxes is generated via a loop through the array with each item set up as follows:
$o .= '<input id="'.$rw[2].'_'.$rw[0].'"
type=checkbox name="' . $rw[2].'_'. $rw[0]. '" />';
$o .= '<label for="'.$rw[2].'_'. $rw[0].'"> ' . $rw[1] . '</label>';
$o .= '</td>';
So we end up with a simple checkbox form with a LABEL FOR and the label text, and the items are all named as the array keys.
This is the HTML output for a typical item:
<tr><td><input id="110_105" type=checkbox name="110_105" />
<label for="110_105"> PHIL233</label></td></tr>
Sorry if this description is a bit long, but what I need is an idea of how to go about looping through the form's elements after it is generated to SELECT the checkbox for every item where the pattern matches.
Hope this makes sense!
Tamra
This situation is perfect for using AJAX to filter the checkbox list. I highly advocate for this instead.
But if you need to filter on the client it's fairly easy with JavaScript.
//give the labels a class so they are easy to find
var labels = document.getElementsByClassName('course-name');
//filtering text field
var query = document.getElementById('query');
//'apply' button
var queryBtn = document.getElementById('query-submit');
queryBtn.addEventListener('click', function() {
for (var i = 0; i < labels.length; i += 1) {
var label = labels[i];
var text = label.innerText;
if (text === query.value) {
label.previousElementSibling.checked = true;
}
}
}, false);
You can try it with jQuery find method.
http://api.jquery.com/find/
With it and the "Attribute Contains Selector", you can do the trick.
http://api.jquery.com/attribute-contains-selector/
The isset() function can be used to check if the input type submit is pressed, but is there a way to check if the input type button is pressed?
In my code the button does nothing but call a function on the .Onclick() event which then refreshes the page and makes a database entry inside PHP...and I want it to make the entry only after the button is pressed...and I can't use the submit type for other reasons...following is some code:
function send()
{
var events = document.getElementById("event").value;
location.href = "calm.php?day=" + xx + "&month=" + yy + "&year=" +
zz + "&events=" + events;
}
<input name="Button"
type="button"
id="submit"
onclick="send(this.form)"
value="Button" />
<?php
session_start();
include_once "connect_to_mysql.php";
$day = $_GET['day'];
$month = $_GET['month'];
$year = $_GET['year'];
$events = $_GET['events'];
$userid = $_SESSION['id'];
if (isset($_POST['button']))
{
$sql = mysql_query("INSERT INTO events (userid,month,day,year,events)
VALUES('$userid','$month','$day', '$year','$events')")
or die (mysql_error());
}
?>
isset($_POST['Button']) you just missed the capital B. You need to match it the same as the input's name attribute.
you need to do that using ajax. so when a user clicks this button the page won't refresh.. there should be a page behind the seen does that for the user. whenever he clicks the button it accesses that page and upload whatever data you want...
edit:
or you can just add a hidden input in the form when the button is clicked the hidden input value changes to i.e. true... then from php codes you can use the isset or other functions to validate whether the user clicked the button or not...
In the example you have, the simplest approach would be to add an extra variable to the parameters passed in &button_press=true or something like that and then you would know that the button had been pressed when you are receiving the information
'locrizak' answered right . Your button name is 'Button' and you tried to check presence of click on 'button' both are different .
In such case if you are unsure of what is wrong , you may print the entire POST array using
print_r($_POST)
This will display all submitted values from form including button
Using isset() is the correct method to check whether a form element is present or not
Use
if(isset($_POST['Button'])){
//code block for insertion,validation etc //
}
isset() function does not works with input type=button. so either we have to use input type=submit instead of button or some hidden type if we still want to use button.