I try to add test.js file to my widget in front-end part. But it's nothing happens. The file contain alert. What's wrong with my code?
class PPNDR_new_widget extends WP_Widget{
function __construct(){
$args = array(
'name' => 'new widget',
'description' => 'this is my first widget',
'classname' => 'ppndr-new-widget'
);
parent::__construct('my_first', '', $args);
}
//front-end display of widget
public function widget($args, $instance) {
add_action('wp_enqueue_scripts', 'CounDounJS_enqueue_js');
function CounDounJS_enqueue_js() {
wp_enqueue_script('resize', plugins_url('/assets/js/test.js', __FILE__));
}
return;
}
}
add_action( 'widgets_init', function() {
register_widget('PPNDR_new_widget');
} );
I had a similar problem and google led me here -- What ended up working for me was eliminating the add_action('wp_enqueue_scripts.. and simply enqueuing my scripts and styles in the widget function.
for example:
//front-end display of widget
public function widget($args, $instance) {
wp_enqueue_script('resize', plugins_url('/assets/js/test.js', __FILE__));
}
There is the problem of not being able to dequeue the script, but I suspect the need for this would be slim.
Hope this helps.
Related
I want to change several background colors via "post type".
I don't know how to query the "post type".
I know, that my code is 100% wrong. I searched the web for a solution. But couldn't find any, that would work.
(function() {
var elements, posttype;
function init() {
elements = document.querySelectorAll('.color');
posttype = get_post_type();
}
function checkColor() {
if (posttype === 'veranstaltung') {
element.classList.add('pink');
element.classList.remove('color');
} else if (posttype === 'ausstellung') {
element.classList.add('green');
element.classList.remove('color')
} else if (posttype === 'digitale-events') {
element.classList.add('red');
element.classList.remove('color')
}
}
init();
checkColor();
})();
One method is javascript if you create a function inside function.php which you have to call all the custom post type and return all the post with ajax in javascript which I do not suggest, the second method is to create a custom page and display all the custom post type with php, and then you have to do a condition to check which post type is the post and then add a custom class to each custom post type.*Note: This get all posts of a custom type use:
$posts = get_posts([
'post_type' => 'custom',
'post_status' => 'publish',
'posts_per_page' => -1,
'order' => 'ASC'
]);
I'm trying live-wire to see how to implement it in my upcoming project. The idea is a simple chat ( user enters a body of text and click send then the message will be at the bottom of the chat)
So far everything works fine till I hit the click send button.
Here is picture before I click on send
and here is what happens after I click send
I feel like the issue is in this part of code where I send the message to the live-wire blade
#foreach ($messages as $message)
#if($message->isYou())
<livewire:conversations.conversation-message-own :message="$message" :key="$message->id" />
#else
<livewire:conversations.conversation-message :message="$message" :key="$message->id" />
#endif
#endforeach
here is the component
public $body= "";
public $conversation;
public function mount(Conversation $conversation)
{
$this->conversation = $conversation;
}
public function reply()
{
$this->validate([
'body' => 'required',
]);
$message = $this->conversation->messages()->create([
'user_id' => user()->id,
'body' => $this->body,
]);
$this->emit('message.created',$message->id);
$this->body = "";
}
public function render()
{
return view('livewire.conversations.conversation-reply');
}
}
last is listening to the event component:
class ConversationMessages extends Component
{
public $messages;
public function mount(Collection $messages)
{
$this->messages = $messages;
}
public function render()
{
return view('livewire.conversations.conversation-messages');
}
protected function getListeners()
{
return [
'message.created' => 'prependMessage',
];
}
public function prependMessage($id)
{
$this->messages->prepend(Message::find($id));
}
}
the issue in the inspect log is
Uncaught (in promise) TypeError: Cannot read property 'data' of null
but I think it's not related to the chats data!
Thanks in advance
The problem is in the keys passed to the conversation-messages components. Livewire breaks trying to render these components, even if separated with ifs. You will need to generate different keys, like a string 'message-own-' . $message->id and 'message-'. $message->id . I tested your code with rand() data:
#foreach ($messages as $message)
#if($message->isOwn())
<livewire:conversations.conversation-message-own :message="$message" :key="rand() * $message->id" />
#else
<livewire:conversations.conversation-message :message="$message" :key="rand() * $message->id" />
#endif
#endforeach
I want to display static block in html login popup during checkout, but there is a problem.
This is the html template which is called from js, this js is called from phtml, and this phtml template called from xml
layout.
( xml -> phtml -> js -> html)
So the question is how to send custom content block from the phtml or xml throught js to html template
vendor/magento/module-catalog/view/frontend/layout/default.xml
This file is calling pthml template with
<block class="Magento\Customer\Block\Account\AuthenticationPopup" name="authentication-popup" as="authentication-popup" template="Magento_Customer::account/authentication-popup.phtml">
vendor/magento/module-customer/view/frontend/templates/account/authentication-popup.phtml
This file is calling js layout with code:
<script type="text/x-magento-init">
{
"#authenticationPopup": {
"Magento_Ui/js/core/app": <?= /* #noEscape */ $block->getJsLayout() ?>
}
}
</script>
vendor/magento/module-customer/view/frontend/web/js/view/authentication-popup.js
this file is called the last html template where should be a static block from admin panel, with code:
define([
'jquery',
'ko',
// ......... //
], function ($, ko, /* ... ... ... .... ... */) {
'use strict';
return Component.extend({
registerUrl: window.authenticationPopup.customerRegisterUrl,
forgotPasswordUrl: window.authenticationPopup.customerForgotPasswordUrl,
autocomplete: window.authenticationPopup.autocomplete,
modalWindow: null,
isLoading: ko.observable(false),
defaults: {
template: 'Magento_Customer/authentication-popup'
},
});
});
this is how i get this block in php
<?php echo $this->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId('reset_password_notice')->toHtml(); ?>
I tried to paste it to phtml, it doesn't work !!!
The problem is solved by myself.
So for the first step i started looking for data provider which helps to send data from pthml throught js to html in vendor/module-customer/
There i found file vendor/module-customer/Model/Checkout/ConfigProvider.php. That was exectly what i need.
Following this link i create:
1) app/code/Theme/Customer/etc/frontend/di.xml with code:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Customer\Controller\Account\CreatePost"
type="Theme_Name\Customer\Controller\Account\CreatePost" />
<type name="Magento\Checkout\Model\CompositeConfigProvider">
<arguments>
<argument name="configProviders" xsi:type="array">
<item name="cms_block_config_provider" xsi:type="object">Theme_Name\Customer\Model\Checkout\ConfigProvider</item>
</argument>
</arguments>
</type>
</config>
2) The next step was to create a class which is called in item tag: Theme_Name/Customer/Model/Checkout/ConfigProvider.php
with code that extends
vendor/module-customer/Model/Checkout/ConfigProvider.php
Note! They both implement the same ConfigProviderInterface. So in new ConifgProvider.php we use the same interface to extend data-provider correctly
<?php
namespace Theme_Name\Customer\Model\Checkout;
use Magento\Checkout\Model\ConfigProviderInterface;
use Magento\Framework\View\LayoutInterface;
class ConfigProvider implements ConfigProviderInterface
{
/** #var LayoutInterface */
protected $_layout;
public function __construct(LayoutInterface $layout)
{
$this->_layout = $layout;
}
public function getConfig()
{
$cmsBlockId = 'block_ID'; // id of cms block to use
return [
'cms_block_message' => $this->_layout->createBlock('Magento\Cms\Block\Block')->setBlockId($cmsBlockId)->toHtml()
];
}
}
Good. Provider is configured.
3)The last one was need to override frontend html KO template:
app/design/frontend/theme_name/Magento_Customer/web/template/authentication-popup.html
Write the next:
<div data-bind="html: window.checkoutConfig.cms_block_message"></div>
You need to put this code into your phtml file.
<?php echo $this->getLayout()->createBlock('Magento\Cms\Block\Block')->setBlockId('reset_password_notice')->toHtml(); ?>
And now it show what you write into this block.
Below is information what I have done till now and what I am trying to do.
What I have done till now
Nodejs module and drupal 8 done. Example modules are working fine.
Created a simple module in drupal 8 consists of a form called simple
form. On its submit function, called nodejs module function to enqueue my message to the channel.
Javascript callback function created defined in nodejs enqueue message.
What I have been trying to acheive
When submitting a text form. Just to update the block in drupal 8.( Update the block content with hello world.)
Problem
My javascript callbacks associated with nodejs aren't being called.
Below are my codes.
Submit Function Code
public function submitForm(array &$form, FormStateInterface $form_state) {
/*$message->broadcast = TRUE;
* This would normally be replaced by code that actually does something
* with the title.
*/
$title = $form_state->getValue('title');
$message = (object) array(
'channel' => 'example',
'broadcast' => TRUE,
'callback' => 'example',
'data' => array(
'message' => 'Hello World'
),
);
nodejs_enqueue_message($message);
drupal_set_message(t('You specified a title of %title.', ['%title' => $title]));
}
Javascript callback code
(function ($) {
Drupal.Nodejs.callbacks.example = {
//grab the message and inject into the header
callback: function (message) {
console.log('simple example');
if(message.channel == 'example') {
$('#nodejs-selector').html(message.data.body);
}
}
};
})(jQuery);
Any help on this, I would be very grateful. I would love to provide more information on this, if anyone needed.
You should modify $message as
$message = (object) array(
'channel' => 'example',
'broadcast' => TRUE,
'callback' => 'example',
'data' => array(
'body' => 'Hello World'
),
);
To access the message body as message.data.body
I have included a javascript in the module "myid" I've been developing in drupal by using this code:
function myid_init() {
drupal_add_js(drupal_get_path("module", "myid") . "js/myid.js");
}
This is my Javascript file "myid.js":
function myid_js_start(){
alert("hello world");
}
Below is the code that creates a button that invokes an alert function:
$form['add_button'] = array(
'#type' => 'button',
'#value' => 'Take a picture',
'#attributes' => array('onclick' => 'myid_js_start()'),
);
I dont know where did I go wrong. The button shows up but doesn't fire any alert function. Can anyone help me with this?
If you have followed the proper drupal directory structures and everything is where it supposed to be then it could be you are setting the attributes[onclick] as 'myid_js_start()'. Try doing it like
$form['add_button'] = array(
'#type' => 'button',
'#value' => 'Take a picture',
'#attributes' => array('onclick' => 'myid_js_start'),
);
Maybe that will solve it.
I don't have a drupal system setup at the moment to test your code. It could be something else but worth a try.
Attach the .js file to the form itself using #attach.
$form['#attached']['js'] = array(
drupal_add_js(drupal_get_path("module", "myid") . "js/myid.js"),
);