I can not isolate the hook to make a partial_booked day change the day to fully_booked once a customer places an order for that day... I want to only allow one booking per day yet there must be the option to select any hour of the day for start_time (between 8AM and 9PM).
I have tried several Availability settings in the product editor and even by using priorities for multiple selections of hour block or using a buffer, there is no option to create a datepicker output of fully_booked once the customer picks the hour they want to book. (We are delivering product and can only deliver one a day... but there has to be a time to choose when to deliver so we can not make the product Availability block all day "selectable.")
What I have tried:
$booking_form_params = array('ajax_url' => WC()->ajax_url(),
'i18n_date_partially_booked' => __('This date is unavailable',
'woocommerce-bookings'),
#uses add_filter( 'booking_form_params' .... );
(this works on the front end perfectly well but the datepicker still allows clicking event if time left in the day) So of course I tried:
$htm .= '.single.single-product td.partial_booked[data-event="click"] *{
pointer-events: unset; cursor:not-allowed !important;
background: #c96259!important;}';
wp_register_style( 'codeoctober-entry-set', false );
wp_enqueue_style( 'codeoctober-entry-set' );
wp_add_inline_style( 'codeoctober-entry-set', $htm );
}
#using add_action( 'wp_footer', .... ); and add_action('wp_enqueue_scripts'....);
wp_enqueue_scripts works great and makes the entire day field (td > a div) of calendar turn a nice bright red... But I still have that pesky click available.
So next I tried:
Some inline javascript in about a dozen different fashions and each time I tried to .removeClass or .addClass() or even .replace(regex) in hopes that the td anchor would honor my request to remove the bookable class. Results: nada!
If I could remove the bookable class then I am good to go. We just do not want any one to select a day if another customer has booked any block of time (minimum blocks are four hours).
Was hoping it was as simple as this:
add_filter( 'wc_bookings_date_picker_args', 'function-name');
function-name
{ $booked =
$wc_bookings_date_picker_args->booking_form->product->get_id() );
return array(
'partially_booked_days' => $booked['fully_booked_days'],
);
}
Here is the workaround.
/**
* Use inline style to show booked whole day
* woocommerce_booking_form_get_posted_data
* top:87vh;width:502%;z-index:9;box-shadow: 0 15px 20px rgba(0,0,0,.25);
* #param string $end_date
* #return array
*/
add_action( 'wp_enqueue_scripts', 'codeoctober_inline_public_script' );
function codeoctober_inline_public_script()
{
$day_booked = true; //codeoctober_booking_day_booked_meta();
if( $day_booked == true ) {
$htm = '';
$htm .= '.single.single-product td.partial_booked[data-event="click"] *, .single.single-product td.partial_booked{-webkit-touch-callout: none;-webkit-user-select: none;-khtml-user-select: none;-moz-user-select: none;-ms-user-select: none;user-select: none; pointer-events: none; cursor:not-allowed !important;background: #c96259!important;}';
wp_register_style( 'codeoctober-entry-set', false );
wp_enqueue_style( 'codeoctober-entry-set' );
wp_add_inline_style( 'codeoctober-entry-set', $htm );
}
}
And then messages customized for event:
/**
* Woo booking form notices
* booking_formparams
*
* #param string $ajax inclusion
* #return array
*/
add_filter( 'booking_form_params', 'codeoctober_change_partbooking_form_params' );
function codeoctober_change_partbooking_form_params( $booking_form_params ) {
$booking_form_params = array('ajax_url' => WC()->ajax_url(),
'i18n_date_partially_booked' => __('This date is unavailable', 'woocommerce-bookings'),
'i18n_start_date' => __('Choose a Start Date', 'woocommerce-bookings'),
'i18n_end_date' => __('Choose an End Date', 'woocommerce-bookings'),
'i18n_dates' => __('Dates', 'woocommerce-bookings'),
'i18n_choose_options' => __('Please select the options for your booking above first', 'woocommerce-bookings'));
/*wp_localize_script('wc-bookings-booking-form', 'booking_form_params',
apply_filters('booking_form_params', $booking_form_params));
*/
return $booking_form_params;
}
Related
The problem is: I can't get where is the mistake here:
#function calcSize($value) {
$containerWidth: calc(100vw - 405px);
$initialContainer: 1278;
$result: $value * $containerWidth / $initialContainer;
#return $result;
}
I'm trying to use it:
.module-title {
font-weight: 700;
font-size: calcSize(45);
}
But I get mistake: "Undefined operation "45 * calc(100vw - 405px)""
The calc() function needs to be sent to the client, so that the 100vw element can be re-calculated every time the browser is resized.
However, you've used it in a server-side formula ($value * $containerWidth / $initialContainer) which needs to be processed before sending it to the browser.
What you probably need to do is have Sass render a calc() formula with all the parts in, which will then be sent to the client to calculate:
#function calcSize($value) {
$initialContainer: 1278;
$result: calc($value * (100vw - 405px) / $initialContainer);
#return $result;
}
(Theoretically, SCSS could work out that that's what you meant, but it might be quite complex to implement.)
I have successfully created a plugin for ckeditor 5 which allows users to select one or more previous posts from a page and upon clicking an "apply quotes" button, it inserts the selected posts in to the editor view one after the other as blockquotes.
This works fine, however, I would like to have the cursor be on a new line after the last blockquote so the user can add their own comments.
I have tried appending a paragraph tag tot he list of quotes, but this appears as a new paragraph WITHIN the last quote, not after it.
Does anybody have a solution to this?
I wrote a simple function that adds to the editor quoted text and a paragraph for the user reply.
/**
* #param {String} author An author of the message.
* #param {String} message A message that will be quoted.
*/
function replyTo( author, message ) {
// window.editor must be an instance of the editor.
editor.model.change( writer => {
const root = editor.model.document.getRoot();
const blockQuote = writer.createElement( 'blockQuote' );
const authorParagraph = writer.createElement( 'paragraph' );
const messageParagraph = writer.createElement( 'paragraph' );
// Inserts: "Author wrote:" as bold and italic text.
writer.insertText( `${ author } wrote:`, { bold: true, italic: true }, authorParagraph );
// Inserts the message.
writer.insertText( message, messageParagraph );
// Appends "Author wrote" and the message to block quote.
writer.append( authorParagraph, blockQuote );
writer.append( messageParagraph, blockQuote );
// A paragraph that allows typing below the block quote.
const replyParagraph = writer.createElement( 'paragraph' );
// Appends the block quote to editor.
writer.append( blockQuote, root );
// Appends the reply paragraph below the block quote.
writer.append( replyParagraph, root );
// Removes the initial paragraph from the editor.
writer.remove( root.getChild( 0 ) );
// And place selection inside the paragraph.
writer.setSelection( replyParagraph, 'in' );
} );
editor.editing.view.focus();
}
If you will have some questions about how to adjust it to your code, I would like to see code that you wrote. It will allow understanding what you did.
Of course, you can see the proposed code as an online demo – https://jsfiddle.net/pomek/s2yjug64/
I am using fullcalendar in the agendaWeek view. I noticed that events that are in a single slot, lets say 30 min, do not display the endtime. The endtime only apears on events that cover more than one slot.
All the options that I've found did not add that to the event title.
Is that possible and I just didn't see it?
Thanks for any suggestions!
EDIT:
This is the Tool I am referring to.
http://fullcalendar.io/
In the function renderEventTable there is a condition that adds a css class if the event is smaller than 30px.
if (seg.bottom - seg.top < 30) {
seg.el.addClass('fc-short');
}
So basicly you can just edit the CSS style for .fc-short.
fc-time-grid-event.fc-short .fc-time span {
display: none; /* don't display the full time text... */
}
.fc-time-grid-event.fc-short .fc-time:before {
content: attr(data-start); /* ...instead, display only the start time */
}
.fc-time-grid-event.fc-short .fc-time:after {
content: "\000A0-\000A0"; /* seperate with a dash, wrapped in nbsp's */
}
I agree that just modifing the style where you need it makes more sense but #Abdullah provided only half the solution. Don't forget to clear the trailing - in the :after section of .fc-time
.fc-time-grid-event.fc-short .fc-time:before {
/* in short mode, only data-start and data-full are available */
content: attr(data-full);
}
.fc-time-grid-event.fc-short .fc-time:after {
/* remove the trailing - after you change the content from data-start to data-full */
content: "";
}
.fc-time-grid-event.fc-short .fc-title:before {
content: "\00a0"; /* when a title exists along with the short time pad it with something like a nbsp*/
}
An easy and better solution that worked around was to simply add css.
which will show [start time] - [end time] [title]
.fc-time-grid-event.fc-short .fc-time:before {
content: attr(data-full); /* ...instead, display only the start time */
}
Yes, I know. And please don't make any of the obvious comments; my life is way too short.
I'm using Serge's/Waqar's code for a popup window, but the popup window is appearing offscreen for IE8 (it's Ok for IE9). The user can find it if they realise that a scroll bar has appeared and they scroll all the way down, but they probably won't do that. Has anyone got any suggestions for a fix? The popup panel is created as follows:
var popup = app.createVerticalPanel()
.setId('popupPanelId')
.setVisible(false)
.setStyleAttributes({
'position' : 'fixed',
'border' : '1px solid blue',
'padding' : '10',
'background' : 'beige',
'width' : POPUP_WIDTH,
'zIndex' : '2'});
and the mask panel is created as follows:
var mask = app.createVerticalPanel()
.setId('maskPanelId')
.setSize('100%', '100%')
.setStyleAttributes({
'backgroundColor' : '#F0F0F0',
'position' : 'fixed',
'top' : '0',
'left' : '0',
'zIndex' : '1',
'opacity' : '0.6'})
.setVisible(false);
If the two fixed attributes are removed, then Chrome behaves in the same way as IE8 - the popup appears offscreen. I'm guessing that IE8 doesn't understand whatever fixed positioning is generated.
Thanks.
I followed up Serge's link, and it fixed the problem (the popup appears correctly on IE8/9, FF, Chrome, Safari, Opera), with one more change. Basically, you have to set Standards mode instead of Quirks mode (good idea anyway) as follows:
function doGet() {
var app = UiApp.createApplication().setStandardsMode(true);
...
}
The other problem is that the code above (and my code) doesn't specify CSS units, which is technically an error. It works in Quirks mode (I think GAS actually supplies px, rather than the browser guessing it). In Standards mode, GAS silently drops the padding spec (bad) and it doesn't appear in the output CSS.
EDIT
Added confirmation dialog popup code below as requested. No corrections, apart from the px, but I have changed it to make it more like a traditional yes/no dialog box, so a lot of the original has disappeared. You need to trigger submitHandler to generate the popup, and write code for OkHandler and CancelHandler. The main issue here is positioning the popup. See the link above.
/* ----------------------------------------------------------------------------
* All the remaining code in this file handles a modal
* dialog box which appears when the user hits the 'submit' button. The box
* is not movable (a GAS bug), but it can be positioned, by changing the
* 'top' and 'left' style attributes. Inspired by Serge's popup code at
* http://stackoverflow.com/q/13692563/785194.
* ------------------------------------------------------------------------- */
/**
* Popup setup. Create two vertical panels, with different Z indexes,
* and create a label in the popup panel which will hold the dialog
* text. Finally, add handlers for the 'Ok' and 'Cancel' buttons.
*/
function setupPopup(app, mainPanel) {
app.add(createMaskPanel());
var popup = app.createVerticalPanel()
.setId('popupPanelId')
.setVisible(false)
.setStyleAttributes({
'position' : 'fixed',
'border' : '1px solid blue',
'padding' : '10px',
'background' : 'beige',
// 'top' : POPUP_TOP,
// 'left' : POPUP_LEFT,
'width' : POPUP_WIDTH,
// 'height' : POPUP_HEIGHT,
'zIndex' : '2'});
popup.add(app.createLabel('').setId('dialogTextId'));
var OkHandler = app.createServerHandler('OkHandler')
.addCallbackElement(mainPanel)
.addCallbackElement(popup);
var CancelHandler = app.createServerHandler('CancelHandler')
.addCallbackElement(mainPanel)
.addCallbackElement(popup);
// create a table with two cells, and insert two buttons into those
// cells
var buttonTable = app.createFlexTable().setId('buttonTable');
buttonTable.insertRow(0).addCell(0).addCell(0);
var OkButton = app.createButton('Continue');
var CancelButton = app.createButton('Cancel');
OkButton.addClickHandler(OkHandler);
CancelButton.addClickHandler(CancelHandler);
buttonTable.setWidget(0, 0, OkButton);
buttonTable.setWidget(0, 1, CancelButton);
popup.add(buttonTable);
app.add(popup);
} // setupPopup()
/**
* A mask panel, to make the popup modal.
*/
function createMaskPanel() {
var app = UiApp.getActiveApplication();
var mask = app.createVerticalPanel()
.setId('maskPanelId')
.setSize('100%', '100%')
.setStyleAttributes({
'backgroundColor' : '#F0F0F0',
'position' : 'fixed',
'top' : '0',
'left' : '0',
'zIndex' : '1',
'opacity' : '0.6'})
.setVisible(false);
mask.add(app.createLabel('POPUP')
.setStyleAttribute('color', '#F0F0F0')
.setStyleAttribute('opacity', '0.6'));
return mask;
}
/**
* 'Submit' button handler.
*/
function submitHandler(e){
var app = UiApp.getActiveApplication();
var popup = app.getElementById('popupPanelId');
var mask = app.getElementById('maskPanelId');
app.getElementById('dialogTextId').setText("yada yada");
popup.setVisible(true);
mask.setVisible(true);
popup.setStyleAttributes(
{'top' : POPUP_TOP,
'left' : POPUP_LEFT});
return app;
}
/**
* Popup box 'Ok' handler; add the form data to the output spreadsheet.
*/
function OkHandler(e) {
...
return app;
}
function CancelHandler(e) {
...
return app;
}
I have added a tab with functionality similar to related products, I have added a column with a dropdown like this:
$this->addColumn('mycolumn', array(
'name' => 'mycolumn',
'header' => Mage::helper('catalog')->__('Display on current child page'),
'index' => 'mycolumn',
'type' => 'select',
'width' => '1',
'align' => 'center',
'options' => array(
1 => Mage::helper('catalog')->__('Yes'),
0 => Mage::helper('catalog')->__('No'),
),
'editable' => true
));
Everytime i change the selection my product gets unchecked and the row is disabled.
I found that this line was commented in magento:
bindFieldsChange : function(){
if (!$(this.containerId)) {
return;
}
---> // var dataElements = $(this.containerId+this.tableSufix).down('.data tbody').select('input', 'select');
var dataElements = $(this.containerId+this.tableSufix).down('tbody').select('input', 'select');
for(var i=0; i<dataElements.length;i++){
Event.observe(dataElements[i], 'change', dataElements[i].setHasChanges.bind(dataElements[i]));
}
}
I found this code in js/mage/adminhtml/grid.js.
When I uncommented this line my dropdown worked like a charm...
I have 2 questions regarding this matter, the first one would be if it's safe to uncomment this (Magento must've had a reason to change this).
My second question is how I could avoid this behaviour without adjusting the grid.js file. I dislike editing corefiles in any way but am unable to figure out how to rewrite this functionality or how to add my column in a manner that the behaviour does not apply itself.
The row click event uses a function called 'openGridRow'
Include some javascript with your grid, and add this function with some custom code to cancel the event if certain conditions are met.
Also then set the checkbox back to checked.
Example will be
function openGridRow(grid, event){
var element = Event.findElement(event, 'tr');
//alert(Event.element(event).tagName.toLowerCase());
if(Event.element(event).type != 'checkbox'){
if(['img', 'a', 'input', 'select', 'option', 'img'].indexOf(Event.element(event).tagName.toLowerCase())!=-1) {
// re-enable the checkbox
var checkbox = Element.select(element, 'input');
if(checkbox[0] && !checkbox[0].disabled){
grid.setCheckboxChecked(checkbox[0], true);
}
return;
}
}
if(element.title){
setLocation(element.title);
}
}
The above example will do nothing, if the element type clicked is a, input, select or option
Anything else will continue as per normal.