Forum Moderators: coopster
i have a script i'm working on for relating articles, i've made progress, but ground to a bit of a halt .
The problem is this, the script below works fine for updating multiple row in the data base, but when i try an d change the text field to a check box everything goes to pot, basically i want to pass the checkbox checked as 1 and unchecked as 0
script working fine like so
while($rows=mysql_fetch_array($result777)){
echo '<input name="rank[]" type="text" value="'.$rows['rank'].'"/>';
echo '<input name="keyword_id[]" type="hidden" value="'.$rows['keyword_id'].'"/>';
echo '<input name="id[]" type="hidden" value="'.$rows['keywordrank_id'].'"/>';
} and up above
for($i=0;$i<$count;$i++){
$sql85="UPDATE keyword_rank SET keyword_id='$keyword_id[$i]', rank='$rank[$i]' WHERE keywordrank_id='$id[$i]'";
$result85=mysql_query($sql85);
}
if($result85){
//}
$updateGoTo = "index.php?nav=" . $category ;
header(sprintf("Location: %s", $updateGoTo));
i've tried the many option s including the following , but i'm struggling, seems like it should be so obvious.
while etc
echo '<input name="rank[]" type="checkbox" value="'.$rows['rank'].'"';
if (($rows['rank']) == '1') {echo "checked=\"checked\"";}
echo'/>';
echo '<input name="keyword_id[]" type="hidden" value="'.$rows['keyword_id'].'"/>';
echo '<input name="id[]" type="hidden" value="'.$rows['keywordrank_id'].'"/>';and above
for($i=0;$i<$count;$i++){
echo $rank[$i].'-'. $i.'<br />';//error check
if (empty($rank[$i])){
$rank[$i] = 0;
}else{
/$rank[$i] = 1;
/}
$sql85="UPDATE keyword_rank SET keyword_id='$keyword_id[$i]', rank='$rank[$i]' WHERE keywordrank_id='$id[$i]'";
$result85=mysql_query($sql85);
}
It gets really tricky when you're dealing with several arrays like you are because they're going to get out of sync. Let's say you have ten items. The visitor leaves the very first checkbox unchecked and checks all the others. The resulting checkbox array is going to have 9 elements while the other arrays still have 10, and the checkboxes will all be off by one ($rank[0] now corresponds to $keyword_id[1]).
i have 5 categories, each category should have two radio groups (unrelated and related)
but this too seemed to cause havoc, and all the radio buttons 10 were relted, is this just the nature of the beast and i have to stick with text boxes or is there another neater solution?
There's a couple of ways that I can think of right off the bat that you can handle checkboxes. You can index them explicitly:
while etc
echo '<input type="checkbox" name="rank[' . $rows['keywordrank_id'] . ']" value="' . $rows['rank'] '"';
if($rows['rank'] == '1') echo ' checked="checked"';
echo '/>';
echo '<input type="hidden" name="keyword_id[' . $rows['keywordrank_id'] . ']" value="' . $rows['keyword_id'] '"';
See how I used keywordrank_id for both elements? That will keep them synced and you can use that during your update.
foreach($_POST['rank'] as $keywordrank_id => $value) {
$keyword_id = $_POST['keyword_id'][$keywordrank_id];
}
Using the foreach construct you only pick up the ones that have been checked.
The other way involves variable variables. What you do is instead of using arrays, append the id onto the end of the element's name, so you end up with check1, check2, check15, etc. The above will probably be a little easier to handle, though.
am feeling slightly lost in a sea of arrays, i really want to understand this but i'm struggling a bit. here are my queries
does what you suggested affect the following columns
keywordrank_id - this is the unique primary key to the table
article_id - this is the article that the checkboxes relate to
keyword_id - this is the category the checkbox refers to
rank - this is either to be 1 or 0
now i think my understanding could be wrong, but is the code above, looking to combine some of the above. or am i just missing the logic.
if not, would i run the foreach loop before the update loop, or instead of the update while loop? ie
foreach($_POST['rank'] as $keywordrank_id => $value) {
$keyword_id = $_POST['keyword_id'][$keywordrank_id];
}
for($i=0;$i<$count;$i++){$sql85="UPDATE keyword_rank SET keyword_id='$keyword_id[$i]', rank='$rank[$i]' WHERE keywordrank_id='$id[$i]'";
$result85=mysql_query($sql85);
}
Thanks for your help as usual, appreciated
mat
When you build the form, use the keywordrank_id as the explicit index for each of your various arrays; you're using that since that's the primary key to the table. When the form is posted, the checkbox array will contain only those which have been checked. Let's say that you built the form with 10 'sets', and that their keywordrank_id is numbered 1 through 10. Then you check items 4, 6, 9, and 10. If you were to do this in response to the post:
foreach($_POST['rank'] as $index => $value)
echo "<div>Checkboxes: $index = $value</div>";
foreach($_POST['keyword_id'] as $index => $value)
echo "<div>Hidden keyword_id's: $index = $value</div>";
foreach($_POST['id'] as $index => $value)
echo "<div>Hidden id's: $index = $value</div>";
You'd see four checkboxes listed, but you'd see all ten of the other ones listed. But, since the index for all of the arrays is the same, they're still in sync, and the index is the keywordrank_id - the unique primary key to the table. And actually, you can now drop your hidden id because you're already tracking it in the index - that third group of echos should be producing 1=1 2=2 3=3 etc.
Because the array index is no longer a 0-9, it's better to use foreach instead of the for, and you want to use an array that has all its elements to drive the loop since you want to update all of the rows:
foreach($_POST['keyword_id'] as $keywordrank_id => $keyword_id) {
$rank = isset($_POST['rank'][$keywordrank_id]) ? 1 : 0;
$sql85="UPDATE keyword_rank SET keyword_id='$keyword_id', rank='$rank' WHERE keywordrank_id='$keywordrank_id'";
$result85=mysql_query($sql85);
}
I did $rank that way because you're going to have mixed values from the form. If you look at the way you populate it, some will have a value of 0 and others will have value of 1. I'm understanding from your first post that if it's checked you want a 1 and if it's unchecked you want a 0.
Are keywordrank_id and keyword_id always numeric, and are the table fields set to a numeric type (tinyint, bigint, float, double)?
Keyword_rank and keyword_id are always numeric, they are set to interger , would i be better off looking at one of the other types you mentioned?
As an aside, but heavily connected with this same functionality, you helped me in a previous post with a mysql statement for extracting related articles.
[webmasterworld.com...]
I've been working on the statement today to bring together articles with related checkboxes. And things appear to be going very well.
I've started to investigate the possibility of three radio buttons, (very related - slightly related - and not related at all) values 2-1- 0 - this is by no means necessary, but you know how it is.
Anyway the story so far is this
SELECT c.article_id , c.headline, d.keyword_id , d.rank = (Select Max(d.rank ))
FROM articles c, keyword_rank d
WHERE (((d. rank = 1 ) or (d. rank = 2))
AND (d.article_id=c. article_id) AND (c. article_id !=34)
AND (d.keyword_id IN (SELECT keyword_id from keyword_rank where article_id = 34)))
Group By d.rank
ORDER by d.rank DESC
This is all well and good and working just dandy, only thing is it places no real weight on whether a match of 2 or 1 is found, would be really neat to get a weighted list. except in the ordering, but even then the article referred to by the article id may only have been checked with slightly related, yet the related article checked very related would come out on top.
was wondering if incorporating some kind of if statement in the select statement, or maybe a case of resorting to two select statements and displaying one below the other.
Thanks again, it's made my evening seing those blue tick in those little boxes, cheers.
I asked about the field types because of form security. If you're the only one who can ever navigate to this form you're ok, but if the general public can get to it that's a different matter. Never, ever trust data that comes in. In this case, you want to "sanitize" the data here:
foreach($_POST['keyword_id'] as $keywordrank_id => $keyword_id) {
$keywordrank_id = intval($keywordrank_id);
$keyword_id = intval($keyword_id);
Always be as restrictive as you can - if it's supposed to be a number, make sure it's a number with intval() or floatval(). If it's supposed to be a word from a finite list, check it against an array with in_array(). If it can be any text, then use mysql_real_escape_string.