Support » Plugins and Hacks » Hacks » Remove text field from comment form

  • Resolved edow

    (@edow)


    Hi,

    I would like to remove the text field from the comment form. The idea is that users can vote if they like the post or not. The like/unlike option must be done with radio buttons in a custom field (that would be the next problem).

    But first: How can I remove the text field? I don’t want it hidden, but entirely removed. What is the best practice for this? I can’t find a decent solution.

    Hopefully anyone can help me with this.

Viewing 15 replies - 16 through 30 (of 49 total)
  • Moderator bcworkz

    (@bcworkz)


    This should more or less work for you. It may take some minor tweaks to get it perfect.

    <div class="upvoters" id="votes">
    <h2>We like this!</h2>
    <div class="voter-img">
    <a href="#respond"><img src="/wp-content/themes/aigooNL/images/upvote.png" class="upvote"></a>
    <?php $comments = get_comments( array('post_id' => get_the_ID(),) );
    $likes = array();
    $unlikes = array();
    foreach( $comments as $comment ) {
    	if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    		else $likes[] = $comment;
    }
    foreach( $likes as $like )
    	echo("<img src=\"/wp-content/themes/aigooNL/images/voter.png\" class=\"tooltip\" title=\"$like->comment_author\">");
    ?>
    </div>
    </div>
    
    <div class="downvoters">
    <h2>We, not so much...</h2>
    <div class="voter-img">
    <a href="#respond"><img src="/wp-content/themes/aigooNL/images/downvote.png" class="downvote"></a>
    <?php
    foreach( $unlikes as $unlike )
    	echo("<img src=\"/wp-content/themes/aigooNL/images/voter.png\" class=\"tooltip\" title=\"$unlike->comment_author\">");
    ?>
    </div>
    </div>

    You should be able to see the main idea here in how each comment for the post is sorted into one array or another based on content, then each sorted array’s author names are output as image title attributes.

    Super awesome! Works great immediately. I hardly dare to ask, but is there with this code the possibility to show a counter for the upvotes and downvotes? If not, it doesn’t matter. This is super awesome already! Thank you so much!

    Moderator bcworkz

    (@bcworkz)


    You’re most welcome, I’m glad I could help.

    A count is super easy as long as you want the counts to appear after the sorting loop (the first foreach{ } loop). Otherwise a little restructuring is required, still not a big deal. Insert something like the following line where you want the count to appear (outside of the loops but inside a <?php ?> block):
    echo '('.count($likes).' votes)';

    Just substitute $unlikes for $likes for the downvotes. I would personally insert this after each echo line, but it will work above the related foreach lines as well.

    Great! Now I’ve the code like this:

    <div class="upvoters" id="votes">
    		<?php $comments = get_comments( array('post_id' => get_the_ID(),) );
    		$likes = array();
    		$unlikes = array();
    		foreach( $comments as $comment ) {
    			if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    				else $likes[] = $comment;
    		}
    		echo '<h2>'.count($likes).' bezoekers vinden dit leuk</h2>';
    		echo '<div class="upvoter-img">';
    		foreach( $likes as $like )
    			echo("<img src=\"/wp-content/themes/aigooNL/images/voter.png\" class=\"tooltip\" title=\"$like->comment_author\">");
    		echo '</div>';
    		?>
    		</div>
    
    		<div class="downvoters">
    		<?php
    		echo '<h2>'.count($unlikes).' bezoekers vinden dit niet leuk</h2>';
    		echo '<div class="downvoter-img">';
    		foreach( $unlikes as $unlike )
    			echo("<img src=\"/wp-content/themes/aigooNL/images/voter.png\" class=\"tooltip\" title=\"$unlike->comment_author\">");
    		echo '</div>';
    		?>
    		</div>

    It’s working great. This is the screenshot (in Dutch) how it looks like: http://oi57.tinypic.com/30hv7g6.jpg
    I guess the code is still correct with my changes?

    I have to design it now, but the functions are working great! Thanks again.

    WordPress has it build in that you may not comment the same text twice. I was forgotten to mention it, but now visitors can comment “like” and “unlike”. Is there a simple solution that prevents visitors from voting like and unlike on the same post? WordPress prevents from like the same post twice or unlike it twice.

    And what do I have to do to show the counters outside the code? I’m thinking of showing them also at the top of the page as well as how I’m showing them now.

    Moderator bcworkz

    (@bcworkz)


    Yeah, your changes are fine 🙂

    I kind of wondered if there was a counter vote prevention, I guess not. It’s a little complicated, we need to query the database, it gets a little messy to ensure the query doesn’t return false positives. Fortunately, I knew right where to find the WP duplicate prevention and it was pretty easy to hack it up for your situation. This goes either in your theme’s (preferably child theme’s) functions.php, or in a simple plugin. If you don’t have a custom site specific plugin, it’s a handy thing to have for little tweaks like this.

    //prevent more than one %like
    add_filter('pre_comment_approved','edow_one_vote',10 ,2);
    function edow_one_vote($approved, $commentdata) {
    	global $wpdb;
    	extract($commentdata, EXTR_SKIP);
    	// expected_slashed ($comment_post_ID, $comment_author, $comment_author_email, $comment_content)
    	$dupe = $wpdb->prepare( "SELECT comment_ID FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_parent = %s AND comment_approved != 'trash' AND ( comment_author = %s ", wp_unslash( $comment_post_ID ), wp_unslash( $comment_parent ), wp_unslash( $comment_author ) );
    	if ( $comment_author_email )
    		$dupe .= $wpdb->prepare( "OR comment_author_email = %s ", wp_unslash( $comment_author_email ) );
    	$dupe .= $wpdb->prepare( ") AND comment_content LIKE %s LIMIT 1", '%like' );
    	if ( $wpdb->get_var($dupe) ) {
    		if ( defined('DOING_AJAX') )
    			die( __('You already voted here!') );
    		wp_die( __('You already voted here!') );
    	}
    }

    FYI, the uppercase LIKE in the second $dupe line is not the comment content, it is a mySQL operator. The ‘%like’ is the comment content to search for, the % is a wildcard character in mySQL. Everything else is nearly straight from comments.php.

    As for moving the counts, the first loop must be moved as well since it establishes the counts. Wherever the $likes and $unlikes arrays are used, they need to be within scope of the first loop or they need to be declared global. Moving the loop up on the same page will always be in scope. Calling the loop in a function would go out of scope. When out of scope, if WP_DEBUG is defined as true, you will get undefined variable warnings, not to mention the count numbers will not display.

    Have fun with the design!

    Thanks for your explanation. Soon I’ll look after moving the counters.

    I’ve a small problem and I don’t know if it is because of the code or something else. I use this line of code to show the images:
    <img src=\"".get_avatar_url(get_avatar( $comment, 50 ))."\" class=\"tooltip\" title=\"$like->comment_author\">

    Normally $comment should be $id_or_email, but that does nothing. If I use $comment to get the comment author avatar (I also use the plugin Local Avatar or something) every author gets the same avatar (the one who voted when he was logged in), also when they’re not logged in. Perhaps I’m doing something wrong. When there’s no uploaded avatar from someone he shows the standard avatar as it should be.

    I’ll post my final code here, because maybe it’s useful for others.

    Code to get the comment form and show the avatars:

    <div class="post-commentform">
    			<?php comments_template(); ?>
    		</div>
    
    		<div class="post-comments">
    			<div class="upvoters" id="votes">
    			<?php $comments = get_comments( array('post_id' => get_the_ID(),) );
    			$likes = array();
    			$unlikes = array();
    			foreach( $comments as $comment ) {
    				if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    					else $likes[] = $comment;
    			}
    			echo '<h3>'.count($likes).' bezoekers vinden dit leuk</h3>';
    			echo '<div class="upvoter-img">';
    			foreach( $likes as $like )
    				echo("<img src=\"".get_avatar_url(get_avatar( $comment, 50 ))."\" class=\"tooltip\" title=\"$like->comment_author\">");
    			echo '</div>';
    			?>
    			</div>
    
    			<div class="downvoters">
    			<?php
    			echo '<h3>'.count($unlikes).' bezoekers vinden dit niet leuk</h3>';
    			echo '<div class="downvoter-img">';
    			foreach( $unlikes as $unlike )
    				echo("<img src=\"".get_avatar_url(get_avatar( $comment, 50 ))."\" class=\"tooltip\" title=\"$unlike->comment_author\">");
    			echo '</div>';
    			?>
    			</div>
    
    			<div class="clearBoth"></div>
    		</div>

    Code in comments.php:

    <form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
    			<fieldset>
    				<div class="comment">
    					<span class="radiobuttonleft"><input type="radio" name="comment" id="comment" value="like" data-related-item="commentinput">Ik vindt dit leuk!</span>
    					<span class="radiobuttonright"><input type="radio" name="comment" id="comment" value="unlike" data-related-item="commentinput">Ik vindt dit niet zo leuk...</span>
    				</div>
    				<div class="fields">
    					<?php $current_user = wp_get_current_user(); ?>
    					<?php
    					if ( is_user_logged_in() ) {
    						echo '';
    					} else {
    						echo '<input type="text" class="commentinput" name="author" id="author" placeholder="Naam of schuilnaam :)" value="'.$current_user->user_login.'" />
    							  <input type="text" class="commentinput" name="email" id="email" placeholder="E-mail" value="'.$current_user->user_email.'" />
    							  <input type="submit" class="commentsubmit" value="Geef je mening!" />
    							  <div class="labelemail">We willen even weten of je geen robot bent</div>';
    					}
    					?>
    				</div>
    
    				<?php comment_id_fields(); ?>
    				<?php do_action('comment_form', $post->ID); ?>
    			</fieldset>
    		</form>

    Then it looks like this, beware, it’s Dutch 😉
    Without replies: http://oi59.tinypic.com/2nkt9g7.jpg
    With replies: http://oi61.tinypic.com/2ev9q49.jpg
    When you give a comment: http://oi62.tinypic.com/1zx39j8.jpg

    So there’s only the little problem with the avatars. Thanks again for your help! I’m super happy with it!

    Moderator bcworkz

    (@bcworkz)


    I’m pleased you’re pleased 🙂

    You are passing the entire comment object to get_avatar(), it wants just a user ID or email, pass $comment->comment_author_email instead of $comment.

    Unfortunately that isn’t working either. It also gives all the voters the same avatar after a logged in user voted.

    This is the corresponding function code:

    function get_avatar_url($get_avatar){
        preg_match("/src='(.*?)'/i", $get_avatar, $matches);
        return $matches[1];
    }

    Maybe there is some error in the function code. I’m happy to open a new topic if you’re done helping me 😉

    Moderator bcworkz

    (@bcworkz)


    The correction is needed anyway, though there’s obviously something else at play. The problem is not extracting the URL, otherwise you would get no image at all. The problem is get_avatar() is returning the default image no matter what. It might require detailed tracing through the get_avatar() function to determine why.

    The first thing to try is to var_dump($comment->comment_author_email) to confirm an actual email is being passed. Besides a trace, other things to check is if the avatar setting on the admin screen is correct and that no plugins or even your theme is causing a conflict somehow.

    I’m not saying I’m done helping you, but I am out of ideas. It’s not that I don’t want to help, it’s that I can’t. Starting a new topic would certainly get other eyes on the problem. You also might try stackexchange. Best of luck to you.

    I have a question about moving the votes. Instead of moving I would like to duplicate the counter to the top of the page. So, I want the counter as where it is now and want another on top of the page. I used this code:

    <?php
    			foreach( $comments as $comment ) {
    				if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    					else $likes[] = $comment;
    			}
    			echo '<h3>'.count($likes).' people like this</h3>';
    			echo '<h3>'.count($unlikes).' people don't like this</h3>';
    			?>

    But that isn’t working. This is the first loop you’re talking about right? This code displays 0 people like this, even when there are likes.

    Which code do I have to use to have another counter on the same page. It would be better if the top counter calculates the difference. So if there’re 10 likes and 5 dislikes the counter say +5 and if there’re 2 likes and 4 dislikes is says -2.

    Moderator bcworkz

    (@bcworkz)


    You need to move (not copy) exactly this portion to above where you want the first score to appear:

    <?php $comments = get_comments( array('post_id' => get_the_ID(),) );
    		$likes = array();
    		$unlikes = array();
    		foreach( $comments as $comment ) {
    			if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    				else $likes[] = $comment;
    		}

    Leave all else where it is.

    Double check that there is no code between this and the final avatar display below that assigns a value to either $likes or $unlikes. “Assigns a value” means the variable appears to the left of a single equals = sign.

    The code to display a difference score is something like this:

    $score = $likes - $unlikes;
    echo "Net Likes-Unlikes Score: $score";

    $score must also not be assigned another value if you are going to use it as part of the avatar display below.

    Thanks, I had to change it to $score = count($likes) - count($unlikes); and now it works great!

    Later I have to figure out how to show the score on the category page, tag page and homepage, but for now it works great. Again, thanks a lot!

    The code which is on top of the page is now:

    <?php
    		$comments = get_comments( array('post_id' => get_the_ID(),) );
    			$likes = array();
    			$unlikes = array();
    			foreach( $comments as $comment ) {
    				if('unlike' == $comment->comment_content ) $unlikes[] = $comment;
    					else $likes[] = $comment;
    			}
    			$score = count($likes) - count($unlikes);
    			$totalvotes = count($likes) + count($unlikes);
    			if ($score > 0 )
    				{
    				echo '<span class="plusscore">+'.$score.'</span><br>';
    				}
    			elseif ($score == 0 )
    				{
    				echo '<span class="zeroscore">'.$score.'</span><br>';
    				}
    			elseif ($score < 0 )
    				{
    				echo '<span class="minusscore">'.$score.'</span><br>';
    				}
    			if ($score == 1 )
    				{
    				echo '<span class="totalvotes">Score uit <a href="#comments">'.$totalvotes.' stem</a></span>';
    				}
    			elseif ($score == -1 )
    				{
    				echo '<span class="totalvotes">Score uit <a href="#comments">'.$totalvotes.' stem</a></span>';
    				}
    			elseif ($score == 0 )
    				{
    				echo '<span class="totalvotes"><a href="#comments">Nu stemmen!</a></span>';
    				}
    			else
    				{
    				echo '<span class="totalvotes">Score uit <a href="#comments">'.$totalvotes.' stemmen</a></span>';
    				}
    		?>

    Moderator bcworkz

    (@bcworkz)


    Good catch with count()! My bad 🙁

    I’m pleased everything is otherwise working well, you’re most welcome.

    To have this code on various archive pages, I suggest you make a template tag function out of your code, and store it either on functions.php or in a simple plugin. Then where the code currently exists, replace the entire code with a call to your new template tag. You can use it in a similar manner inside of any loop. including the loops on archive pages.

    The one problem with this scheme is you cannot then use values internal to the function farther down the page. One way around this is to have the function return a value (or array of values) that can be assigned to a local variable for use elsewhere on the page.

    I found out the problem with the avatars. All I had to do was to change $comment->comment_author_email to $like->comment_author_email and $unlike->comment_author_email.

    🙂

    To return a value that can be assigned to a local variable for use elsewhere on the page looks like the best solution. I have to figure this out, because I’m a noob with this. Thanks for giving me a clue.

Viewing 15 replies - 16 through 30 (of 49 total)
  • The topic ‘Remove text field from comment form’ is closed to new replies.