Magento category edit page and ajax - magento

I am adding some extra html to some input attributes in the category edit area by creating a new attribute input renderer type in my modules mysql install script:
$installer->addAttribute(
'catalog_category',
'mymodule_category_popularity',
array(
'label' => 'My Label',
'group' => 'My Group',
'type' => 'int',
'class' => 'validate-number',
'required' => false,
'default' => 50,
'input_renderer' => 'mymodule/adminhtml_catalog_category_widget_slider',
)
);
And the renderer:
class Mynamespace_Mymodule_Block_Adminhtml_Catalog_Category_Widget_Slider extends Varien_Data_Form_Element_Text
{
public function getAfterElementHtml()
{
$html = parent::getAfterElementHtml();
return $html." <div id=\"slider\"></div>";
}
}
And the javascript:
var $j = jQuery.noConflict();
$j(document).ready(function(){
$j( "#slider" ).slider();
});
This works fine, the plugins get loaded correctly and so does jQuery (as I have loaded it using my layout xml for the module). I see a slider. However, after the page has completely finished (the Magento ajax has re-loaded the category edit tabs) my slider dissapears. This, I assume, is because the javascript code is not getting ran again.
I have tried adding my javascript to the core edit.phtml (as there is other Magento JS there) however I just get an error: $j('#slider).slider() is not a function. This is because the content is getting loaded via ajax.
So, how do I make sure that I can use $j('#slider).slider() in the category edit area? Confusing I know.

I accomplished this by creating a javascript function:
function loadedInput() {
$('#slider').slider();
}
And calling that function in the attribute renderer:
class Mynamespace_Mymodule_Block_Adminhtml_Catalog_Category_Widget_Slider extends Varien_Data_Form_Element_Text
{
public function getAfterElementHtml()
{
$html = parent::getAfterElementHtml();
return $html." <div id=\"slider\"></div><script>loadedInput();</script>";
}
}

Related

Laravel-Backpack - How to re-render Ajax charts

I'm trying to display some AJAX loaded charts that change content when the user changes a filter without reloading the page. Followed Backpack and Laravel charts docs but I'm kinda stuck on how to re-render the chart without reloading the page. This is what I have so far:
routes:
Route::get('charts/test-chart', 'Charts\TestChartChartController#response')->name('charts.test-chart.index');
Route::get('charts/test-chart-ajax', 'Charts\TestChartChartController#data');
controller:
public function setup()
{
$this->chart = new Chart();
$labels = [];
for ($days_backwards = 30; $days_backwards >= 0; $days_backwards--) {
if ($days_backwards == 1) {
}
$labels[] = $days_backwards.' days ago';
}
$this->chart->labels($labels);
$this->chart->load(backpack_url('charts/test-chart-ajax'));
}
public function data(Request $request)
{
for ($days_backwards = 30; $days_backwards >= 0; $days_backwards--) {
$users[] = \App\Models\User::whereDate('created_at', today()
->subDays($days_backwards))
->count();
}
$this->chart->dataset('Users', 'line', $users)
->color('rgb(77, 189, 116)')
->backgroundColor('rgba(77, 189, 116, 0.4)');
return $this->chart->api();
}
view:
#extends(backpack_view('blank'))
#php
#extends(backpack_view('blank'))
#php
Widget::add([
'type' => 'event_select',
'view' => 'event_select',
]);
Widget::add(
[
'type' => 'div',
'class' => 'row',
'content' => [ // widgets
[ 'type'=> 'chart', 'controller' => \App\Http\Controllers\Admin\Charts\TestChartChartController::class ],
]
]);
#endphp
#section('content')
#endsection
js: (here is the part where I'm lost)
#push('after_scripts')
<script>
$(document).ready(function() {
$('.eventSelector').each(function(index, element) {
selected_event = this.getAttribute('selected_event');
this.value = selected_event;
});
$('.eventSelector').on('change', changeType);
});
function changeType() {
var eventId = $('.eventSelector').val();
$.ajax(
{
This is the part where I'm stuck, I don't know how to make the ajax call to reload the chart without reloading the page.
});
}
</script>
#endpush
It works alright the first time but I don't really know how to re-render the chart when the user changes the filter. Apparently there is something in the docs here : https://v6.charts.erik.cat/api_charts.html#update-the-chart-after-rendering but I have no idea how to use that api_url mentioned. At the end of the documentation there is a link to a sample, but now seems broken (404)
Any help would be greatly appreciated. Thanks!
***EDIT: I think I made some progress, but now I get an error I haven't been able to solve:
I added this to the script.blade.js file and it looks like its refreshing the table (because my endpoint is getting called twice):
var original_api_url = {{ $chart->id }}_api_url;
{{ $chart->id }}_refresh(original_api_url + "?year=22");
But I get this error on the console:
Uncaught (in promise) TypeError: Cannot set properties of undefined (setting 'datasets')

Drupal 7 - Trying to add form to list view

sorry if this has been asked before, I looked around but haven't found this specific question on StackOverFlow.com.
I have a view called 'view-post-wall' which I'm trying to add the form that submits posts to this view called 'post' via ajax submit, though I haven't begun adding ajax yet.
My module's name is 'friendicate'
I don't understand what I'm missing here, I'm following a tutorial and have been unable to get past this issue for 2 days now.
I don't get any errors either.
Here is the module code in full
function _form_post_ajax_add() {
$form = array();
$form['title'] = array(
'#type' => 'textfield',
'#title' => 'Title of post',
);
$form['body'] = array(
'#type' => 'textarea',
'#title' => 'description',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Submit post',
);
return $form;
}
function post_ajax_preprocess_page(&$variables) {
//krumo($variables);
$arg = arg();
if($arg[0] == 'view-post-wall') {
$variables['page']['content']['system_main']['main']['#markup'] = drupal_render(drupal_get_form('_form_post_ajax_add'));
}
}
There are multiple ways to accomplish this, and I'll outline those methods below. Also, if nothing works from my suggestions below, it's possible that you have an invalid form function name. Im not sure if that throws off Drupal or not. The correct format for the function name should end in _form and contain the arguments $form and $form_state, like so:
_form_post_ajax_add_form($form, &$form_state) { ... }
Also, if you want to use a hook, Steff mentioned in a comment to your question that you'll need to use your module name in the function name.
friendicate_preprocess_page(&$variables) { ... }
Ok, now for a few ideas how to get the form on the page.
Block
You can create a custom block within your module, and then assign it to a region in admin/structure/blocks
<?php
/**
* Implements hook_block_info().
*/
function friendicate_block_info() {
$blocks = array();
$blocks['post_ajax'] = array(
'info' => t('Translation Set Links'),
'cache' => DRUPAL_NO_CACHE,
);
return $blocks;
}
/**
* Implements hook_block_view().
*/
function friendicate_block_view($delta = '') {
$block = array();
if ($delta == 'post_ajax') {
$form = drupal_get_form('_form_post_ajax_add_form');
$block['content'] = $form;
}
return $block;
}
Clear the cache and your block should appear in admin/structure/blocks
Views attachment before/after
You can add markup before and after a view using the Views hook hook_views_pre_render()
<?php
/**
* Implements hook_view_pre_render().
*/
function frendicate_views_pre_render(&$view) {
if($view->name == 'view_post_wall') { // the machine name of your view
$form = drupal_get_form('_form_post_ajax_add_form');
$view->attachment_before = render($form);
}
}
Or maybe use view post render
function friendicate_views_post_render(&$view, &$output, &$cache) {
//use the machine name of your view
if ($view->name == 'view_post_wall') {
$output .= drupal_render(drupal_get_form('_form_post_ajax_add'));
}
}

Magento Form with Tabs Fieldset Issue

I'm writing a custom Magento module for my store and I'm facing a weird issue with a fieldset in one form. The form is assigned to a tab, however the fieldset starts from the top of container, not from just below buttons area. Please see the image attached
I want it to display like:
This module is being developed on Magento 1.9.0.1 without any modification whatsoever, just the demo data.
Below is the code for all the classes:
Controller:
added form container and tabs to left column
class Koala_Socialmanager_Adminhtml_TwitterController extends Mage_Adminhtml_Controller_Action {
public function directTweetAction(){
$this->loadLayout();
$this->_addContent($this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_tweet','directTweet'))
->_addLeft($this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_edit_tabs'));
$this->renderLayout();
Form container:
class Koala_Socialmanager_Block_Twitter_DirectTweet_Tweet extends Mage_Adminhtml_Block_Widget_Form_Container {
public function __construct()
{
$this->_blockGroup = 'koala_socialmanager';
$this->_controller = 'twitter_directTweet';
$this->_headerText = Mage::helper('koala_socialmanager')->__('Direct Tweets');
parent::__construct();
$this->_updateButton('save', 'label', Mage::helper('adminhtml')->__('Tweet Now!'));
}
}
Tabs:
class Koala_Socialmanager_Block_Twitter_DirectTweet_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs{
public function __construct(){
parent::__construct();
$this->setId('tweetTabs');
$this->setDestinationElementId('edit_form');
$this->setTitle(Mage::helper('koala_socialmanager')->__('Twitter'));
}
public function _beforeToHtml(){
$this->addTab('form_section_form',array(
'label' => Mage::helper('koala_socialmanager')->__("Tweet"),
'title' => Mage::helper('koala_socialmanager')->__("Tweet"),
'content' => $this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_edit_tabs_form')->initForm()->toHtml(),
'active' => true
));
$this->addTab('form_section_external_media',array(
'label' => Mage::helper('koala_socialmanager')->__("External Media"),
'title' => Mage::helper('koala_socialmanager')->__("External Media"),
'content' => $this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_edit_tabs_externalMedia')->initForm()->toHtml()
));
$this->addTab('form_section_magento_media',array(
'label' => Mage::helper('koala_socialmanager')->__("Magento Product Media"),
'title' => Mage::helper('koala_socialmanager')->__("Magento Product Media"),
'content' => $this->getLayout()->createBlock('koala_socialmanager/twitter_directTweet_edit_tabs_magentoProductMedia')->toHtml()
));
return parent::_beforeToHtml();
}
}
And form with fieldset:
class Koala_Socialmanager_Block_Twitter_DirectTweet_Edit_Tabs_Form extends Mage_Adminhtml_Block_Widget_Form {
public function __construct()
{
parent::__construct();
}
public function initForm(){
$form = new Varien_Data_Form();
$this->setForm($form);
$form->setHtmlIdPrefix('socialmanager');
$helper = Mage::helper('koala_socialmanager');
$fieldset = $form->addFieldset('base_fieldset', array(
'legend' => Mage::helper('koala_socialmanager')->__('Tweeter Message')
));
$fieldset->addField('statusUpdate', 'textarea', array(
'name'=>'tweet',
'label'=>$helper->__("Tweet this Message:"),
'after_element_html'=>'<div class="characterCounter">0</div>'
));
Mage::helper('koala_socialmanager')->getTwitterFormScript();
return $this;
I believe I'm missing something silly. Any help appreciated.
Cheers
Paul
I've solved the problem, still don't know the cause though. I simply rewritten everything to another folder changing the class names, created another action in controller called testAction, so all files from DirectTweet folder are located in Message folder, and guess what? when you display that form from testActoin it works as it should, when I display the old form from DirectTweet folder - fieldset is broken.
I have magento cache disabled all the time, I cleared all tmp, cache, session folders, cleared browser cache and had no luck with fixing it, so I'm wondering why the new "version" works even though there is no changes to the code apart from cosmetic ones (removing empty lines, or changed text for labels/headers).
For the last 20 minutes I was comparing file by file in phpstorm, and seriously no differences apart from class names and texts to output.... I'm to tired to think about it anymore.
Below desired output :)
Happy New Year
Paul

Status change by clicking image button in yii2

I am working on yii2 gridview and I want to change the status by clicking image.
Here is my gridview code:`
['header'=>'Deleted',
'format' => 'image',
'value'=>function($data) { return $data->deleteimageurl; },],
['header'=>'Reports Status',
'format' => 'image',
'value'=>function($data) { return $data->statusimageurl; },],`
And in model I have created these functions in model to view the images using the image path:
public function getdeleteImageurl()
{
return \Yii::$app->request->BaseUrl.'/images/'.$this->is_deleted.'.png';
}
public function getstatusImageurl()
{
return \Yii::$app->request->BaseUrl.'/images/'.$this->reports_status.'.png';
}
Now How can I change the status? How can I add an ID in image column ? I can use ajax if I add an ID there.Or if there is any other solutions please let me know.
You should use format raw and value like as:
'value'=>function($data) {
return HTML:img($data->statusimageurl, ['data-id'=>$data->id]);
},
After you can use ajax with data-id

Drupal 7 - Ajax and Bootstrap - Rerender Main Menu on Login

How can I rerender the main menu in Drupal after an Ajax Login?
I already tried the following (generating the return value in my PHP Ajax Controller):
$tree = menu_tree_all_data('main-menu');
$returnValue = drupal_render(menu_tree_output($tree));
However this will not include the Bootstrap specific class names. It basically just returns a minimalistic menu structure without anything added by the theme.
In the Bootstrap theme, the menu is rendered like this:
<?php if (!empty($primary_nav)): ?>
<?php print render($primary_nav); ?>
<?php endif; ?>
<?php if (!empty($secondary_nav)): ?>
<?php print render($secondary_nav); ?>
<?php endif; ?>
How can I enforce this type of rendering from my module?
Since I am working on an ajax one pager site, I need to update the menu based on a user's role after login. A page reload would destroy the desired look and feel, and is therefore no option.
Currently I am using the following code to process the login:
function wr_pages_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'user_login_block' || $form_id == 'user_login') {
$form['actions']['submit']['#ajax'] = array(
'callback' => 'wr_login_form_callback',
'wrapper' => 'user-login',
'method' => 'replace',
'effect' => 'fade',
'event' => 'click'
);
}
}
function wr_login_form_callback($form, $form_state) {
if (!form_get_errors()) {
return "<script>adjustViewsAndMenu();</script>";
}
else {
return $form;
}
}
adjustViewsAndMenu() makes changes to the menu, and adds extra parts to the one pager, depending on a user's role, however this function does not use any Drupal rendering, which is most likely not the best way to deal with this problem. Still haven't found out how to rerender a menu with AJAX while using the theme's rendering.

Resources