How to echo "# in stock" from product page on WooCommerce? - woocommerce

I try to print again "In stock" inside the product page but I cant find solution how can I echo it. On the image is by default but I want to have it again on the same page, how can i echo / print that.
Thanks
>>>1 in stock Image <<<

function wc_dropdown_variation_attribute_options( $args = array() ) {
global $product;
$variations = $product->get_available_variations();
$args = wp_parse_args( apply_filters( 'woocommerce_dropdown_variation_attribute_options_args', $args ), array(
'options' => false,
'attribute' => false,
'product' => false,
'selected' => false,
'name' => '',
'id' => '',
'class' => '',
'show_option_none' => __( 'Choose an option', 'woocommerce' ),
) );
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute );
$class = $args['class'];
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
$html = '<select id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '">';
if ( $args['show_option_none'] ) {
$html .= '<option value="">' . esc_html( $args['show_option_none'] ) . '</option>';
}
if ( ! empty( $options ) ) {
/*if ( $product && taxonomy_exists( $attribute ) ) {
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
foreach ( $terms as $term ) {
if ( in_array( $term->slug, $options ) ) {
$html .= '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ) ) . '</option>';
}
}
} else {*/
foreach ( $options as $option ) {
foreach ($variations as $variation) {
if($variation['attributes'][$name] == $option) {
$stock = esc_html($variation['max_qty']);
}
}
if( $stock == 0) {
$stock_text = ' - (Out of Stock)';
$class = 'option-out-of-stock';
$disabled = 'disabled';
} elseif ($stock < 5 ) {
$stock_text = ' - Only ' . $stock . ' left!';
$class= 'option-hurry';
$disabled = '';
} elseif ($stock < 6) {
$stock_text = ' - Only a few left!';
$class = 'option-few';
$disabled = '';
} else {
$stock_text = ' - (In Stock)';
$class = '';
$disabled = '';
}
// This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
$selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false );
$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . ' class="'.$class.'" '.$disabled.'>' . $option . $stock_text .'</option>';
//}
}
}
$html .= '</select>';
echo apply_filters( 'woocommerce_dropdown_variation_attribute_options_html', $html, $args );
}

Related

How to return HTML in woocommerce dropdown select

I have this code for the woocommerce dropdown select:
//add stock qty and status to variation dropdown
add_filter( 'woocommerce_dropdown_variation_attribute_options_html', 'variations_options_html_callback', 10, 2);
function variations_options_html_callback( $html, $args ){
$args = wp_parse_args( apply_filters( 'woocommerce_dropdown_variation_attribute_options_args', $args ), array(
'options' => false,
'attribute' => false,
'product' => false,
'selected' => false,
'name' => '',
'id' => '',
'class' => '',
'show_option_none' => __( 'Choose an option', 'woocommerce' ),
) );
$options = $args['options'];
$product = $args['product'];
$attribute = $args['attribute'];
$name = $args['name'] ? $args['name'] : 'attribute_' . sanitize_title( $attribute );
$id = $args['id'] ? $args['id'] : sanitize_title( $attribute );
$class = $args['class'];
$show_option_none = $args['show_option_none'] ? true : false;
$show_option_none_text = $args['show_option_none'] ? $args['show_option_none'] : __( 'Choose an option', 'woocommerce' ); // We'll do our best to hide the placeholder, but we'll need to show something when resetting options.
if ( empty( $options ) && ! empty( $product ) && ! empty( $attribute ) ) {
$attributes = $product->get_variation_attributes();
$options = $attributes[ $attribute ];
}
$html = '<div class="custom-select"><select id="' . esc_attr( $id ) . '" class="' . esc_attr( $class ) . '" name="' . esc_attr( $name ) . '" data-attribute_name="attribute_' . esc_attr( sanitize_title( $attribute ) ) . '" data-show_option_none="' . ( $show_option_none ? 'yes' : 'no' ) . '">';
$html .= '<option value="">' . esc_html( $show_option_none_text ) . '</option>';
if ( ! empty( $options ) ) {
if ( $product && taxonomy_exists( $attribute ) ) {
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $attribute, array( 'fields' => 'all' ) );
foreach ( $terms as $term ) {
if ( in_array( $term->slug, $options ) ) {
$stock_status = get_variation_stock_status( $product, $name, $term->slug );
$html .= '<option value="' . esc_attr( $term->slug ) . '" ' . selected( sanitize_title( $args['selected'] ), $term->slug, false ) . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $term->name ).$stock_status ) . '</option>';
}
}
} else {
foreach ( $options as $option ) {
// This handles < 2.4.0 bw compatibility where text attributes were not sanitized.
$selected = sanitize_title( $args['selected'] ) === $args['selected'] ? selected( $args['selected'], sanitize_title( $option ), false ) : selected( $args['selected'], $option, false );
$html .= '<option value="' . esc_attr( $option ) . '" ' . $selected . '>' . esc_html( apply_filters( 'woocommerce_variation_option_name', $option ) ) . '</option>';
}
}
}
$html .= '</select></div>';
return $html;
}
function get_variation_stock_status( $product, $name, $term_slug ){
foreach ( $product->get_available_variations() as $variation ){
if($variation['attributes'][$name] == $term_slug ){
$variation_obj = wc_get_product( $variation['variation_id'] );
$stock_qty = $variation_obj->get_stock_quantity();
$stock_order = $product->is_on_backorder();
break;
}
}
// if the stock of the product is lower than 0 it returns
if ( $variation_obj->get_stock_quantity() <= 0 && $product->is_on_backorder() ) {
return ' ';
}
else {
return $stock_qty == 0 ? ' POWIADOM MNIE' : ' ';
}
}
And I would like the string "POWIADOM MNIE" to be in a different color than the attribute name. when I put HTML in there it doesn't work, just the html gets displayed as a string...
I tried:
$text='<p>'.'POWIADOM MNIE'.'</p>';
and then:
return $stock_qty == 0 ? ' $text ' : ' ';
or simply:
return $stock_qty == 0 ? '<p>'.'POWIADOM MNIE'.'</p>' : ' ';
but neither works. It looks like this:
dropdown select
Can you help me do it, please?

selectize.js and Shiny : select choices from a remote API

With no prior programming knowledge in JavaScript and APIs, I'm having some troubles to make this example fit my needs : select GitHub repo.
I'm trying to adapt it to work with this API: https://api-adresse.data.gouv.fr/search/? .
The response is a GeoJSON file, where the features are stored in response$features. I want to get the properties$label attribute for each feature.
Here is what I've done so far. I get an array but the items are not displayed in the dropdown...
UI :
########
# ui.R #
########
library(shiny)
fluidPage(
title = 'Selectize examples',
mainPanel(
selectizeInput('addresses', 'Select address', choices = '', options = list(
valueField = 'properties.label',
labelField = 'properties.label',
searchField = 'properties.label',
options = list(),
create = FALSE,
render = I("
{
option: function(item, escape) {
return '<div>' + '<strong>' + escape(item.properties.name) + '</strong>' + '</div>';
}
}" ),
load = I("
function(query, callback) {
if (!query.length) return callback();
$.ajax({
url: 'https://api-adresse.data.gouv.fr/search/?',
type: 'GET',
data: {
q: query
},
dataType: 'json',
error: function() {
callback();
},
success: function(res) {
console.log(res.features);
callback(res.features);
}
});
}"
)
))
)
)
Server :
############
# server.R #
############
library(shiny)
function(input, output) {
output$github <- renderText({
paste('You selected', if (input$github == '') 'nothing' else input$github,
'in the Github example.')
})
}
Thank you for your help.
Got it working thanks to this comment.
selectize doesn't support accessing nested values with dot notation
UI:
########
# ui.R #
########
library(shiny)
fluidPage(
title = 'Selectize examples',
mainPanel(
selectizeInput('addresses', 'Select address', choices = '', options = list(
valueField = 'name',
labelField = 'name',
searchField = 'name',
loadThrottle = '500',
persist = FALSE,
options = list(),
create = FALSE,
render = I("
{
option: function(item, escape) {
return '<div>' + '<strong>' + escape(item.name) + '</strong>' + '</div>';
}
}" ),
load = I("
function(query, callback) {
if (!query.length) return callback();
$.ajax({
url: 'https://api-adresse.data.gouv.fr/search/?',
type: 'GET',
data: {
q: query
},
dataType: 'json',
error: function() {
callback();
},
success: function (data) {
callback(data.features.map(function (item) {
return {name: item.properties.name,
label: item.properties.label,
score: item.properties.score};
}));
}
});
}"
)
))
)
)
Server:
############
# server.R #
############
library(shiny)
function(input, output) {
output$github <- renderText({
paste('You selected', if (input$github == '') 'nothing' else input$github,
'in the Github example.')
})
}

Use data.table for shiny inputs and store user inputs in a data.frame

In my shinyapp, I wish to use data.table to get user inputs using radio buttons or check boxes and store the user inputs in a data.frame.
Here is what I have achieved so far:
library(shiny)
library(data.table)
library(DT)
shinyApp(
ui = fluidPage(
title = 'Radio buttons in a table',
DT::dataTableOutput('foo'),
verbatimTextOutput('sel')
),
server = function(input, output, session) {
x <- data.table( 'Breed Split' = paste0("F",rep(0:16)), Frisian = rep(1,17), Jersey = rep(2,17), Cross = rep(3,17) )
x[, Frisian := sprintf( '<input type="radio" name="%s" value="%s"/>', `Breed Split`, x[, Frisian] )]
x[, Jersey := sprintf( '<input type="radio" name="%s" value="%s"/>', `Breed Split`, x[, Jersey] )]
x[, Cross := sprintf( '<input type="radio" name="%s" value="%s"/>', `Breed Split`, x[, Cross] )]
output$foo = DT::renderDataTable(
x, escape = FALSE, selection = 'none', server = FALSE, rownames=FALSE,
options = list(dom = 't', paging = FALSE, ordering = FALSE),
callback = JS("table.rows().every(function(i, tab, row) {
var $this = $(this.node());
$this.attr('id', this.data()[0]);
$this.addClass('shiny-input-radiogroup');
});
Shiny.unbindAll(table.table().node());
Shiny.bindAll(table.table().node());")
)
output$sel = renderPrint({
str(sapply(x$`Breed Split`, function(i) input[[i]]))
})
}
)
And the other thing is if there is any way to set the default input values as shown in this screenshot.
[]
Try to add column of checked name and then remove column whe render DT
library(shiny)
library(data.table)
library(DT)
shinyApp(
ui = fluidPage(
title = 'Radio buttons in a table',
DT::dataTableOutput('foo'),
verbatimTextOutput('sel')
),
server = function(input, output, session) {
x <- data.table( 'Breed Split' = paste0("F",rep(0:16)), Frisian = rep(1,17), Jersey = rep(2,17), Cross = rep(3,17) ,
checked=c(rep("Frisian",9),rep("Jersey",5),rep("Cross",3))
)
x[, Frisian := sprintf( '<input type="radio" name="%s" value="%s" %s/>', `Breed Split`, x[, Frisian],ifelse("Frisian"==x[, checked],"checked" ,""))]
x[, Jersey := sprintf( '<input type="radio" name="%s" value="%s" %s/>', `Breed Split`, x[, Jersey],ifelse("Jersey"==x[, checked],"checked" ,"" ))]
x[, Cross := sprintf( '<input type="radio" name="%s" value="%s" %s/>', `Breed Split`, x[, Cross] ,ifelse("Cross"==x[, checked],"checked" ,""))]
output$foo = DT::renderDataTable(
x[,-c("checked")], escape = FALSE, selection = 'none', server = FALSE, rownames=FALSE,
options = list(dom = 't', paging = FALSE, ordering = FALSE),
callback = JS("table.rows().every(function(i, tab, row) {
var $this = $(this.node());
$this.attr('id', this.data()[0]);
$this.addClass('shiny-input-radiogroup');
});
Shiny.unbindAll(table.table().node());
Shiny.bindAll(table.table().node());")
)
output$sel = renderPrint({
str(sapply(x$`Breed Split`, function(i) input[[i]]))
})
}
)

Radio Buttons on Shiny Datatable, with data.frame / data.table

Pretty much a copy paste from this example (which, I assume, supersedes some of the other answers on SO) except that I'm trying to use a data.table instead of a matrix. I'm unable to figure out why it isn't working.
library(shiny)
library(DT)
shinyApp(
ui = fluidPage(
title = 'Radio buttons in a table',
DT::dataTableOutput('foo'),
verbatimTextOutput('sel')
),
server = function(input, output, session) {
m = data.table(
month1 = month.abb,
A = '1',
B = '2',
C = '3',
QWE = runif(12)
)
m[, A := sprintf(
'<input type="radio" name="%s" value="%s"/>',
month1, m[, A]
)]
m[, B := sprintf(
'<input type="radio" name="%s" value="%s"/>',
month1, m[, B]
)]
m[, C := sprintf(
'<input type="radio" name="%s" value="%s"/>',
month1, m[, C]
)]
output$foo = DT::renderDataTable(
m, escape = FALSE, selection = 'none', server = FALSE,
options = list(dom = 't', paging = FALSE, ordering = FALSE),
callback = JS("table.rows().every(function(i, tab, row) {
var $this = $(this.node());
$this.attr('id', this.data()[0]);
$this.addClass('shiny-input-radiogroup');
});
Shiny.unbindAll(table.table().node());
Shiny.bindAll(table.table().node());")
)
output$sel = renderPrint({
str(sapply(month.abb, function(i) input[[i]]))
})
}
)
Issue is with rownames. You have an extra column of rownames that gets all the shiny attributes added to it, but it isn't a radio buttons it's just text so it breaks (although it should throw an error).
Here is a working version:
library(shiny)
library(DT)
shinyApp(
ui = fluidPage(
title = 'Radio buttons in a table',
DT::dataTableOutput('foo'),
verbatimTextOutput('sel')
),
server = function(input, output, session) {
m = data.table(
month1 = month.abb,
A = '1',
B = '2',
C = '3',
QWE = runif(12)
)
m[, A := sprintf(
'<input type="radio" name="%s" value="%s"/>',
month1, m[, A]
)]
m[, B := sprintf(
'<input type="radio" name="%s" value="%s"/>',
month1, m[, B]
)]
m[, C := sprintf(
'<input type="radio" name="%s" value="%s"/>',
month1, m[, C]
)]
output$foo = DT::renderDataTable(
m, escape = FALSE, selection = 'none', server = FALSE, rownames=FALSE,
options = list(dom = 't', paging = FALSE, ordering = FALSE),
callback = JS("table.rows().every(function(i, tab, row) {
var $this = $(this.node());
$this.attr('id', this.data()[0]);
$this.addClass('shiny-input-radiogroup');
});
Shiny.unbindAll(table.table().node());
Shiny.bindAll(table.table().node());")
)
output$sel = renderPrint({
str(sapply(month.abb, function(i) input[[i]]))
})
}
)

CMB Metabox and Select Dropdown

i am having problem with CMB metabox and select dropdown. I can see only first letter of value for example if my select box have in array Banana, Orange, Apple it prints only first letter both in admin and website (frontend). What can cause that problem?
array(
'name' => 'Test Radio',
'id' => $prefix . 'test_radio',
'type' => 'radio',
'options' => array(
'standard' => __( 'Banana', 'cmb' ),
'custom' => __( 'Orange', 'cmb' ),
'none' => __( 'Apple', 'cmb' ),
),
),
I had the same problem. This works for me :
array(
'name' => 'Test Select',
'id' => $prefix . 'test_select',
'type' => 'select',
'options' => array(
array(
'name' => __( 'Banana', 'cmb' ),
'value' => 'banana',
),
array(
'name' => __( 'Orange', 'cmb' ),
'value' => 'orange',
),
array(
'name' => __( 'Apple', 'cmb' ),
'value' => 'apple',
),
),
),
You are using a radio type field and need the select type field. Try this:
array(
'name' => 'Test Select',
'id' => $prefix . 'test_select',
'type' => 'select',
'options' => array(
'banana' => __( 'Banana', 'cmb' ),
'orange' => __( 'Orange', 'cmb' ),
'apple' => __( 'Apple', 'cmb' ),
),
),

Resources