I'm learning JS/jQuery mainly for implementing AJAX in my WordPress projects.
After hours of headache trying to figure out what's wrong with this code I decided to post it here, hoping somebody nice will help me.
My contact form JS script is not working as expected.
I can't figure out why after click on the submit button, the css rules of the required fields don't change on the page.
The jQuery script:
jQuery( document ).ready( function( $ ) {
if ( $( '#mystcf-send' ).length > 0 ) {
alert( 'Everything OK' ); // We enter in the condition... as expected.
$( 'body' ).append( '<div id="noty"></div>' );
$( '#mystcf-send' ).click( function() {
var busy = false,
error = false,
form = $( this ).parent( 'form' );
alert( 'Everything OK' ); // After click on '#mystcf-send' button, the alert box popin, the code is excecuting normally untill here...
form.find( '[required]' ).each( function() {
alert(); // After click on #mystcf button, this alert box is NOT displaying... and so the conditions below are not working.
if( $.trim( $( this ).val() ) == '' ) {
$( this ).css( 'border-color', '#FF0000' );
error = true;
}
else {
$( this ).css( 'border-color', '#CDCDCD' );
}
} );
return false;
} );
}
} );
The PHP script:
<?php
if ( ! defined( 'ABSPATH' ) ) exit;
add_shortcode( 'mystcf', 'mystcf_shortcode' );
add_action( 'wp_enqueue_scripts', 'mystcf_scripts' );
function mystcf_scripts() {
if ( is_page( 'contact' ) ) :
wp_register_script( 'mystcf-script', get_stylesheet_directory_uri() . '/inc/contact-form/js/jquery-contact-form.js', array( 'jquery' ) );
wp_localize_script( 'mystcf-script', 'mystcf_ajax', array( 'url' => admin_url( 'admin-ajax.php' ) ) );
wp_enqueue_script( 'mystcf-script' );
endif;
}
function mystcf_shortcode() {
ob_start();
mystcf_template();
$contact_form = ob_get_clean();
return $contact_form;
}
function mystcf_template() { ?>
<div class="mystcf-container">
<form id="mystcf">
<div class="mystcf-left-panel">
<p>
<label for="mystcf-email">Email <abbr class="required" title="<?php esc_attr( __( 'Required', 'mystorefront' ) ); ?>">*</abbr></label><br />
<input type="email" id="mystcf-email" name="mystcf_email" value="<?php if ( isset( $_POST['mystcf_email'] ) ) echo esc_attr( $_POST['mystcf_email'] ); ?>" required />
</p>
<p>
<label for="mystcf-first-name">Prénom</label><br />
<input type="text" id="mystcf-first-name" name="mystcf_first_name" value="<?php if ( isset( $_POST['mystcf_first_name'] ) ) echo esc_attr( $_POST['mystcf_first_name'] ); ?>" />
</p>
<p>
<label for="mystcf-second-name">Nom</label><br />
<input type="text" id="mystcf-second-name" name="mystcf_second_name" value="<?php if ( isset( $_POST['mystcf_second_name'] ) ) echo esc_attr( $_POST['mystcf_second_name'] ); ?>" />
</p>
<p>
<label for="mystcf-tel">Téléphone</label><br />
<input type="tel" id="mystcf-tel" name="mystcf_tel" value="<?php if ( isset( $_POST['mystcf_tel'] ) ) echo esc_attr( $_POST['mystcf_tel'] ); ?>" />
</p>
</div>
<div class="mystcf-right-panel">
<p>
<label for="mystcf-message">Message <abbr class="required" title="<?php esc_attr( __( 'Required', 'mystorefront' ) ); ?>">*</abbr></label><br />
<textarea type="text" id="mystcf-message" name="mystcf_message" rows="17" required><?php if ( isset( $_POST['mystcf_message'] ) ) echo esc_textarea( $_POST['mystcf_message'] ); ?></textarea>
</p>
</div>
<?php wp_nonce_field( '', 'security' ); ?>
<input type="hidden" name="mystcf_sent" value="1">
<p>
<input type="submit" class="mystcf-send" id="mystcf-send" value="<?php esc_attr( __( 'Send', 'mystorefront' ) ); ?>">
</p>
</form>
</div><?php
}
The problem is with the line where you search the form. It should be this:
form = $(this).closest('form');
parent() returns the parent (and only if it matches the selector specified). On the other hand, closest() searches all ancestors and return the first match.
Related
I'm trying to customize the input buttons, but when I update the amount by the custom buttons, the value doesn't update.
I'm copying overwriting the file in the path: woocommerce-booking/booking-form/number.php
This is another file template that I believe is useful to understand my need: woocommerce-booking/templates/single-product/add-to-cart/booking.php
<p class="form-field form-field-wide <?php echo esc_attr( implode( ' ', $class ) ); ?>">
<label for="<?php echo esc_attr( $name ); ?>"><?php echo esc_html( $label ); ?>:</label>
<!-- Custom Input Button -->
<button onclick="this.parentNode.querySelector('input[type=number]').stepDown()" class="minus">-</button>
<input type="number" value="<?php echo ( ! empty( $min ) ) ? esc_attr( $min ) : 0; ?>"
step="<?php echo ( isset( $step ) ) ? esc_attr( $step ) : ''; ?>"
min="<?php echo ( isset( $min ) ) ? esc_attr( $min ) : ''; ?>"
max="<?php echo ( isset( $max ) ) ? esc_attr( $max ) : ''; ?>" name="<?php echo esc_attr( $name ); ?>"
id="<?php echo esc_attr( $name ); ?>" /> <?php echo ( ! empty( $after ) ) ? esc_html( $after ) : ''; ?>
<!-- Custom Input Button -->
<button onclick="this.parentNode.querySelector('input[type=number]').stepUp()" class="plus">+</button>
</p>
I try to make custom calculator on product page. I made a calculator and script which calculated. But all start values is static now. This calculator should work with custom values each product.
I have a section which I added on product page like a shortcode.
function woo_calculator_content() {
// Калькулятор
echo ('
<section>
<script src="http://door.vel-wild.pro/wp-content/themes/mrDoor/raschet.js"></script>
<form action="" method="post">
<div class="vel_sum input-group">
<span>Сколько нужно м<sup>2</sup></span>
<input type="button" value="-" class="button-minus" data-field="quantity">
<input class="vel_sum_meter" id="skolkometrov" name="QTY" type="number" step="1" min="1" value="1" oncclick="multiply(this)">
<input type="button" value="+" class="button-plus" data-field="quantity">
<input name="PPRICE" value="1.67" style="display: none;">
<div> <span>Колличество упаковок <input name="TOTAL" readonly class="vel_sum_upakovka"></span>
<span><input class="vel_sum_upakovkametrov" name="TOTALMETERS" readonly>м<sup>2</sup></span></div>
</div>
</form>
</section>');
}
add_shortcode( '4cards', 'woo_calculator_content' );
But now I need get value from my custom fild and add this on input name="PPRICE" value.
Something like this
The code my custom fild is:
// Display Fields
add_action( 'woocommerce_product_options_general_product_data', __NAMESPACE__.'\woo_add_custom_general_fields' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
// Number Field
woocommerce_wp_text_input(
array(
'id' => '_number_field',
'label' => __( 'м<sup>2</sup> в упаковке', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Enter the custom value here.', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
?>
<?php
echo '</div>';
}
// Save Fields
add_action( 'woocommerce_process_product_meta', __NAMESPACE__.'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields_save( $post_id ){
// Number Field
$woocommerce_number_field = $_POST['_number_field'];
if( !empty( $woocommerce_number_field ) )
update_post_meta( $post_id, '_number_field', esc_attr( $woocommerce_number_field ) );
}
// Вывод описания сколько в упаковке
add_action( 'woocommerce_before_add_to_cart_form', 'production_time', 11 );
function production_time() {
global $product;
$woocommerce_number_field =$product->get_meta('_number_field');
if( has_term( ['laminat'], 'product_cat' ) ) {
echo '<div class="vel_costpack_hide"><p class="ri ri-clock">' . sprintf( __( ' Товар продается упаковками. В упаковке: %s', 'woocommerce' ), $woocommerce_number_field, __( 'м<sup>2</sup>', 'woocommerce' )) . '</p></div>';
}
}
To get a product custom field from a product Id (so the product Id is required) use Wordpress get_post_meta() with the right meta key.
Simply replace in your first function the line:
<input name="PPRICE" value="1.67" style="display: none;">
with this code line for example:
<input name="PPRICE" value="1.67 (' . get_post_meta( get_the_id(), '_number_field', true) . ' м<sup>2</sup> в упаковке)" style="display: none;">
The WooCommerce way (Since WooCommerce 3)
You can also use The WC_Data method get_meta() on the WC_Product Object instance like:
global $product;
if ( ! is_a( $product, 'WC_Product' ) ) {
$product = wc_get_product( get_the_id() );
}
$value_number_field = $product->get_meta('_number_field'); // Get custom field value
echo $value_number_field; // Display it
I'm trying to create a food delivery web page with the wordpress restropress plugin,
the page looks like this: https://restropress.magnigenie.com/demo/food-items/
And the problem I have is that in the checkout form I want to remove the city field
since being a delivery I obviously only make deliveries in my city
and I don't want my customers to go through that redundancy.
I would also like to change the postcode field from text to a drop-down.
I have tried with some action hooks setting as "unset" the field "city" but nothing.
In the html of the page I managed to make the changes directly
but when I updated the plug-in changes were lost.
Can you help me? This is the plugins code that I'm trying to modify:
<fieldset id="rpress_checkout_order_details">
<legend><?php echo apply_filters( 'rpress_checkout_order_details_text', esc_html__( 'Order Details', 'restropress' ) ); ?></legend>
<?php do_action( 'rpress_purchase_form_before_order_details' ); ?>
<?php
if( rpress_selected_service() == 'delivery' ) :
$customer = RPRESS()->session->get( 'customer' );
$customer = wp_parse_args( $customer, array( 'delivery_address' => array(
'address' => '',
'flat' => '',
'city' => '',
'postcode' => '',
) ) );
$customer['delivery_address'] = array_map( 'sanitize_text_field', $customer['delivery_address'] );
if( is_user_logged_in() ) {
$user_address = get_user_meta( get_current_user_id(), '_rpress_user_delivery_address', true );
foreach( $customer['delivery_address'] as $key => $field ) {
if ( empty( $field ) && ! empty( $user_address[ $key ] ) ) {
$customer['delivery_address'][ $key ] = $user_address[ $key ];
} else {
$customer['delivery_address'][ $key ] = '';
}
}
}
$customer['delivery_address'] = apply_filters( 'rpress_delivery_address', $customer['delivery_address'] );
?>
<p id="rpress-street-address" class="rp-col-md-6 rp-col-sm-12">
<label class="rpress-street-address" for="rpress-street-address">
<?php esc_html_e('Street Address', 'restropress') ?>
<span class="rpress-required-indicator">*</span>
</label>
<input class="rpress-input" type="text" name="rpress_street_address" id="rpress-street-address" placeholder="<?php esc_html_e('Street Address', 'restropress'); ?>" value="<?php echo $customer['delivery_address']['address']; ?>" />
</p>
<p id="rpress-apt-suite" class="rp-col-md-6 rp-col-sm-12">
<label class="rpress-apt-suite" for="rpress-apt-suite">
<?php esc_html_e('Apartment, suite, unit etc. (optional)', 'restropress'); ?>
</label>
<input class="rpress-input" type="text" name="rpress_apt_suite" id="rpress-apt-suite" placeholder="<?php esc_html_e('Apartment, suite, unit etc. (optional)', 'restropress'); ?>" value="<?php echo $customer['delivery_address']['flat']; ?>" />
</p>
<p id="rpress-city" class="rp-col-md-6 rp-col-sm-12">
<label class="rpress-city" for="rpress-city">
<?php _e('Town / City', 'restropress') ?>
<span class="rpress-required-indicator">*</span>
</label>
<input class="rpress-input" type="text" name="rpress_city" id="rpress-city" placeholder="<?php _e('Town / City', 'restropress') ?>" value="<?php echo $customer['delivery_address']['city']; ?>" />
</p>
<p id="rpress-postcode" class="rp-col-md-6 rp-col-sm-12">
<label class="rpress-postcode" for="rpress-postcode">
<?php _e('Postcode / ZIP', 'restropress') ?>
<span class="rpress-required-indicator">*</span>
</label>
<input class="rpress-input" type="text" name="rpress_postcode" id="rpress-postcode" placeholder="<?php _e('Postcode / ZIP', 'restropress') ?>" value="<?php echo $customer['delivery_address']['postcode']; ?>" />
</p>
<?php endif; ?>
<p id="rpress-order-note" class="rp-col-sm-12">
<label class="rpress-order-note" for="rpress-order-note"><?php echo sprintf( __('%s Instructions', 'restropress'), rpress_selected_service( 'label' ) ); ?></label>
<textarea name="rpress_order_note" class="rpress-input" rows="5" cols="8" placeholder="<?php echo sprintf( __('Add %s instructions (optional)', 'restropress'), strtolower( rpress_selected_service( 'label' ) ) ); ?>"></textarea>
</p>
<?php do_action( 'rpress_purchase_form_order_details' ); ?>
<?php do_action( 'rpress_purchase_form_order_details_fields' ); ?>
</fieldset>
I put this following hook in the functions.php file and it didn't work:
function wp_edit_checkout_fields($fields){
unset($fields['delivery_adress']['city']);
return $fields;
}
add_filter('rpress_purchase_form_order_details_fields', 'wp_edit_checkout_fields');
Note that, there is do_action( 'rpress_purchase_form_order_details_fields' ); in the plugin code. It is usually used with add_action, but not with add_filter.
Maybe you could take advantage of this filter call:
$customer['delivery_address'] = apply_filters( 'rpress_delivery_address', $customer['delivery_address'] );
Try something like this (put in your function.php file):
function your_custom_function($delivery_address) {
// Try to somehow process the city field here...
// First, you could output a variable
// to understand the data structure
print_r($delivery_address);
// and return the changed address
return $delivery_address;
}
add_filter( 'rpress_delivery_address', 'your_custom_function' );
Docs - https://developer.wordpress.org/reference/functions/add_filter/
I’m building custom WordPress and WooCommerce theme and adding custom plus and minus buttons to Product page quantity field. The buttons do update quantity input's value and I also receive "Item has been added to your cart" notification (on Product page) when I submit Add to Cart. But the cart page doesn’t show any items, neither says the cart is empty.
I can not work out which WooCommerce JS function I’m suppose to hook into, neither how to hook into it. Could I ask for help please?!
Thanks in advance!
My HTML layout:
<div class="quantity">
<label class="quantity__label" for="<?php echo esc_attr( $input_id ); ?>"><?php esc_html_e( 'Quantity:', 'woocommerce' ); ?></label>
<div class="quantity__wrapper">
<input type="button" value="-" class="quantity__button quantity__remove js-qty-remove" />
<input
type="text"
id="<?php echo esc_attr( $input_id ); ?>"
class="input-text qty text quantity__input"
step="<?php echo esc_attr( $step ); ?>"
min="<?php echo esc_attr( $min_value ); ?>"
max="<?php echo esc_attr( 0 < $max_value ? $max_value : '' ); ?>"
name="<?php echo esc_attr( $input_name ); ?>"
value="<?php echo esc_attr( $input_value ); ?>"
title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ); ?>"
size="4"
pattern="<?php echo esc_attr( $pattern ); ?>"
inputmode="<?php echo esc_attr( $inputmode ); ?>"
aria-labelledby="<?php echo esc_attr( $labelledby ); ?>" />
<input type="button" value="+" class="quantity__button quantity__add js-qty-add" />
</div>
</div>
My custom jQuery function:
function quantityButtons() {
var $qtyAdd = $('.js-qty-add'),
$qtyRemove = $('.js-qty-remove'),
$qtyInput = $('.quantity__input');
$qtyAdd.on('click', addQty);
$qtyRemove.on('click', removeQty);
function addQty() {
var $qtyInput = $('.quantity__input'),
$qtyRemove = $('.js-qty-remove'),
$i = $qtyInput.val();
$i++;
$qtyRemove.attr("disabled", !$i);
$qtyInput.val($i);
}
function removeQty() {
var $qtyInput = $('.quantity__input'),
$qtyRemove = $('.js-qty-remove'),
$i = $qtyInput.val();
if ($i >= 1) {
$i--;
$qtyInput.val($i);
} else {
$qtyRemove.attr("disabled", true);
}
}
$qtyRemove.attr("disabled", !$qtyInput.val());
}
quantityButtons();
Your First code part is made from a customization of global/quantity-input.php Woocommerce template code…
So for testing, I have changed partially that global/quantity-input.php template code with the following (very near to your code):
?>
<div class="quantity">
<label class="screen-reader-text" for="<?php echo esc_attr( $input_id ); ?>"><?php esc_html_e( 'Quantity', 'woocommerce' ); ?></label>
<input type="button" value="-" class="qty_button minus" />
<input
type="number"
id="<?php echo esc_attr( $input_id ); ?>"
class="input-text qty text"
step="<?php echo esc_attr( $step ); ?>"
min="<?php echo esc_attr( $min_value ); ?>"
max="<?php echo esc_attr( 0 < $max_value ? $max_value : '' ); ?>"
name="<?php echo esc_attr( $input_name ); ?>"
value="<?php echo esc_attr( $input_value ); ?>"
title="<?php echo esc_attr_x( 'Qty', 'Product quantity input tooltip', 'woocommerce' ); ?>"
size="4"
pattern="<?php echo esc_attr( $pattern ); ?>"
inputmode="<?php echo esc_attr( $inputmode ); ?>"
aria-labelledby="<?php echo esc_attr( $labelledby ); ?>" />
<input type="button" value="+" class="qty_button plus" />
</div>
<?php
Now the necessary CSS and revisited jQuery code functions:
// Minimum CSS to remove +/- default buttons on input field type number
add_action( 'wp_head' , 'custom_quantity_fields_css' );
function custom_quantity_fields_css(){
?>
<style>
.quantity input::-webkit-outer-spin-button,
.quantity input::-webkit-inner-spin-button {
display: none;
margin: 0;
}
.quantity input.qty {
appearance: textfield;
-webkit-appearance: none;
-moz-appearance: textfield;
}
</style>
<?php
}
add_action( 'wp_footer' , 'custom_quantity_fields_script' );
function custom_quantity_fields_script(){
?>
<script type='text/javascript'>
jQuery( function( $ ) {
if ( ! String.prototype.getDecimals ) {
String.prototype.getDecimals = function() {
var num = this,
match = ('' + num).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
if ( ! match ) {
return 0;
}
return Math.max( 0, ( match[1] ? match[1].length : 0 ) - ( match[2] ? +match[2] : 0 ) );
}
}
// Quantity "plus" and "minus" buttons
$( document.body ).on( 'click', '.plus, .minus', function() {
var $qty = $( this ).closest( '.quantity' ).find( '.qty'),
currentVal = parseFloat( $qty.val() ),
max = parseFloat( $qty.attr( 'max' ) ),
min = parseFloat( $qty.attr( 'min' ) ),
step = $qty.attr( 'step' );
// Format values
if ( ! currentVal || currentVal === '' || currentVal === 'NaN' ) currentVal = 0;
if ( max === '' || max === 'NaN' ) max = '';
if ( min === '' || min === 'NaN' ) min = 0;
if ( step === 'any' || step === '' || step === undefined || parseFloat( step ) === 'NaN' ) step = 1;
// Change the value
if ( $( this ).is( '.plus' ) ) {
if ( max && ( currentVal >= max ) ) {
$qty.val( max );
} else {
$qty.val( ( currentVal + parseFloat( step )).toFixed( step.getDecimals() ) );
}
} else {
if ( min && ( currentVal <= min ) ) {
$qty.val( min );
} else if ( currentVal > 0 ) {
$qty.val( ( currentVal - parseFloat( step )).toFixed( step.getDecimals() ) );
}
}
// Trigger change event
$qty.trigger( 'change' );
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
The quantity buttons "plus" and "minus" work perfectly and are displayed this way:
Products are added to cart with the correct quantity:
if you change the quantity field value with plus and minus buttons, the "Update cart" button is activated when any quantity field change.
When you click on "Update cart", the quantities as correctly updated.
/* Show Buttons */
add_action( 'woocommerce_before_add_to_cart_quantity', 'display_quantity_plus' );
function display_quantity_plus() {
echo '<button type="button" class="plus" >+</button>';
}
add_action( 'woocommerce_after_add_to_cart_quantity', 'display_quantity_minus' );
function display_quantity_minus() {
echo '<button type="button" class="minus" >-</button>';
}
//Note: to place minus # left and plus # right replace above add_actions with:
//add_action( 'woocommerce_before_add_to_cart_quantity', 'display_quantity_minus' );
//add_action( 'woocommerce_after_add_to_cart_quantity', 'display_quantity_plus' );
add_action( 'wp_footer', 'add_cart_quantity_plus_minus' );
function add_cart_quantity_plus_minus() {
// Only run this on the single product page
if ( ! is_product() ) return;
?>
<script type="text/javascript">
jQuery(document).ready(function($){
$('form.cart').on( 'click', 'button.plus, button.minus', function() {
// Get current quantity values
var qty = $( this ).closest( 'form.cart' ).find( '.qty' );
var val = parseFloat(qty.val());
var max = parseFloat(qty.attr( 'max' ));
var min = parseFloat(qty.attr( 'min' ));
var step = parseFloat(qty.attr( 'step' ));
// Change the value if plus or minus
if ( $( this ).is( '.plus' ) ) {
if ( max && ( max <= val ) ) {
qty.val( max );
} else {
qty.val( val + step );
}
} else {
if ( min && ( min >= val ) ) {
qty.val( min );
} else if ( val > 1 ) {
qty.val( val - step );
}
}
});
});
</script>
//add css
.single-product div.product form.cart .quantity {
float: none;
margin: 0;
display: inline-block;
}
In my wordpress website i create an Ajax search and search post_title. The code is here...
Function and script:
<?php
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() {
?>
<script type="text/javascript">
function fetch(){
jQuery.ajax({
url: ajaxwpse.ajaxurl,
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
</script>
<?php
}
add_action('wp_ajax_data_fetch' , 'data_fetch');
add_action('wp_ajax_nopriv_data_fetch','data_fetch');
function data_fetch(){
if ( esc_attr( $_POST['keyword'] ) == null ) { die(); }
$the_query = new WP_Query( array( 'posts_per_page' => -1, 's' => esc_attr( $_POST['keyword'] ), 'post_type' => array('mobile','tablet') ) );
if( $the_query->have_posts() ) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<div>
<button class="post-link" rel="<?php the_ID(); ?>"> ADD </button>
<li><?php the_title();?></li>
</div>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}
After sucessfully search with Ajax Now i need to add post_title from search to div id="post-container" dynamically.
HTML
<input type="text" name="keyword" id="keyword" onkeyup="fetch()" placeholder="Search to add"></input>
<div id="datafetch"></div> // successfuly ajax Search Result Here
<div id="post-container"> </div> // Trying to add post title here
I create a ADD button in search result to add post_title into div.
How dynamically add post_title from search field to div with button?
You've to attach click event to your button the get the post_title and append it to the div :
$(function(){
$('body').on('click', '.post-link', function(){
var post_title = $(this).closest('div').find('a').text();
$('#post-container').append( post_title );
});
});
Hope this helps.
$(function(){
$('body').on('click', '.post-link', function(){
var post_title = $(this).closest('div').find('a').text();
if( $('#post-container p').length < 4 )
$('#post-container').append( '<p>' + post_title + ' ------ REMOVE</p>' );
else
alert('You could add max 4 titles');
});
$('body').on('click', '.remove-title', function(){
$(this).closest('p').remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<button class="post-link"> ADD </button>
<li>
The title 1 HERE
</li>
</div>
<div>
<button class="post-link"> ADD </button>
<li>
The title 2 HERE
</li>
</div>
<div>
<button class="post-link"> ADD </button>
<li>
The title 3 HERE
</li>
</div>
<hr>
<div id="post-container"> </div>
Compose both divs in your PHP function, then put them in a single <div>, like this:
PHP:
add_action('wp_ajax_nopriv_data_fetch','data_fetch');
function data_fetch(){
if ( esc_attr( $_POST['keyword'] ) == null ) { die(); }
$the_query = new WP_Query( array( 'posts_per_page' => -1, 's' => esc_attr( $_POST['keyword'] ), 'post_type' => array('mobile','tablet') ) );
if( $the_query->have_posts() ) :
// compose $post_title
$post_title = "...";
echo "<div id=\"datafetch\">";
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<div>
<button class="post-link" rel="<?php the_ID(); ?>"> ADD </button>
<li><?php the_title();?></li>
</div>
<?php endwhile;
echo "</div><div id=\"post-container\">" . $post_title . "</div>";
wp_reset_postdata();
endif;
die();
}
HTML:
<input type="text" name="keyword" id="keyword" onkeyup="fetch()" placeholder="Search to add"></input>
<div id="result"></div>
JS:
// in your ajax call
success: function(data) {
jQuery('#result').html( data );
}