0

I have a database containing log entries of various servers and their processes.
The data is retrieved with php, presented in an html table with each row containing (among others) a textarea for a comment and a button to submit the form and change the comment in the DB.
The names for the text areas and the values of the buttons are created by variables so I use an array for the name like name='Array[$foo]' and a corresponding button with value='$foo'. Then I can use the button value as array key to lookup the text area content when I got both via $_Request. This method is not very suitable with a huge table because of Apache max_input_vars and an array with thousands of elements.

Is there another smart solution to send the one specific text area input and not a huge array or how else can I identify the correct textarea that should be used to modify the comment in the DB?

#one row example
$output_data .= "<tr><td>".$hostname."</td>";
foreach ($row as &$field){
    $output_data .= "<td>".$field."</td>";     
}
$output_data .= "<td>".$filename."</td><td><textarea name='Comment[".$system_name."_".$table_name."_".$id."]' rows='1' cols='20'>".$comment."</textarea></td><td><button type='submit' name='SetComment' value='".htmlspecialchars($system_name."_".$table_name."_".$id)."'>Comment</button></td></tr>\n";
8
  • 3
    Have you thought about giving each row it's own <form> ..... </form>, so only one row will be submitted when you press the submit button in that row? Commented Oct 27 at 19:45
  • That's a good idea but form can't be used inside a table so the table will likely look crooked. My large html table consists of many db table so maybe I split them to one form per db table. Commented Oct 27 at 20:05
  • 2
    You could have a single form outside the table, and use JS to fill it in from the selected table row. Commented Oct 28 at 0:34
  • 1
    Either you use Ajax to submit that specific textarea input values, or, use JS to capture the textarea value and the ID when user clicked the comment button, set the values to your form with hidden input, and trigger the form submit. Either way you will need to use JS for both. I would strongly suggest you look into Ajax form submission. For vanilla js, look into fetch() API Commented Oct 28 at 3:22
  • 2
    "but form can't be used inside a table" - you can't wrap it around a table row, but you can stick it into a table cell. And by using the form attribute, you can associate input fields/textareas/buttons with the form, without them needing to be descendants of the form. Commented Oct 28 at 7:15

2 Answers 2

0

According to what you described, the current form is something like:

Current Code after rendering - revised from what you posted

<form action=update1.php>
<table>
<tr><td>domain1.com
<tr><td>Field1
<td><textarea name=Comment[system1_domain1.com_1]></textarea>
<tr><td>Field2
<td><textarea name=Comment[system1_domain1.com_2]></textarea>
<tr><td>Field3
<td><textarea name=Comment[system1_domain1.com_3]></textarea>
</table>

<table>
<tr><td>domain2.com
<tr><td>Field1
<td><textarea name=Comment[system1_domain2.com_4]></textarea>
<tr><td>Field2
<td><textarea name=Comment[system1_domain2.com_5]></textarea>
<tr><td>Field3
<td><textarea name=Comment[system1_domain2.com_6]></textarea>

<tr><td><input type=submit>
</table>
</form>

But the above only contains 2 sets of "domain" data, what you have is "thousands of data elements" which may be limited by httpd's max_input_vars (The default value for the max_input_vars directive in PHP is 1000)

To tackle the problem, as other volunteers have stated, you may use either Ajax or JS. In this case I would recommend using JS to tackle the prblem (to keep it simple).

Let's use a simple JS onblur() function. It has the advantage that whenever you change something (say after finish data input in a textarea and go to the next one, or after you finish the last data input and click the submit button, this function will be triggered)

So let's amend the above code to:


<table>
<tr><td>domain1.com
<tr><td>Field1
<td><textarea onblur='javascript:update1(this, "system1","domain1.com",1)'></textarea>
<tr><td>Field2
<td><textarea onblur='javascript:update1(this, "system1","domain1.com",2)'></textarea>
<tr><td>Field3
<td><textarea onblur='javascript:update1(this, "system1","domain1.com",3)'></textarea>
</table>


<table>
<tr><td>domain2.com
<tr><td>Field1
<td><textarea onblur='javascript:update1(this, "system1","domain2.com",4)'></textarea>
<tr><td>Field2
<td><textarea onblur='javascript:update1(this, "system1","domain2.com",5)'></textarea>
<tr><td>Field3
<td><textarea onblur='javascript:update1(this, "system1","domain2.com",6)'></textarea>
</table>


<form action=target1.php method=POST>
<textarea id=final name=final></textarea>
<input type=submit>
</form> 

<script>
function update1(var1, var2, var3, var4) {
  document.getElementById('final').value +=var1.value +"|"+var2+"|"+var3+"|"+var4+"#";
}

</script>

The above code use "|" as delimitors of the data items per set, and use "#" as delimitor to separate adjacent data item sets. (but of course you may choose other delimitors, choose the ones which will not be used in the data input in your case)

After data input you will have something like this: enter image description here

Of course you may wish to make the textarea with id=final to be "hidden" (type=hidden), since there is no point to allow the user to "accidentally" amend the data inside.

On submission of the form (which only contains one textbox), you need to use a PHP script to parse the data into separate SQL update statments and execute them. (I think that is very simple so I am not going to put this part)

Since there is only one textbox submitted, it will not be limited by max_input_vars

Sign up to request clarification or add additional context in comments.

Comments

0

You mention the Apache max_input_vars as a limitation, but there is another limitation that is just as important: who will sift through thousands of log lines at a time and then submit their commentary input one at a time without regard for what they already submitted before and at the same time receive the same flood of log lines as they viewed before?

Conceptually I would paginate the log lines so that only 10 to mabe 100 are displayed at the same time, I would also give users the possibility to see by default a page of log lines that they haven't commented on before by making a filter available that removes log lines that the user commented on in the past.

Of course the filter of already commented on log lines would be implemented in the database by adding a field in the sql definition of the log lines that is initially unset for log lines that received no comments from the user and then set after the user submitted a comment for that log line.

For pagination I would make a query to first get from the database the most recent 10 or 100 log lines, display that index of log lines to the user with the display of what log lines counts they are currently seeing.

I would also consider the making of a comment on a particular log line an interface page of its own.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.